pixman: Branch 'master' - 5 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sun Jan 17 13:59:47 PST 2010


 pixman/pixman-bits-image.c |   11 ++++++++--
 pixman/pixman-image.c      |    3 ++
 test/Makefile.am           |    7 +++++-
 test/alphamap.c            |   49 +++++++++++++++++++++++++++++++++++++++++++++
 test/utils.c               |   14 ++++++++++++
 test/utils.h               |    4 +++
 6 files changed, 85 insertions(+), 3 deletions(-)

New commits:
commit 8dabd1fdd8f0030086cfe70f0baba7c502a0e1b8
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun Jan 17 16:45:23 2010 -0500

    bits: Print an error if someone tries to create an image with bpp < depth
    
    Something in the X server apparently does this.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index a3bcd69..23a3796 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1044,6 +1044,12 @@ pixman_image_create_bits (pixman_format_code_t format,
     return_val_if_fail (bits == NULL ||
                         (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
 
+    if (PIXMAN_FORMAT_BPP (format) < PIXMAN_FORMAT_DEPTH (format))
+    {
+	fprintf (stderr, "Bad format passed to pixman_image_create_bits();\n");
+	return NULL;
+    }
+
     if (!bits && width && height)
     {
 	free_me = bits = create_bits (format, width, height, &rowstride_bytes);
commit 2c3cbc83c4018173d9deae3f24c457b3ca16dbcd
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat Jan 16 10:31:22 2010 -0500

    When fetching from an alpha map, replace the alpha channel of the image
    
    Previously it would be multiplied onto the image pixel, but the Render
    specification is pretty clear that the alpha map should be used
    *instead* of any alpha channel within the image.
    
    This makes the assumption that the pixels in the image are already
    premultiplied with the alpha channel from the alpha map. If we don't
    make this assumption and the image has an alpha channel of its own, we
    would have to first unpremultiply that pixel, and then premultiply the
    alpha value onto the color channels, and then replace the alpha
    channel.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index fb1af92..a3bcd69 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -120,7 +120,8 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
 	pixel_a = ALPHA_8 (pixel_a);
     }
 
-    UN8x4_MUL_UN8 (pixel, pixel_a);
+    pixel &= 0x00ffffff;
+    pixel |= (pixel_a << 24);
 
     return pixel;
 }
commit 0df6098f3d941608f945d02e2af65b70ac499e0a
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat Jan 16 10:09:25 2010 -0500

    pixman_image_validate() needs to also validate the alpha map.
    
    This is the other half of bug 25950.

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index e55ba2c..1619165 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -245,6 +245,9 @@ _pixman_image_validate (pixman_image_t *image)
 	image->common.property_changed (image);
 	image->common.dirty = FALSE;
     }
+
+    if (image->common.alpha_map)
+	_pixman_image_validate (image->common.alpha_map);
 }
 
 PIXMAN_EXPORT pixman_bool_t
commit 7f00dc62e4aa4b2b417ca1c86813a6b4c7f78673
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat Jan 16 10:07:48 2010 -0500

    When fetching from an alpha map, use the alpha map's fetch function.
    
    Don't use the one from the image. This is the first half of bug 25950.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 5a5a690..fb1af92 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -115,7 +115,7 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
     }
     else
     {
-	pixel_a = image->fetch_pixel_raw_32 (
+	pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
 	    image->common.alpha_map, x, y);
 	pixel_a = ALPHA_8 (pixel_a);
     }
commit 042f978b04aefe56ec912c88ec879e668153a287
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat Jan 16 09:48:45 2010 -0500

    test: Add new alphamap test program.
    
    This program demonstrates three bugs relating to alpha maps:
    
    - When fetching from an alpha map into 32 bit intermediates, we use
      the fetcher from the image, and not the one from the alpha map.
    
    - For 64 bit intermediates we call fetch_pixel_generic_lossy_32()
      which then calls fetch_pixel_raw_64, which is NULL because alpha
      images are never validated.
    
    - The alpha map should be used *in place* of any existing alpha
      channel, but we are actually multiplying it onto the image.

diff --git a/test/Makefile.am b/test/Makefile.am
index ab98756..5f6ba13 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -7,6 +7,7 @@ TESTPROGRAMS =			\
 	oob-test		\
 	window-test		\
 	trap-crasher		\
+	alphamap		\
 	blitters-test		\
 	scaling-test		\
 	composite
@@ -24,6 +25,9 @@ blitters_test_SOURCES = blitters-test.c utils.c utils.h
 scaling_test_LDADD = $(TEST_LDADD)
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 
+alphamap_LDADD = $(TEST_LDADD)
+alphamap_SOURCES = alphamap.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
@@ -39,7 +43,8 @@ TESTPROGRAMS_GTK =		\
 	alpha-test		\
 	screen-test		\
 	convolution-test	\
-	trap-test
+	trap-test		\
+	alphamap
 
 INCLUDES += $(GTK_CFLAGS)
 
diff --git a/test/alphamap.c b/test/alphamap.c
new file mode 100644
index 0000000..e6a25ef
--- /dev/null
+++ b/test/alphamap.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+#define WIDTH 400
+#define HEIGHT 200
+
+int
+main (int argc, char **argv)
+{
+    uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
+    uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    int i;
+
+    pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
+    pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+
+    for (i = 0; i < 2; ++i)
+    {
+	pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : PIXMAN_a2r10g10b10;
+	pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, src, WIDTH * 4);
+	int j, k;
+
+	pixman_image_set_alpha_map (s, a, 0, 0);
+
+	pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+	for (j = 0; j < HEIGHT; ++j)
+	{
+	    for (k = 0; k < WIDTH; ++k)
+	    {
+		uint8_t ap = ((uint8_t *)alpha)[j * WIDTH + k];
+		uint32_t dap = (dest[j * WIDTH + k] >> 24);
+		uint32_t sap = (src[j * WIDTH + k] >> 24);
+
+		if (ap != dap)
+		{
+		    printf ("Wrong alpha value at (%d, %d). Should be %d; got %d (src was %d)\n", k, j, ap, dap, sap);
+		    return 1;
+		}
+	    }
+	}
+
+	pixman_image_unref (s);
+    }
+
+    return 0;
+}
diff --git a/test/utils.c b/test/utils.c
index 1e42d89..58cd100 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -192,3 +192,17 @@ image_endian_swap (pixman_image_t *img, int bpp)
     }
 }
 
+uint8_t *
+make_random_bytes (int n_bytes)
+{
+    uint8_t *bytes = malloc (n_bytes);
+    int i;
+
+    if (!bytes)
+	return NULL;
+
+    for (i = 0; i < n_bytes; ++i)
+	bytes[i] = lcg_rand () & 0xff;
+
+    return bytes;
+}
diff --git a/test/utils.h b/test/utils.h
index 8fdb2ce..fb1ccec 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -39,3 +39,7 @@ compute_crc32 (uint32_t    in_crc32,
  */
 void
 image_endian_swap (pixman_image_t *img, int bpp);
+
+/* Generate n_bytes random bytes in malloced memory */
+uint8_t *
+make_random_bytes (int n_bytes);


More information about the xorg-commit mailing list