11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Test program, which can detect some problems with affine transformations
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * in pixman. Testing is done by running lots of random SRC and OVER
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * compositing operations a8r8g8b8, x8a8r8g8b8, r5g6b5 and a8 color formats
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * with random scaled, rotated and translated transforms.
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck *
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Script 'fuzzer-find-diff.pl' can be used to narrow down the problem in
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * the case of test failure.
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <assert.h>
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdlib.h>
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <stdio.h>
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "utils.h"
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAX_SRC_WIDTH  16
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAX_SRC_HEIGHT 16
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAX_DST_WIDTH  16
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAX_DST_HEIGHT 16
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define MAX_STRIDE     4
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/*
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck * Composite operation with pseudorandom images
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck */
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reckuint32_t
251176bdada62cabc6ec4b0308a930e83b679d5d36John Recktest_composite (int      testnum,
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		int      verbose)
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                i;
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *   src_img;
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_t *   dst_img;
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_transform_t transform;
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_region16_t  clip;
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                src_width, src_height;
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                dst_width, dst_height;
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                src_stride, dst_stride;
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                src_x, src_y;
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                dst_x, dst_y;
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                src_bpp;
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                dst_bpp;
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    int                w, h;
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t     scale_x = 65536, scale_y = 65536;
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_fixed_t     translate_x = 0, translate_y = 0;
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_op_t        op;
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_repeat_t    repeat = PIXMAN_REPEAT_NONE;
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_format_code_t src_fmt, dst_fmt;
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *         srcbuf;
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t *         dstbuf;
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    uint32_t           crc32;
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    FLOAT_REGS_CORRUPTION_DETECTOR_START ();
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    prng_srand (testnum);
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    op = (prng_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (src_stride & 3)
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	src_stride += 2;
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (dst_stride & 3)
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	dst_stride += 2;
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    w = prng_rand_n (dst_width * 3 / 2 - dst_x);
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    h = prng_rand_n (dst_height * 3 / 2 - dst_y);
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    srcbuf = (uint32_t *)malloc (src_stride * src_height);
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    prng_randmemset (srcbuf, src_stride * src_height, 0);
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    prng_randmemset (dstbuf, dst_stride * dst_height, 0);
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_fmt = dst_bpp == 4 ? (prng_rand_n (2) == 0 ?
871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    src_img = pixman_image_create_bits (
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        src_fmt, src_width, src_height, srcbuf, src_stride);
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    dst_img = pixman_image_create_bits (
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        dst_fmt, dst_width, dst_height, dstbuf, dst_stride);
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_endian_swap (src_img);
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_endian_swap (dst_img);
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_transform_init_identity (&transform);
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (3) > 0)
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	scale_x = -65536 * 3 + prng_rand_n (65536 * 6);
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (prng_rand_n (2))
1041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    scale_y = -65536 * 3 + prng_rand_n (65536 * 6);
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    scale_y = scale_x;
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_transform_init_scale (&transform, scale_x, scale_y);
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (3) > 0)
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	translate_x = -65536 * 3 + prng_rand_n (6 * 65536);
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	if (prng_rand_n (2))
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    translate_y = -65536 * 3 + prng_rand_n (6 * 65536);
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	else
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    translate_y = translate_x;
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (4) > 0)
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int c, s, tx = 0, ty = 0;
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	switch (prng_rand_n (4))
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 0:
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* 90 degrees */
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    c = 0;
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    s = pixman_fixed_1;
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    tx = pixman_int_to_fixed (MAX_SRC_HEIGHT);
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 1:
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* 180 degrees */
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    c = -pixman_fixed_1;
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    s = 0;
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    tx = pixman_int_to_fixed (MAX_SRC_WIDTH);
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ty = pixman_int_to_fixed (MAX_SRC_HEIGHT);
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	case 2:
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* 270 degrees */
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    c = 0;
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    s = -pixman_fixed_1;
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    ty = pixman_int_to_fixed (MAX_SRC_WIDTH);
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	default:
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    /* arbitrary rotation */
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    c = prng_rand_n (2 * 65536) - 65536;
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    s = prng_rand_n (2 * 65536) - 65536;
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    break;
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_transform_rotate (&transform, NULL, c, s);
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_transform_translate (&transform, NULL, tx, ty);
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (8) == 0)
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* Flip random bits */
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int maxflipcount = 8;
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	while (maxflipcount--)
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    int i = prng_rand_n (2);
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    int j = prng_rand_n (3);
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    int bitnum = prng_rand_n (32);
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    transform.matrix[i][j] ^= 1 << bitnum;
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (prng_rand_n (2))
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		break;
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_set_transform (src_img, &transform);
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    switch (prng_rand_n (4))
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 0:
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	repeat = PIXMAN_REPEAT_NONE;
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 1:
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	repeat = PIXMAN_REPEAT_NORMAL;
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 2:
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	repeat = PIXMAN_REPEAT_PAD;
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    case 3:
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	repeat = PIXMAN_REPEAT_REFLECT;
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	break;
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    default:
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck        break;
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_set_repeat (src_img, repeat);
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (2))
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    else
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (verbose)
1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define M(r,c)								\
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	transform.matrix[r][c]
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf ("src_fmt=%s, dst_fmt=%s\n", format_name (src_fmt), format_name (dst_fmt));
2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf ("op=%s, repeat=%d, transform=\n",
2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        operator_name (op), repeat);
2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf (" { { { 0x%08x, 0x%08x, 0x%08x },\n"
2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		"     { 0x%08x, 0x%08x, 0x%08x },\n"
2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		"     { 0x%08x, 0x%08x, 0x%08x },\n"
2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		" } };\n",
2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		M(0,0), M(0,1), M(0,2),
2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		M(1,0), M(1,1), M(1,2),
2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		M(2,0), M(2,1), M(2,2));
2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        src_width, src_height, dst_width, dst_height);
2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	        src_x, src_y, dst_x, dst_y);
2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	printf ("w=%d, h=%d\n", w, h);
2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (8) == 0)
2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_box16_t clip_boxes[2];
2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int            n = prng_rand_n (2) + 1;
2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (i = 0; i < n; i++)
2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].x1 = prng_rand_n (src_width);
2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].y1 = prng_rand_n (src_height);
2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].x2 =
2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].y2 =
2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (verbose)
2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		printf ("source clip box: [%d,%d-%d,%d]\n",
2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		        clip_boxes[i].x1, clip_boxes[i].y1,
2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		        clip_boxes[i].x2, clip_boxes[i].y2);
2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_region_init_rects (&clip, clip_boxes, n);
2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_set_clip_region (src_img, &clip);
2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_set_source_clipping (src_img, 1);
2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_region_fini (&clip);
2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (prng_rand_n (8) == 0)
2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_box16_t clip_boxes[2];
2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int            n = prng_rand_n (2) + 1;
2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (i = 0; i < n; i++)
2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].x1 = prng_rand_n (dst_width);
2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].y1 = prng_rand_n (dst_height);
2561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].x2 =
2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    clip_boxes[i].y2 =
2591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    if (verbose)
2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    {
2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		printf ("destination clip box: [%d,%d-%d,%d]\n",
2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		        clip_boxes[i].x1, clip_boxes[i].y1,
2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		        clip_boxes[i].x2, clip_boxes[i].y2);
2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    }
2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_region_init_rects (&clip, clip_boxes, n);
2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_image_set_clip_region (dst_img, &clip);
2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	pixman_region_fini (&clip);
2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_composite (op, src_img, NULL, dst_img,
2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck                            src_x, src_y, 0, 0, dst_x, dst_y, w, h);
2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (dst_fmt == PIXMAN_x8r8g8b8)
2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	/* ignore unused part */
2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (i = 0; i < dst_stride * dst_height / 4; i++)
2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    dstbuf[i] &= 0xFFFFFF;
2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    image_endian_swap (dst_img);
2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (verbose)
2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    {
2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	int j;
2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (i = 0; i < dst_height; i++)
2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	{
2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    for (j = 0; j < dst_stride; j++)
2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck		printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	    printf ("\n");
2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	}
2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (src_img);
2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_image_unref (dst_img);
3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    crc32 = compute_crc32 (0, dstbuf, dst_stride * dst_height);
3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (srcbuf);
3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    free (dstbuf);
3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return crc32;
3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if BILINEAR_INTERPOLATION_BITS == 8
3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define CHECKSUM 0x2CDF1F07
3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif BILINEAR_INTERPOLATION_BITS == 7
3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define CHECKSUM 0xBC00B1DF
3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#elif BILINEAR_INTERPOLATION_BITS == 4
3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define CHECKSUM 0xA227306B
3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#else
3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#define CHECKSUM 0x00000000
3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reckint
3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reckmain (int argc, const char *argv[])
3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    pixman_disable_out_of_bounds_workaround ();
3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return fuzzer_test_main ("affine", 8000000, CHECKSUM,
3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck			     test_composite, argc, argv);
3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
327