pixman: Branch 'master' - 7 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Fri Dec 17 14:08:21 PST 2010


 configure.ac               |    8 
 test/Makefile.am           |   10 
 test/blitters-test.c       |   57 ---
 test/composite.c           |   56 +-
 test/gradient-crash-test.c |  124 ++++--
 test/stress-test.c         |  855 +++++++++++++++++++++++++++++++++++++++++++++
 test/utils.c               |   89 ++++
 test/utils.h               |   19 -
 8 files changed, 1087 insertions(+), 131 deletions(-)

New commits:
commit f914cf448630d4ba4af6603b827c621ae6705387
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Mon Aug 23 21:55:02 2010 -0400

    Add a stress-test program.
    
    This test program tries to use as many rarely-used features as
    possible, including alpha maps, accessor functions, oddly-sized
    images, strange transformations, conical gradients, etc.
    
    The hope is to provoke crashes or irregular behavior in pixman.

diff --git a/test/Makefile.am b/test/Makefile.am
index d7b5b7f..52e4183 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -15,6 +15,7 @@ TESTPROGRAMS =			\
 	scaling-crash-test	\
 	gradient-crash-test	\
 	alphamap		\
+	stress-test		\
 	blitters-test		\
 	scaling-test		\
 	affine-test		\
@@ -51,6 +52,9 @@ composite_SOURCES = composite.c utils.c utils.h
 gradient_crash_test_LDADD = $(TEST_LDADD)
 gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
 
+stress_test_LDADD = $(TEST_LDADD)
+stress_test_SOURCES = stress-test.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/stress-test.c b/test/stress-test.c
new file mode 100644
index 0000000..bcbc1f8
--- /dev/null
+++ b/test/stress-test.c
@@ -0,0 +1,855 @@
+#include "utils.h"
+
+#if 0
+#define fence_malloc malloc
+#define fence_free free
+#define make_random_bytes malloc
+#endif
+
+static const pixman_format_code_t image_formats[] =
+{
+    PIXMAN_a8r8g8b8,
+    PIXMAN_x8r8g8b8,
+    PIXMAN_r5g6b5,
+    PIXMAN_r3g3b2,
+    PIXMAN_a8,
+    PIXMAN_a8b8g8r8,
+    PIXMAN_x8b8g8r8,
+    PIXMAN_b8g8r8a8,
+    PIXMAN_b8g8r8x8,
+    PIXMAN_x14r6g6b6,
+    PIXMAN_r8g8b8,
+    PIXMAN_b8g8r8,
+    PIXMAN_r5g6b5,
+    PIXMAN_b5g6r5,
+    PIXMAN_x2r10g10b10,
+    PIXMAN_a2r10g10b10,
+    PIXMAN_x2b10g10r10,
+    PIXMAN_a2b10g10r10,
+    PIXMAN_a1r5g5b5,
+    PIXMAN_x1r5g5b5,
+    PIXMAN_a1b5g5r5,
+    PIXMAN_x1b5g5r5,
+    PIXMAN_a4r4g4b4,
+    PIXMAN_x4r4g4b4,
+    PIXMAN_a4b4g4r4,
+    PIXMAN_x4b4g4r4,
+    PIXMAN_a8,
+    PIXMAN_r3g3b2,
+    PIXMAN_b2g3r3,
+    PIXMAN_a2r2g2b2,
+    PIXMAN_a2b2g2r2,
+    PIXMAN_c8,
+    PIXMAN_g8,
+    PIXMAN_x4c4,
+    PIXMAN_x4g4,
+    PIXMAN_c4,
+    PIXMAN_g4,
+    PIXMAN_g1,
+    PIXMAN_x4a4,
+    PIXMAN_a4,
+    PIXMAN_r1g2b1,
+    PIXMAN_b1g2r1,
+    PIXMAN_a1r1g1b1,
+    PIXMAN_a1b1g1r1,
+    PIXMAN_a1
+};
+
+static pixman_filter_t filters[] =
+{
+    PIXMAN_FILTER_NEAREST,
+    PIXMAN_FILTER_BILINEAR,
+    PIXMAN_FILTER_FAST,
+    PIXMAN_FILTER_GOOD,
+    PIXMAN_FILTER_BEST,
+    PIXMAN_FILTER_CONVOLUTION
+};
+
+static int
+get_size (void)
+{
+    switch (lcg_rand_n (28))
+    {
+    case 0:
+	return 1;
+
+    case 1:
+	return 2;
+
+    default:
+    case 2:
+	return lcg_rand_n (200);
+
+    case 4:
+	return lcg_rand_n (2000) + 1000;
+
+    case 5:
+	return 65535;
+
+    case 6:
+	return 65536;
+
+    case 7:
+	return lcg_rand_N (64000) + 63000;
+    }
+}
+
+static void
+destroy (pixman_image_t *image, void *data)
+{
+    if (image->type == BITS && image->bits.free_me != image->bits.bits)
+    {
+	uint32_t *bits;
+
+	if (image->bits.bits != (void *)0x01)
+	{
+	    bits = image->bits.bits;
+
+	    if (image->bits.rowstride < 0)
+		bits -= (- image->bits.rowstride * (image->bits.height - 1));
+
+	    fence_free (bits);
+	}
+    }
+
+    free (data);
+}
+
+static uint32_t
+real_reader (const void *src, int size)
+{
+    switch (size)
+    {
+    case 1:
+	return *(uint8_t *)src;
+    case 2:
+	return *(uint16_t *)src;
+    case 4:
+	return *(uint32_t *)src;
+    default:
+	assert (0);
+	break;
+    }
+}
+
+static void
+real_writer (void *src, uint32_t value, int size)
+{
+    switch (size)
+    {
+    case 1:
+	*(uint8_t *)src = value;
+	break;
+
+    case 2:
+	*(uint16_t *)src = value;
+	break;
+
+    case 4:
+	*(uint32_t *)src = value;
+	break;
+
+    default:
+	assert (0);
+	break;
+    }
+}
+
+static uint32_t
+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);
+}
+
+static void
+fake_writer (void *src, uint32_t value, int size)
+{
+    assert (size == 1 || size == 2 || size == 4);
+}
+
+static int32_t
+log_rand (void)
+{
+    uint32_t mask;
+
+    mask = (1 << lcg_rand_n (31)) - 1;
+
+    return (lcg_rand () & mask) - (mask >> 1);
+}
+
+static pixman_image_t *
+create_random_bits_image (void)
+{
+    pixman_format_code_t format;
+    pixman_indexed_t *indexed;
+    pixman_image_t *image;
+    int width, height, stride;
+    uint32_t *bits;
+    pixman_read_memory_func_t read_func = NULL;
+    pixman_write_memory_func_t write_func = NULL;
+    pixman_filter_t filter;
+    pixman_fixed_t *coefficients = NULL;
+    int n_coefficients = 0;
+
+    /* format */
+    format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))];
+
+    indexed = NULL;
+    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
+    {
+	indexed = malloc (sizeof (pixman_indexed_t));
+
+	initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), TRUE);
+    }
+    else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
+    {
+	indexed = malloc (sizeof (pixman_indexed_t));
+
+	initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), FALSE);
+    }
+    else
+    {
+	indexed = NULL;
+    }
+
+    /* size */
+    width = get_size ();
+    height = get_size ();
+
+    if ((uint64_t)width * height > 200000)
+    {
+	if (lcg_rand_n(2) == 0)
+	    height = 200000 / width;
+	else
+	    width = 200000 / height;
+    }
+
+    if (height == 0)
+	height = 1;
+    if (width == 0)
+	width = 1;
+
+    /* bits */
+    switch (lcg_rand_n (7))
+    {
+    default:
+    case 0:
+	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = (stride + 3) & (~3);
+	bits = (uint32_t *)make_random_bytes (height * stride);
+	break;
+
+    case 1:
+	stride = 0;
+	bits = NULL;
+	break;
+
+    case 2: /* Zero-filled */
+	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = (stride + 3) & (~3);
+	bits = fence_malloc (height * stride);
+	if (!bits)
+	    return NULL;
+	memset (bits, 0, height * stride);
+	break;
+
+    case 3: /* Filled with 0xFF */
+	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = (stride + 3) & (~3);
+	bits = fence_malloc (height * stride);
+	if (!bits)
+	    return NULL;
+	memset (bits, 0xff, height * stride);
+	break;
+
+    case 4: /* bits is a bad pointer, has read/write functions */
+	stride = 232;
+	bits = (void *)0x01;
+	read_func = fake_reader;
+	write_func = fake_writer;
+	break;
+
+    case 5: /* bits is a real pointer, has read/write functions */
+	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = (stride + 3) & (~3);
+	bits = fence_malloc (height * stride);
+	if (!bits)
+	    return NULL;
+	memset (bits, 0xff, height * stride);
+	read_func = real_reader;
+	write_func = real_writer;
+	break;
+
+    case 6: /* bits is a real pointer, stride is negative */
+	stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17));
+	stride = (stride + 3) & (~3);
+	bits = (uint32_t *)make_random_bytes (height * stride);
+	if (!bits)
+	    return NULL;
+	bits += ((height - 1) * stride) / 4;
+	stride = - stride;
+	break;
+    }
+
+    /* Filter */
+    filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))];
+    if (filter == PIXMAN_FILTER_CONVOLUTION)
+    {
+	int width = lcg_rand_n (17);
+	int height = lcg_rand_n (19);
+
+	n_coefficients = width * height + 2;
+	coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t));
+
+	if (coefficients)
+	{
+	    int i;
+
+	    for (i = 0; i < width * height; ++i)
+		coefficients[i + 2] = lcg_rand_u32();
+
+	    coefficients[0] = width << 16;
+	    coefficients[1] = height << 16;
+	}
+	else
+	{
+	    filter = PIXMAN_FILTER_BEST;
+	}
+    }
+
+    /* Finally create the image */
+    image = pixman_image_create_bits (format, width, height, bits, stride);
+    if (!image)
+	return NULL;
+
+    pixman_image_set_indexed (image, indexed);
+    pixman_image_set_destroy_function (image, destroy, indexed);
+    pixman_image_set_accessors (image, read_func, write_func);
+    pixman_image_set_filter (image, filter, coefficients, n_coefficients);
+
+    return image;
+}
+
+static pixman_repeat_t repeats[] =
+{
+    PIXMAN_REPEAT_NONE,
+    PIXMAN_REPEAT_NORMAL,
+    PIXMAN_REPEAT_REFLECT,
+    PIXMAN_REPEAT_PAD
+};
+
+static uint32_t
+absolute (int32_t i)
+{
+    return i < 0? -i : i;
+}
+
+static void
+set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
+{
+    pixman_repeat_t repeat;
+
+    /* Set properties that are generic to all images */
+
+    /* Repeat */
+    repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))];
+    pixman_image_set_repeat (image, repeat);
+
+    /* Alpha map */
+    if (allow_alpha_map && lcg_rand_n (3) == 0)
+    {
+	pixman_image_t *alpha_map;
+	int16_t x, y;
+
+	alpha_map = create_random_bits_image ();
+
+	if (alpha_map)
+	{
+	    set_general_properties (alpha_map, FALSE);
+
+	    x = lcg_rand_N (100000) - 65536;
+	    y = lcg_rand_N (100000) - 65536;
+
+	    pixman_image_set_alpha_map (image, alpha_map, x, y);
+
+	    pixman_image_unref (alpha_map);
+	}
+    }
+
+    /* Component alpha */
+    pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0);
+
+    /* Clip region */
+    if (lcg_rand_n (8) != 0)
+    {
+	pixman_region32_t region;
+	int i, n_rects;
+
+	pixman_region32_init (&region);
+
+	switch (lcg_rand_n (10))
+	{
+	case 0:
+	    n_rects = 0;
+	    break;
+
+	case 1: case 2: case 3:
+	    n_rects = 1;
+	    break;
+
+	case 4: case 5:
+	    n_rects = 2;
+	    break;
+
+	case 6: case 7:
+	    n_rects = 3;
+
+	default:
+	    n_rects = lcg_rand_n (100);
+	    break;
+	}
+
+	for (i = 0; i < n_rects; ++i)
+	{
+	    uint32_t width, height;
+	    int x, y;
+
+	    x = log_rand();
+	    y = log_rand();
+	    width = absolute (log_rand ()) + 1;
+	    height = absolute (log_rand ()) + 1;
+
+	    pixman_region32_union_rect (
+		&region, &region, x, y, width, height);
+	}
+
+	pixman_image_set_clip_region32 (image, &region);
+
+	pixman_region32_fini (&region);
+    }
+
+    /* Whether source clipping is enabled */
+    pixman_image_set_source_clipping (image, !!lcg_rand_n (2));
+
+    /* Client clip */
+    pixman_image_set_has_client_clip (image, !!lcg_rand_n (2));
+
+    /* Transform */
+    if (lcg_rand_n (5) < 2)
+    {
+	pixman_transform_t xform;
+	int i, j, k;
+	uint32_t tx, ty, sx, sy;
+	uint32_t c, s;
+
+	memset (&xform, 0, sizeof xform);
+	xform.matrix[0][0] = pixman_fixed_1;
+	xform.matrix[1][1] = pixman_fixed_1;
+	xform.matrix[2][2] = pixman_fixed_1;
+
+	for (k = 0; k < 3; ++k)
+	{
+	    switch (lcg_rand_n (4))
+	    {
+	    case 0:
+		/* rotation */
+		c = lcg_rand_N (2 * 65536) - 65536;
+		s = lcg_rand_N (2 * 65536) - 65536;
+		pixman_transform_rotate (&xform, NULL, c, s);
+		break;
+
+	    case 1:
+		/* translation */
+		tx = lcg_rand_u32();
+		ty = lcg_rand_u32();
+		pixman_transform_translate (&xform, NULL, tx, ty);
+		break;
+
+	    case 2:
+		/* scale */
+		sx = lcg_rand_u32();
+		sy = lcg_rand_u32();
+		pixman_transform_scale (&xform, NULL, sx, sy);
+		break;
+
+	    case 3:
+		if (lcg_rand_n (16) == 0)
+		{
+		    /* random */
+		    for (i = 0; i < 3; ++i)
+			for (j = 0; j < 3; ++j)
+			    xform.matrix[i][j] = lcg_rand_u32();
+		    break;
+		}
+		else if (lcg_rand_n (16) == 0)
+		{
+		    /* zero */
+		    memset (&xform, 0, sizeof xform);
+		}
+		break;
+	    }
+	}
+
+	pixman_image_set_transform (image, &xform);
+    }
+}
+
+static pixman_color_t
+random_color (void)
+{
+    pixman_color_t color =
+    {
+	lcg_rand() & 0xffff,
+	lcg_rand() & 0xffff,
+	lcg_rand() & 0xffff,
+	lcg_rand() & 0xffff,
+    };
+
+    return color;
+}
+
+
+static pixman_image_t *
+create_random_solid_image (void)
+{
+    pixman_color_t color = random_color();
+    pixman_image_t *image = pixman_image_create_solid_fill (&color);
+
+    return image;
+}
+
+static pixman_gradient_stop_t *
+create_random_stops (int *n_stops)
+{
+    pixman_fixed_t step;
+    pixman_fixed_t s;
+    int i;
+    pixman_gradient_stop_t *stops;
+
+    *n_stops = lcg_rand_n (50) + 1;
+
+    step = pixman_fixed_1 / *n_stops;
+
+    stops = malloc (*n_stops * sizeof (pixman_gradient_stop_t));
+
+    s = 0;
+    for (i = 0; i < (*n_stops) - 1; ++i)
+    {
+	stops[i].x = s;
+	stops[i].color = random_color();
+
+	s += step;
+    }
+
+    stops[*n_stops - 1].x = pixman_fixed_1;
+    stops[*n_stops - 1].color = random_color();
+
+    return stops;
+}
+
+static pixman_point_fixed_t
+create_random_point (void)
+{
+    pixman_point_fixed_t p;
+
+    p.x = log_rand ();
+    p.y = log_rand ();
+
+    return p;
+}
+
+static pixman_image_t *
+create_random_linear_image (void)
+{
+    int n_stops;
+    pixman_gradient_stop_t *stops;
+    pixman_point_fixed_t p1, p2;
+    pixman_image_t *result;
+
+    stops = create_random_stops (&n_stops);
+    if (!stops)
+	return NULL;
+
+    p1 = create_random_point ();
+    p2 = create_random_point ();
+
+    result = pixman_image_create_linear_gradient (&p1, &p2, stops, n_stops);
+
+    free (stops);
+
+    return result;
+}
+
+static pixman_image_t *
+create_random_radial_image (void)
+{
+    int n_stops;
+    pixman_gradient_stop_t *stops;
+    pixman_point_fixed_t inner_c, outer_c;
+    pixman_fixed_t inner_r, outer_r;
+    pixman_image_t *result;
+
+    inner_c = create_random_point();
+    outer_c = create_random_point();
+    inner_r = lcg_rand();
+    outer_r = lcg_rand();
+
+    stops = create_random_stops (&n_stops);
+
+    if (!stops)
+	return NULL;
+
+    result = pixman_image_create_radial_gradient (
+	&inner_c, &outer_c, inner_r, outer_r, stops, n_stops);
+
+    free (stops);
+
+    return result;
+}
+
+static pixman_image_t *
+create_random_conical_image (void)
+{
+    pixman_gradient_stop_t *stops;
+    int n_stops;
+    pixman_point_fixed_t c;
+    pixman_fixed_t angle;
+    pixman_image_t *result;
+
+    c = create_random_point();
+    angle = lcg_rand();
+
+    stops = create_random_stops (&n_stops);
+
+    if (!stops)
+	return NULL;
+
+    result = pixman_image_create_conical_gradient (&c, angle, stops, n_stops);
+
+    free (stops);
+
+    return result;
+}
+
+static pixman_image_t *
+create_random_image (void)
+{
+    pixman_image_t *result;
+
+    switch (lcg_rand_n (5))
+    {
+    default:
+    case 0:
+	result = create_random_bits_image ();
+	break;
+
+    case 1:
+	result = create_random_solid_image ();
+	break;
+
+    case 2:
+	result = create_random_linear_image ();
+	break;
+
+    case 3:
+	result = create_random_radial_image ();
+	break;
+
+    case 4:
+	result = create_random_conical_image ();
+	break;
+    }
+
+    if (result)
+	set_general_properties (result, TRUE);
+
+    return result;
+}
+
+static const pixman_op_t op_list[] =
+{
+    PIXMAN_OP_SRC,
+    PIXMAN_OP_OVER,
+    PIXMAN_OP_ADD,
+    PIXMAN_OP_CLEAR,
+    PIXMAN_OP_SRC,
+    PIXMAN_OP_DST,
+    PIXMAN_OP_OVER,
+    PIXMAN_OP_OVER_REVERSE,
+    PIXMAN_OP_IN,
+    PIXMAN_OP_IN_REVERSE,
+    PIXMAN_OP_OUT,
+    PIXMAN_OP_OUT_REVERSE,
+    PIXMAN_OP_ATOP,
+    PIXMAN_OP_ATOP_REVERSE,
+    PIXMAN_OP_XOR,
+    PIXMAN_OP_ADD,
+    PIXMAN_OP_SATURATE,
+    PIXMAN_OP_DISJOINT_CLEAR,
+    PIXMAN_OP_DISJOINT_SRC,
+    PIXMAN_OP_DISJOINT_DST,
+    PIXMAN_OP_DISJOINT_OVER,
+    PIXMAN_OP_DISJOINT_OVER_REVERSE,
+    PIXMAN_OP_DISJOINT_IN,
+    PIXMAN_OP_DISJOINT_IN_REVERSE,
+    PIXMAN_OP_DISJOINT_OUT,
+    PIXMAN_OP_DISJOINT_OUT_REVERSE,
+    PIXMAN_OP_DISJOINT_ATOP,
+    PIXMAN_OP_DISJOINT_ATOP_REVERSE,
+    PIXMAN_OP_DISJOINT_XOR,
+    PIXMAN_OP_CONJOINT_CLEAR,
+    PIXMAN_OP_CONJOINT_SRC,
+    PIXMAN_OP_CONJOINT_DST,
+    PIXMAN_OP_CONJOINT_OVER,
+    PIXMAN_OP_CONJOINT_OVER_REVERSE,
+    PIXMAN_OP_CONJOINT_IN,
+    PIXMAN_OP_CONJOINT_IN_REVERSE,
+    PIXMAN_OP_CONJOINT_OUT,
+    PIXMAN_OP_CONJOINT_OUT_REVERSE,
+    PIXMAN_OP_CONJOINT_ATOP,
+    PIXMAN_OP_CONJOINT_ATOP_REVERSE,
+    PIXMAN_OP_CONJOINT_XOR,
+    PIXMAN_OP_MULTIPLY,
+    PIXMAN_OP_SCREEN,
+    PIXMAN_OP_OVERLAY,
+    PIXMAN_OP_DARKEN,
+    PIXMAN_OP_LIGHTEN,
+    PIXMAN_OP_COLOR_DODGE,
+    PIXMAN_OP_COLOR_BURN,
+    PIXMAN_OP_HARD_LIGHT,
+    PIXMAN_OP_DIFFERENCE,
+    PIXMAN_OP_EXCLUSION,
+    PIXMAN_OP_SOFT_LIGHT,
+    PIXMAN_OP_HSL_HUE,
+    PIXMAN_OP_HSL_SATURATION,
+    PIXMAN_OP_HSL_COLOR,
+    PIXMAN_OP_HSL_LUMINOSITY,
+};
+
+static void
+run_test (uint32_t seed)
+{
+    pixman_image_t *source, *mask, *dest;
+    pixman_op_t op;
+
+    lcg_srand (seed);
+
+    source = create_random_image ();
+    mask   = create_random_image ();
+    dest   = create_random_bits_image ();
+
+    if (source && mask && dest)
+    {
+	set_general_properties (dest, TRUE);
+
+	op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))];
+
+	pixman_image_composite32 (op,
+				  source, mask, dest,
+				  log_rand(), log_rand(),
+				  log_rand(), log_rand(),
+				  log_rand(), log_rand(),
+				  absolute (log_rand()),
+				  absolute (log_rand()));
+    }
+    if (source)
+	pixman_image_unref (source);
+    if (mask)
+	pixman_image_unref (mask);
+    if (dest)
+	pixman_image_unref (dest);
+}
+
+static pixman_bool_t
+get_int (char *s, uint32_t *i)
+{
+    char *end;
+    int p;
+
+    p = strtol (s, &end, 0);
+
+    if (end != s && *end == 0)
+    {
+	*i = p;
+	return TRUE;
+    }
+
+    return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+    int verbose = FALSE;
+    uint32_t seed = 1;
+    uint32_t n_tests = 0xffffffff;
+    uint32_t mod = 0;
+    uint32_t i;
+
+    pixman_disable_out_of_bounds_workaround ();
+
+    enable_fp_exceptions();
+
+    if (getenv ("VERBOSE") != NULL)
+	verbose = TRUE;
+
+    for (i = 1; i < argc; ++i)
+    {
+	if (strcmp (argv[i], "-v") == 0)
+	{
+	    verbose = TRUE;
+
+	    if (i + 1 < argc)
+	    {
+		get_int (argv[i + 1], &mod);
+		i++;
+	    }
+	}
+	else if (strcmp (argv[i], "-s") == 0 && i + 1 < argc)
+	{
+	    get_int (argv[i + 1], &seed);
+	    i++;
+	}
+	else if (strcmp (argv[i], "-n") == 0 && i + 1 < argc)
+	{
+	    get_int (argv[i + 1], &n_tests);
+	    i++;
+	}
+	else
+	{
+	    if (strcmp (argv[i], "-h") != 0)
+		printf ("Unknown option '%s'\n\n", argv[i]);
+
+	    printf ("Options:\n\n"
+		    "-n <number>        Number of tests to run\n"
+		    "-s <seed> 	        Seed of first test\n"
+		    "-v                 Print out seeds\n"
+		    "-v <n>             Print out every n'th seed\n\n");
+
+	    exit (-1);
+	}
+    }
+
+    if (n_tests == 0xffffffff)
+	n_tests = 8000;
+
+    /* FIXME: seed 2005763 fails in set_lum() with divide by zero */
+#ifdef USE_OPENMP
+#   pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed)
+#endif
+    for (i = seed; i < seed + n_tests; ++i)
+    {
+	if (verbose)
+	{
+	    if (mod == 0 || (i % mod) == 0)
+		printf ("Seed %d\n", i);
+	}
+
+	run_test (i);
+    }
+
+    return 0;
+}
diff --git a/test/utils.h b/test/utils.h
index abd11ec..9c7bdb1 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -41,6 +41,15 @@ lcg_rand_N (int max)
     return (lo | hi) % max;
 }
 
+static inline uint32_t
+lcg_rand_u32 (void)
+{
+    uint32_t lo = lcg_rand();
+    uint32_t hi = lcg_rand();
+
+    return (hi << 16) | lo;
+}
+
 /* CRC 32 computation
  */
 uint32_t
commit 7d7b03c0911584f687a7fd57a3f5d5eed21080e0
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Tue Oct 12 10:56:26 2010 -0400

    Make the argument to fence_malloc() an int64_t
    
    That way we can detect if someone attempts to allocate a negative size
    and abort instead of just returning NULL and segfaulting later.

diff --git a/test/utils.c b/test/utils.c
index cde9c62..a7abec5 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -232,7 +232,7 @@ typedef struct
 #endif
 
 void *
-fence_malloc (uint32_t len)
+fence_malloc (int64_t len)
 {
     unsigned long page_size = getpagesize();
     unsigned long page_mask = page_size - 1;
@@ -246,12 +246,15 @@ fence_malloc (uint32_t len)
     uint8_t *payload;
     uint8_t *addr;
 
+    if (len < 0)
+	abort();
+    
     addr = mmap (NULL, n_bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
 		 -1, 0);
 
     if (addr == MAP_FAILED)
     {
-	printf ("mmap failed on %u %u\n", len, n_bytes);
+	printf ("mmap failed on %lld %u\n", (long long int)len, n_bytes);
 	return NULL;
     }
 
diff --git a/test/utils.h b/test/utils.h
index 7b33461..abd11ec 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -57,7 +57,7 @@ image_endian_swap (pixman_image_t *img, int bpp);
  * so that out-of-bounds access will cause segfaults
  */
 void *
-fence_malloc (uint32_t len);
+fence_malloc (int64_t len);
 
 void
 fence_free (void *data);
commit d41522113ec84e74f7915599fd7624f842be8862
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sun Aug 29 18:02:02 2010 -0400

    test/utils.c: Initialize palette->rgba to 0.
    
    That way it can be used with palettes that are not statically
    allocated, without causing valgrind issues.

diff --git a/test/utils.c b/test/utils.c
index 4701bf6..cde9c62 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -528,6 +528,8 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
     for (i = 0; i < 32768; ++i)
 	palette->ent[i] = lcg_rand() & mask;
 
+    memset (palette->rgba, 0, sizeof (palette->rgba));
+
     for (i = 0; i < mask + 1; ++i)
     {
 	uint32_t rgba24;
commit 337f0bff0d8965cb702175e0eedbf418b1e7f0b5
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Mon Aug 23 21:02:02 2010 -0400

    test: Move palette initialization to utils.[ch]

diff --git a/test/blitters-test.c b/test/blitters-test.c
index 77a26dd..21685b1 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -400,59 +400,6 @@ test_composite (int testnum, int verbose)
     return crc32;
 }
 
-#define CONVERT_15(c, is_rgb)						\
-    (is_rgb?								\
-     ((((c) >> 3) & 0x001f) |						\
-      (((c) >> 6) & 0x03e0) |						\
-      (((c) >> 9) & 0x7c00)) :						\
-     (((((c) >> 16) & 0xff) * 153 +					\
-       (((c) >>  8) & 0xff) * 301 +					\
-       (((c)      ) & 0xff) * 58) >> 2))
-
-static void
-initialize_palette (pixman_indexed_t *palette, uint32_t mask, int is_rgb)
-{
-    int i;
-
-    for (i = 0; i < 32768; ++i)
-	palette->ent[i] = lcg_rand() & mask;
-
-    for (i = 0; i < mask + 1; ++i)
-    {
-	uint32_t rgba24;
- 	pixman_bool_t retry;
-	uint32_t i15;
-
-	/* We filled the rgb->index map with random numbers, but we
-	 * do need the ability to round trip, that is if some indexed
-	 * color expands to an argb24, then the 15 bit version of that
-	 * color must map back to the index. Anything else, we don't
-	 * care about too much.
-	 */
-	do
-	{
-	    uint32_t old_idx;
-	    
-	    rgba24 = lcg_rand();
-	    i15 = CONVERT_15 (rgba24, is_rgb);
-
-	    old_idx = palette->ent[i15];
-	    if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
-		retry = 1;
-	    else
-		retry = 0;
-	} while (retry);
-	
-	palette->rgba[i] = rgba24;
-	palette->ent[i15] = i;
-    }
-
-    for (i = 0; i < mask + 1; ++i)
-    {
-	assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
-    }
-}
-
 int
 main (int argc, const char *argv[])
 {
@@ -460,8 +407,8 @@ main (int argc, const char *argv[])
 
     for (i = 1; i <= 8; i++)
     {
-	initialize_palette (&(rgb_palette[i]), (1 << i) - 1, TRUE);
-	initialize_palette (&(y_palette[i]), (1 << i) - 1, FALSE);
+	initialize_palette (&(rgb_palette[i]), i, TRUE);
+	initialize_palette (&(y_palette[i]), i, FALSE);
     }
 
     return fuzzer_test_main("blitters", 2000000,
diff --git a/test/utils.c b/test/utils.c
index a7c55f6..4701bf6 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -509,3 +509,57 @@ aligned_malloc (size_t align, size_t size)
 
     return result;
 }
+
+#define CONVERT_15(c, is_rgb)						\
+    (is_rgb?								\
+     ((((c) >> 3) & 0x001f) |						\
+      (((c) >> 6) & 0x03e0) |						\
+      (((c) >> 9) & 0x7c00)) :						\
+     (((((c) >> 16) & 0xff) * 153 +					\
+       (((c) >>  8) & 0xff) * 301 +					\
+       (((c)      ) & 0xff) * 58) >> 2))
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
+{
+    int i;
+    uint32_t mask = (1 << depth) - 1;
+
+    for (i = 0; i < 32768; ++i)
+	palette->ent[i] = lcg_rand() & mask;
+
+    for (i = 0; i < mask + 1; ++i)
+    {
+	uint32_t rgba24;
+ 	pixman_bool_t retry;
+	uint32_t i15;
+
+	/* We filled the rgb->index map with random numbers, but we
+	 * do need the ability to round trip, that is if some indexed
+	 * color expands to an argb24, then the 15 bit version of that
+	 * color must map back to the index. Anything else, we don't
+	 * care about too much.
+	 */
+	do
+	{
+	    uint32_t old_idx;
+
+	    rgba24 = lcg_rand();
+	    i15 = CONVERT_15 (rgba24, is_rgb);
+
+	    old_idx = palette->ent[i15];
+	    if (CONVERT_15 (palette->rgba[old_idx], is_rgb) == i15)
+		retry = 1;
+	    else
+		retry = 0;
+	} while (retry);
+
+	palette->rgba[i] = rgba24;
+	palette->ent[i15] = i;
+    }
+
+    for (i = 0; i < mask + 1; ++i)
+    {
+	assert (palette->ent[CONVERT_15 (palette->rgba[i], is_rgb)] == i);
+    }
+}
diff --git a/test/utils.h b/test/utils.h
index bac2916..7b33461 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -123,3 +123,6 @@ void enable_fp_exceptions(void);
 /* Try to get an aligned memory chunk */
 void *
 aligned_malloc (size_t align, size_t size);
+
+void
+initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb);
commit 2444b2265abeaf6dcf3df1763bc2711684e63bb8
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Oct 20 13:12:37 2010 -0400

    Extend gradient-crash-test
    
    Test the gradients with various transformations, and test cases where
    the gradients are specified with two identical points.

diff --git a/test/Makefile.am b/test/Makefile.am
index 79a1223..d7b5b7f 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -10,10 +10,10 @@ TESTPROGRAMS =			\
 	region-translate-test	\
 	fetch-test		\
 	oob-test		\
-	gradient-crash-test	\
 	trap-crasher		\
 	alpha-loop		\
 	scaling-crash-test	\
+	gradient-crash-test	\
 	alphamap		\
 	blitters-test		\
 	scaling-test		\
@@ -22,7 +22,6 @@ TESTPROGRAMS =			\
 
 a1_trap_test_LDADD = $(TEST_LDADD)
 fetch_test_LDADD = $(TEST_LDADD)
-gradient_crash_test_LDADD = $(TEST_LDADD)
 trap_crasher_LDADD = $(TEST_LDADD)
 oob_test_LDADD = $(TEST_LDADD)
 scaling_crash_test_LDADD = $(TEST_LDADD)
@@ -49,6 +48,9 @@ alpha_loop_SOURCES = alpha-loop.c utils.c utils.h
 composite_LDADD = $(TEST_LDADD)
 composite_SOURCES = composite.c utils.c utils.h
 
+gradient_crash_test_LDADD = $(TEST_LDADD)
+gradient_crash_test_SOURCES = gradient-crash-test.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
diff --git a/test/gradient-crash-test.c b/test/gradient-crash-test.c
index 804f83b..395c469 100644
--- a/test/gradient-crash-test.c
+++ b/test/gradient-crash-test.c
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include "pixman.h"
+#include <fenv.h>
+#include "utils.h"
 
 int
 main (int argc, char **argv)
@@ -11,8 +12,14 @@ main (int argc, char **argv)
     uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
     pixman_image_t *src_img;
     pixman_image_t *dest_img;
-    int i, j;
+    int i, j, k, p;
 
+    typedef struct
+    {
+	pixman_point_fixed_t p0;
+	pixman_point_fixed_t p1;
+    } point_pair_t;
+    
     pixman_gradient_stop_t onestop[1] =
 	{
 	    { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
@@ -30,29 +37,56 @@ main (int argc, char **argv)
 	    { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } }
 	};
 
-    pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
-    pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH / 8.),
-				pixman_int_to_fixed (0) };
-
-#if 0
-    pixman_transform_t trans = {
-	{ { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
-	  { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
-	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
-	}
-    };
-#else
-    pixman_transform_t trans = {
-	{ { pixman_fixed_1, 0, 0 },
-	  { 0, pixman_fixed_1, 0 },
-	  { 0, 0, pixman_fixed_1 } }
+    point_pair_t point_pairs [] =
+	{ { { pixman_double_to_fixed (0), 0 },
+	    { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } },
+	  { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) },
+	    { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } }
+	};
+    
+    pixman_transform_t transformations[] = {
+	{
+	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
+	      { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
+	    }
+	},
+	{
+	    { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
+	    }
+	},
+	{
+	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) } 
+	    }
+	},
+	{
+	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) } 
+	    }
+	},
+	{
+	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 
+	    }
+	},
+	{
+	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (3), },
+	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
+	      { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 
+	    }
+	},
     };
-#endif
-
-    pixman_point_fixed_t c_inner;
-    pixman_point_fixed_t c_outer;
+    
     pixman_fixed_t r_inner;
     pixman_fixed_t r_outer;
+
+    enable_fp_exceptions();
     
     for (i = 0; i < WIDTH * HEIGHT; ++i)
 	dest[i] = 0x4f00004f; /* pale blue */
@@ -62,10 +96,6 @@ main (int argc, char **argv)
 					 dest,
 					 WIDTH * 4);
 
-    c_inner.x = pixman_double_to_fixed (50.0);
-    c_inner.y = pixman_double_to_fixed (50.0);
-    c_outer.x = pixman_double_to_fixed (50.0);
-    c_outer.y = pixman_double_to_fixed (50.0);
     r_inner = 0;
     r_outer = pixman_double_to_fixed (50.0);
     
@@ -73,6 +103,7 @@ main (int argc, char **argv)
     {
 	pixman_gradient_stop_t *stops;
         int num_stops;
+
 	if (i == 0)
 	{
 	    stops = onestop;
@@ -91,23 +122,34 @@ main (int argc, char **argv)
 	
 	for (j = 0; j < 3; ++j)
 	{
-	    if (j == 0)
-	        src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
-								stops, num_stops);
-	    else if (j == 1)
-	        src_img = pixman_image_create_radial_gradient  (&c_inner, &c_outer,
-								r_inner, r_outer,
-								stops, num_stops);
-	    else
-	        src_img = pixman_image_create_linear_gradient  (&p1, &p2,
-								stops, num_stops);
-	    pixman_image_set_transform (src_img, &trans);
-	    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE);
-	    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
-				    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+	    for (p = 0; p < ARRAY_LENGTH (point_pairs); ++p)
+	    {
+		point_pair_t *pair = &(point_pairs[p]);
+
+		if (j == 0)
+		    src_img = pixman_image_create_conical_gradient (&(pair->p0), r_inner,
+								    stops, num_stops);
+		else if (j == 1)
+		    src_img = pixman_image_create_radial_gradient  (&(pair->p0), &(pair->p1),
+								    r_inner, r_outer,
+								    stops, num_stops);
+		else
+		    src_img = pixman_image_create_linear_gradient  (&(pair->p0), &(pair->p1),
+								    stops, num_stops);
+		
+		for (k = 0; k < ARRAY_LENGTH (transformations); ++k)
+		{
+		    pixman_image_set_transform (src_img, &transformations[k]);
+		    
+		    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE);
+		    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
+					    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
+		}
+
+		pixman_image_unref (src_img);
+	    }
 
 	}
-	pixman_image_unref (src_img);
     }
 
     pixman_image_unref (dest_img);
commit de2e51dacb1ccd312c0461088b942ef4e93e2731
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Oct 20 13:53:07 2010 -0400

    Add enable_fp_exceptions() function in utils.[ch]
    
    This function enables floating point traps if possible.

diff --git a/configure.ac b/configure.ac
index 147e1bf..2570c84 100644
--- a/configure.ac
+++ b/configure.ac
@@ -639,6 +639,14 @@ if test x$have_getpagesize = xyes; then
    AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()])
 fi
 
+AC_CHECK_HEADER([fenv.h],
+   [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have <fenv.h>])])
+
+AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no)
+if test x$have_feenableexcept = xyes; then
+   AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()])
+fi
+
 AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no)
 AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no)
 if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then
diff --git a/test/utils.c b/test/utils.c
index f6278fe..a7c55f6 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -1,3 +1,5 @@
+#define _GNU_SOURCE
+
 #include "utils.h"
 #include <signal.h>
 
@@ -15,6 +17,10 @@
 #include <sys/mman.h>
 #endif
 
+#ifdef HAVE_FENV_H
+#include <fenv.h>
+#endif
+
 /* Random number seed
  */
 
@@ -469,6 +475,26 @@ fail_after (int seconds, const char *msg)
 #endif
 }
 
+void
+enable_fp_exceptions (void)
+{
+#ifdef HAVE_FENV_H
+#ifdef HAVE_FEENABLEEXCEPT
+    /* Note: we don't enable the FE_INEXACT trap because
+     * that happens quite commonly. It is possible that
+     * over- and underflow should similarly be considered
+     * okay, but for now the test suite passes with them
+     * enabled, and it's useful to know if they start
+     * occuring.
+     */
+    feenableexcept (FE_DIVBYZERO	|
+		    FE_INVALID		|
+		    FE_OVERFLOW		|
+		    FE_UNDERFLOW);
+#endif
+#endif
+}
+
 void *
 aligned_malloc (size_t align, size_t size)
 {
diff --git a/test/utils.h b/test/utils.h
index 2ea4170..bac2916 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -82,6 +82,9 @@ fuzzer_test_main (const char *test_name,
 void
 fail_after (int seconds, const char *msg);
 
+/* If possible, enable traps for floating point exceptions */
+void enable_fp_exceptions(void);
+
 /* A pair of macros which can help to detect corruption of
  * floating point registers after a function call. This may
  * happen if _mm_empty() call is forgotten in MMX/SSE2 fast
commit a2afcc9ba4ed5a2843fd133ca23704960846185b
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Mon Aug 23 20:56:11 2010 -0400

    test: Make composite test use some existing macros instead of defining its own
    
    Also move the ARRAY_LENGTH macro into utils.h so it can be used elsewhere.

diff --git a/test/composite.c b/test/composite.c
index 5cdc521..e14f954 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -31,10 +31,6 @@
 #include <time.h>
 #include "utils.h"
 
-#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
-#define min(a,b) ((a) <= (b) ? (a) : (b))
-#define max(a,b) ((a) >= (b) ? (a) : (b))
-
 typedef struct color_t color_t;
 typedef struct format_t format_t;
 typedef struct image_t image_t;
@@ -211,7 +207,7 @@ static const operator_t operators[] =
 static double
 calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
 {
-#define mult_chan(src, dst, Fa, Fb) min ((src) * (Fa) + (dst) * (Fb), 1.0)
+#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0)
 
     double Fa, Fb;
 
@@ -267,150 +263,150 @@ calc_op (pixman_op_t op, double src, double dst, double srca, double dsta)
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, (1.0 - dsta) / srca);
+	    Fa = MIN (1.0, (1.0 - dsta) / srca);
 	return mult_chan (src, dst, Fa, 1.0);
 
     case PIXMAN_OP_DISJOINT_OVER:
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, (1.0 - srca) / dsta);
+	    Fb = MIN (1.0, (1.0 - srca) / dsta);
 	return mult_chan (src, dst, 1.0, Fb);
 
     case PIXMAN_OP_DISJOINT_IN:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+	    Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
 	return mult_chan (src, dst, Fa, 0.0);
 
     case PIXMAN_OP_DISJOINT_IN_REVERSE:
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+	    Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
 	return mult_chan (src, dst, 0.0, Fb);
 
     case PIXMAN_OP_DISJOINT_OUT:
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, (1.0 - dsta) / srca);
+	    Fa = MIN (1.0, (1.0 - dsta) / srca);
 	return mult_chan (src, dst, Fa, 0.0);
 
     case PIXMAN_OP_DISJOINT_OUT_REVERSE:
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, (1.0 - srca) / dsta);
+	    Fb = MIN (1.0, (1.0 - srca) / dsta);
 	return mult_chan (src, dst, 0.0, Fb);
 
     case PIXMAN_OP_DISJOINT_ATOP:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - (1.0 - dsta) / srca);
+	    Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca);
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, (1.0 - srca) / dsta);
+	    Fb = MIN (1.0, (1.0 - srca) / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_DISJOINT_ATOP_REVERSE:
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, (1.0 - dsta) / srca);
+	    Fa = MIN (1.0, (1.0 - dsta) / srca);
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - (1.0 - srca) / dsta);
+	    Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_DISJOINT_XOR:
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, (1.0 - dsta) / srca);
+	    Fa = MIN (1.0, (1.0 - dsta) / srca);
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, (1.0 - srca) / dsta);
+	    Fb = MIN (1.0, (1.0 - srca) / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_CONJOINT_OVER:
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - srca / dsta);
+	    Fb = MAX (0.0, 1.0 - srca / dsta);
 	return mult_chan (src, dst, 1.0, Fb);
 
     case PIXMAN_OP_CONJOINT_OVER_REVERSE:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - dsta / srca);
+	    Fa = MAX (0.0, 1.0 - dsta / srca);
 	return mult_chan (src, dst, Fa, 1.0);
 
     case PIXMAN_OP_CONJOINT_IN:
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, dsta / srca);
+	    Fa = MIN (1.0, dsta / srca);
 	return mult_chan (src, dst, Fa, 0.0);
 
     case PIXMAN_OP_CONJOINT_IN_REVERSE:
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, srca / dsta);
+	    Fb = MIN (1.0, srca / dsta);
 	return mult_chan (src, dst, 0.0, Fb);
 
     case PIXMAN_OP_CONJOINT_OUT:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - dsta / srca);
+	    Fa = MAX (0.0, 1.0 - dsta / srca);
 	return mult_chan (src, dst, Fa, 0.0);
 
     case PIXMAN_OP_CONJOINT_OUT_REVERSE:
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - srca / dsta);
+	    Fb = MAX (0.0, 1.0 - srca / dsta);
 	return mult_chan (src, dst, 0.0, Fb);
 
     case PIXMAN_OP_CONJOINT_ATOP:
 	if (srca == 0.0)
 	    Fa = 1.0;
 	else
-	    Fa = min (1.0, dsta / srca);
+	    Fa = MIN (1.0, dsta / srca);
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - srca / dsta);
+	    Fb = MAX (0.0, 1.0 - srca / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_CONJOINT_ATOP_REVERSE:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - dsta / srca);
+	    Fa = MAX (0.0, 1.0 - dsta / srca);
 	if (dsta == 0.0)
 	    Fb = 1.0;
 	else
-	    Fb = min (1.0, srca / dsta);
+	    Fb = MIN (1.0, srca / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_CONJOINT_XOR:
 	if (srca == 0.0)
 	    Fa = 0.0;
 	else
-	    Fa = max (0.0, 1.0 - dsta / srca);
+	    Fa = MAX (0.0, 1.0 - dsta / srca);
 	if (dsta == 0.0)
 	    Fb = 0.0;
 	else
-	    Fb = max (0.0, 1.0 - srca / dsta);
+	    Fb = MAX (0.0, 1.0 - srca / dsta);
 	return mult_chan (src, dst, Fa, Fb);
 
     case PIXMAN_OP_MULTIPLY:
@@ -617,7 +613,7 @@ eval_diff (color_t *expected, color_t *test, pixman_format_code_t format)
     gdiff = fabs (test->b - expected->b) * bscale;
     adiff = fabs (test->a - expected->a) * ascale;
 
-    return max (max (max (rdiff, gdiff), bdiff), adiff);
+    return MAX (MAX (MAX (rdiff, gdiff), bdiff), adiff);
 }
 
 static char *
diff --git a/test/utils.h b/test/utils.h
index e7920f0..2ea4170 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -3,6 +3,8 @@
 #include <assert.h>
 #include "pixman-private.h" /* For 'inline' definition */
 
+#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
+
 /* A primitive pseudorandom number generator,
  * taken from POSIX.1-2001 example
  */


More information about the xorg-commit mailing list