summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-01-07 16:48:00 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-01-18 15:37:36 -0500
commita9b4fa378b70412ccf065454be009c1f8da4003a (patch)
tree8324e8ef52232d72872dec370a3d69048ca450bb
parent7dd2b8ee7e1f3c817205cf510507f4b54562444b (diff)
Fix bugs with alpha maps
The alpha channel from the alpha map must be inserted as the new alpha channel when a scanline is fetched from an image. Previously the alpha map would overwrite the buffer instead. This wasn't caught be the alpha map test because it would only verify that the resulting alpha channel was correct, and not pay attention to incorrect color channels.
-rw-r--r--pixman/pixman-bits-image.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 99c0dfe..2f56de3 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1294,12 +1294,27 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
if (image->common.alpha_map)
{
- x -= image->common.alpha_origin_x;
- y -= image->common.alpha_origin_y;
+ uint32_t *alpha;
+
+ if ((alpha = malloc (width * sizeof (uint32_t))))
+ {
+ int i;
+
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
+
+ image->common.alpha_map->fetch_scanline_32 (
+ (pixman_image_t *)image->common.alpha_map,
+ x, y, width, alpha, mask);
- image->common.alpha_map->fetch_scanline_32 (
- (pixman_image_t *)image->common.alpha_map,
- x, y, width, buffer, mask);
+ for (i = 0; i < width; ++i)
+ {
+ buffer[i] &= ~0xff000000;
+ buffer[i] |= (alpha[i] & 0xff000000);
+ }
+
+ free (alpha);
+ }
}
return iter->buffer;
@@ -1312,17 +1327,33 @@ dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
int x = iter->x;
int y = iter->y;
int width = iter->width;
- uint32_t * buffer = iter->buffer;
+ uint64_t * buffer = (uint64_t *)iter->buffer;
image->fetch_scanline_64 (
- (pixman_image_t *)image, x, y, width, buffer, mask);
+ (pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
if (image->common.alpha_map)
{
- x -= image->common.alpha_origin_x;
- y -= image->common.alpha_origin_y;
+ uint64_t *alpha;
+
+ if ((alpha = malloc (width * sizeof (uint64_t))))
+ {
+ int i;
+
+ x -= image->common.alpha_origin_x;
+ y -= image->common.alpha_origin_y;
- image->common.alpha_map->fetch_scanline_64 (
- (pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask);
+ image->common.alpha_map->fetch_scanline_64 (
+ (pixman_image_t *)image->common.alpha_map,
+ x, y, width, (uint32_t *)alpha, mask);
+
+ for (i = 0; i < width; ++i)
+ {
+ buffer[i] &= ~0xffff000000000000ULL;
+ buffer[i] |= (alpha[i] & 0xffff000000000000ULL);
+ }
+
+ free (alpha);
+ }
}
return iter->buffer;