pixman: Branch 'master' - 7 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Mon Jan 9 02:40:31 PST 2012


 pixman/pixman-combine.c.template |    6 +++---
 pixman/pixman-combine.h.template |    4 ++--
 pixman/pixman-fast-path.c        |    4 ++--
 pixman/pixman-image.c            |   15 +++++++--------
 pixman/pixman-trap.c             |    2 +-
 pixman/pixman-utils.c            |   35 ++++++++++++++++++++++++++---------
 pixman/pixman.h                  |   12 ++++++++----
 test/blitters-test.c             |    4 ++--
 test/composite-traps-test.c      |    2 +-
 test/region-contains-test.c      |    4 ++--
 test/stress-test.c               |    3 ++-
 11 files changed, 56 insertions(+), 35 deletions(-)

New commits:
commit 37572455866114cbb8bb1bf3acfb1c61d200f98c
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Dec 20 06:32:26 2011 -0500

    Fix rounding for DIV_UNc()
    
    We need to compute floor (a/b * 255 + 0.5), not floor (a / b * 255),
    so add b/2 to the numerator in the DIV_UNc() macro.

diff --git a/pixman/pixman-combine.h.template b/pixman/pixman-combine.h.template
index 53afcd2..20f784b 100644
--- a/pixman/pixman-combine.h.template
+++ b/pixman/pixman-combine.h.template
@@ -28,7 +28,7 @@
     ((t) = (a) * (comp2_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
 
 #define DIV_UNc(a, b)							\
-    (((comp2_t) (a) * MASK) / (b))
+    (((comp2_t) (a) * MASK + ((b) / 2)) / (b))
 
 #define ADD_UNc(x, y, t)				     \
     ((t) = (x) + (y),					     \
diff --git a/test/blitters-test.c b/test/blitters-test.c
index fd62c67..feea308 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -424,6 +424,6 @@ main (int argc, const char *argv[])
     }
 
     return fuzzer_test_main("blitters", 2000000,
-			    0x3EDA4108,
+			    0xA364B5BF,
 			    test_composite, argc, argv);
 }
commit 2437ae80e5066dec9fe52f56b016bf136d7cea06
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Thu Dec 22 11:37:26 2011 -0500

    Reject trapezoids where top (botttom) is above (below) the edges
    
    When a trapezoid has a top/bottom that is above/below the left/right
    edges, degenerate trapezoids become possible. For example the edge
    could be very short and close to horizontal. If the bottom edge is far
    below the bottom point of such a short edge, the result is that the
    lower right corner of the trapezoid will be extremely far to the left.
    
    This kind of trapezoid causes overflows in the rasterization code, so
    change pixman_trapezoid_valid() to reject them.

diff --git a/pixman/pixman.h b/pixman/pixman.h
index 18d9513..20ff496 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -908,10 +908,14 @@ struct pixman_triangle
 };
 
 /* whether 't' is a well defined not obviously empty trapezoid */
-#define pixman_trapezoid_valid(t)				   \
-    ((t)->left.p1.y != (t)->left.p2.y &&			   \
-     (t)->right.p1.y != (t)->right.p2.y &&			   \
-     (int) ((t)->bottom - (t)->top) > 0)
+#define pixman_trapezoid_valid(t)					\
+    ((t)->left.p1.y != (t)->left.p2.y &&				\
+     (t)->right.p1.y != (t)->right.p2.y &&				\
+     (int) ((t)->bottom - (t)->top) > 0 &&				\
+     (t)->bottom <= (t)->left.p2.y &&					\
+     (t)->bottom <= (t)->right.p2.y &&					\
+     (t)->top >= (t)->left.p1.y &&					\
+     (t)->top >= (t)->right.p1.y)
 
 struct pixman_span_fix
 {
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index ff03b50..de518d8 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int      testnum,
 int
 main (int argc, const char *argv[])
 {
-    return fuzzer_test_main("composite traps", 40000, 0xE3112106,
+    return fuzzer_test_main("composite traps", 40000, 0x4346479C,
 			    test_composite, argc, argv);
 }
commit 6a8192b6dd88b833bb918de28331d3a85c84a4f7
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Dec 20 06:34:41 2011 -0500

    In MUL_UNc() cast to comp2_t
    
    Otherwise, when comp1_t is 16 bits wide, we can end up with a signed
    integer overflow.

diff --git a/pixman/pixman-combine.h.template b/pixman/pixman-combine.h.template
index 67ed309..53afcd2 100644
--- a/pixman/pixman-combine.h.template
+++ b/pixman/pixman-combine.h.template
@@ -25,7 +25,7 @@
  */
 
 #define MUL_UNc(a, b, t)						\
-    ((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
+    ((t) = (a) * (comp2_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
 
 #define DIV_UNc(a, b)							\
     (((comp2_t) (a) * MASK) / (b))
commit 33ac0a9084aabd0e47fb1c9e5638eafc809c52cb
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Dec 21 08:19:05 2011 -0500

    Fix a bunch of signed overflow issues
    
    In pixman-fast-path.c: (1 << 31) - 1 causes a signed overflow, so
    change to (1U << n) - 1.
    
    In pixman-image.c: The check for whether m10 == -m01 will overflow
    when -m01 == INT_MIN. Instead just check whether the variables are 1
    and -1.
    
    In pixman-utils.c: When the depth of the topmost channel is 0, we can
    end up shifting by 32.
    
    In blitters-test.c: Replicating the mask would end up shifting more
    than 32.
    
    In region-contains-test.c: Computing the average of two large integers
    could overflow. Instead add half the difference between them to the
    first integer.
    
    In stress-test.c: Masking the value in fake_reader() would sometimes
    shift by 32. Instead just use the most significant bits instead of
    the least significant.
    
    All these issues were found by the IOC tool:
    
        http://embed.cs.utah.edu/ioc/

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 038dcf7..eac8dea 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1969,9 +1969,9 @@ static const pixman_fast_path_t c_fast_paths[] =
 };
 
 #ifdef WORDS_BIGENDIAN
-#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (32 - (offs) - (n)))
+#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n)))
 #else
-#define A1_FILL_MASK(n, offs) (((1 << (n)) - 1) << (offs))
+#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs))
 #endif
 
 static force_inline void
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index ad5996b..8599a1e 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -299,13 +299,12 @@ compute_image_info (pixman_image_t *image)
 	             image->common.transform->matrix[1][1] == 0)
 	    {
 		pixman_fixed_t m01 = image->common.transform->matrix[0][1];
-		if (m01 == -image->common.transform->matrix[1][0])
-		{
-			if (m01 == -pixman_fixed_1)
-			    flags |= FAST_PATH_ROTATE_90_TRANSFORM;
-			else if (m01 == pixman_fixed_1)
-			    flags |= FAST_PATH_ROTATE_270_TRANSFORM;
-		}
+		pixman_fixed_t m10 = image->common.transform->matrix[1][0];
+
+		if (m01 == -1 && m10 == 1)
+		    flags |= FAST_PATH_ROTATE_90_TRANSFORM;
+		else if (m01 == 1 && m10 == -1)
+		    flags |= FAST_PATH_ROTATE_270_TRANSFORM;
 	    }
 	}
 
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index d2af51a..2ec2594 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -220,16 +220,33 @@ pixman_expand (uint64_t *           dst,
     for (i = width - 1; i >= 0; i--)
     {
 	const uint32_t pixel = src[i];
-	const uint8_t a = (pixel >> a_shift) & a_mask,
-	              r = (pixel >> r_shift) & r_mask,
-	              g = (pixel >> g_shift) & g_mask,
-	              b = (pixel >> b_shift) & b_mask;
-	const uint64_t
-	    a16 = a_size ? unorm_to_unorm (a, a_size, 16) : 0xffff,
-	    r16 = unorm_to_unorm (r, r_size, 16),
-	    g16 = unorm_to_unorm (g, g_size, 16),
-	    b16 = unorm_to_unorm (b, b_size, 16);
+	uint8_t a, r, g, b;
+	uint64_t a16, r16, g16, b16;
+
+	if (a_size)
+	{
+	    a = (pixel >> a_shift) & a_mask;
+	    a16 = unorm_to_unorm (a, a_size, 16);
+	}
+	else
+	{
+	    a16 = 0xffff;
+	}
 
+	if (r_size)
+	{
+	    r = (pixel >> r_shift) & r_mask;
+	    g = (pixel >> g_shift) & g_mask;
+	    b = (pixel >> b_shift) & b_mask;
+	    r16 = unorm_to_unorm (r, r_size, 16);
+	    g16 = unorm_to_unorm (g, g_size, 16);
+	    b16 = unorm_to_unorm (b, b_size, 16);
+	}
+	else
+	{
+	    r16 = g16 = b16 = 0;
+	}
+	
 	dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
     }
 }
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 63162e6..fd62c67 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -103,7 +103,7 @@ free_random_image (uint32_t initcrc,
 		mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
 	    }
 
-	    for (i = 0; i < 32; i++)
+	    for (i = 0; i * PIXMAN_FORMAT_BPP (fmt) < 32; i++)
 		mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));
 
 	    for (i = 0; i < stride * height / 4; i++)
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
index 2372686..9524e28 100644
--- a/test/region-contains-test.c
+++ b/test/region-contains-test.c
@@ -73,7 +73,7 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
     case 3:
 	return begin;
     default:
-	return (begin + end) / 2;
+	return (end - begin) / 2 + begin;
     }
     return 0;
 }
@@ -163,7 +163,7 @@ main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("region_contains",
 			     1000000,
-			     0xD7C297CC,
+			     0xD2BF8C73,
 			     test_region_contains_rectangle,
 			     argc, argv);
 }
diff --git a/test/stress-test.c b/test/stress-test.c
index 08bf1d4..3174621 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -166,7 +166,8 @@ fake_reader (const void *src, int size)
     uint32_t r = lcg_rand_u32 ();
 
     assert (size == 1 || size == 2 || size == 4);
-    return r & ((1 << (size * 8)) - 1);
+
+    return r >> (32 - (size * 8));
 }
 
 static void
commit d788f762788c2178970ff0ff2cb6e0097171cc3c
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sun Dec 18 09:54:47 2011 -0500

    Add missing cast in _pixman_edge_multi_init()
    
    nx and e->dy are both 32 bit quantities, so a cast is needed to make
    sure their product is 64 bit before subtracting it from a 64 bit
    quantity.

diff --git a/pixman/pixman-trap.c b/pixman/pixman-trap.c
index c99f03e..adf5d7b 100644
--- a/pixman/pixman-trap.c
+++ b/pixman/pixman-trap.c
@@ -139,7 +139,7 @@ _pixman_edge_multi_init (pixman_edge_t * e,
     if (ne > 0)
     {
 	int nx = ne / e->dy;
-	ne -= nx * e->dy;
+	ne -= nx * (pixman_fixed_48_16_t)e->dy;
 	stepx += nx * e->signdx;
     }
 
commit 4f3fe9c9096b2261217c2d4beb7d5eb8e578ed76
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sun Dec 18 08:16:45 2011 -0500

    Fix some signed overflow bugs
    
    In the macros for the PDF blend modes, two comp1_t variables are
    multiplied together and then used as if the result were a
    comp4_t. When comp1_t is a uint8_t, this is fine because they are
    promoted to int, and the product of two uint8_ts fits in an
    int. However, when comp1_t is uint16, the product does not necessarily
    fit in an int, so casts are necessary.
    
    Fix for bug 43906, reported by Siarhei Siamashka.

diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template
index c17bcea..cd008d9 100644
--- a/pixman/pixman-combine.c.template
+++ b/pixman/pixman-combine.c.template
@@ -522,7 +522,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
 	    UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida);	\
 	    								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UNc (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) +		\
 		(blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \
 		(blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \
 		(blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa));	\
@@ -552,7 +552,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
 	    UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida);     \
             								\
 	    result +=							\
-	        (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) +		\
+	        (DIV_ONE_UNc (ALPHA_c (m) * (comp4_t)da) << A_SHIFT) +	\
 	        (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \
 	        (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \
 	        (blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \
@@ -926,7 +926,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
 	    blend_ ## name (c, dc, da, sc, sa);				\
             								\
 	    *(dest + i) = result +					\
-		(DIV_ONE_UNc (sa * da) << A_SHIFT) +			\
+		(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) +		\
 		(DIV_ONE_UNc (c[0]) << R_SHIFT) +			\
 		(DIV_ONE_UNc (c[1]) << G_SHIFT) +			\
 		(DIV_ONE_UNc (c[2]));					\
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 55b6c73..63162e6 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -424,6 +424,6 @@ main (int argc, const char *argv[])
     }
 
     return fuzzer_test_main("blitters", 2000000,
-			    0x29137844,
+			    0x3EDA4108,
 			    test_composite, argc, argv);
 }
commit 3e93bba3b04b42c2ab99d828dae12c18f29bcf7d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Thu Jan 5 10:37:51 2012 -0500

    pixman-image.c: Fix typo in pixman_image_set_transform()
    
    A parenthesis was misplaced so that the size argument to memcmp() was
    always 0. The bug is harmless except that the flags might be
    unnecessarily recomputed in some cases.
    
    A bug reporting this in Mozilla's fork was discovered here:
    
        https://bugzilla.mozilla.org/show_bug.cgi?id=710992

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 913853c..ad5996b 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -631,7 +631,7 @@ pixman_image_set_transform (pixman_image_t *          image,
     }
 
     if (common->transform &&
-	memcmp (common->transform, transform, sizeof (pixman_transform_t) == 0))
+	memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
     {
 	return TRUE;
     }


More information about the xorg-commit mailing list