[Pixman] [PATCH 2/2] Fix bugs with alpha maps

Søren Sandmann sandmann at cs.au.dk
Mon Jan 9 02:46:11 PST 2012


From: Søren Sandmann Pedersen <ssp at redhat.com>

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.
---
 pixman/pixman-bits-image.c |   53 ++++++++++++++++++++++++++++++++++---------
 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;
-- 
1.7.4



More information about the Pixman mailing list