Home | History | Annotate | Download | only in test
      1 /* Based loosely on scaling-test */
      2 
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include "utils.h"
      6 
      7 #define MAX_SRC_WIDTH  48
      8 #define MAX_SRC_HEIGHT 48
      9 #define MAX_DST_WIDTH  48
     10 #define MAX_DST_HEIGHT 48
     11 #define MAX_STRIDE     4
     12 
     13 static pixman_format_code_t formats[] =
     14 {
     15     PIXMAN_a8r8g8b8, PIXMAN_a8, PIXMAN_r5g6b5, PIXMAN_a1, PIXMAN_a4
     16 };
     17 
     18 static pixman_format_code_t mask_formats[] =
     19 {
     20     PIXMAN_a1, PIXMAN_a4, PIXMAN_a8,
     21 };
     22 
     23 static pixman_op_t operators[] =
     24 {
     25     PIXMAN_OP_OVER, PIXMAN_OP_ADD, PIXMAN_OP_SRC, PIXMAN_OP_IN
     26 };
     27 
     28 #define RANDOM_ELT(array)						\
     29     ((array)[prng_rand_n(ARRAY_LENGTH((array)))])
     30 
     31 static void
     32 destroy_bits (pixman_image_t *image, void *data)
     33 {
     34     fence_free (data);
     35 }
     36 
     37 static pixman_fixed_t
     38 random_fixed (int n)
     39 {
     40     return prng_rand_n (n << 16);
     41 }
     42 
     43 /*
     44  * Composite operation with pseudorandom images
     45  */
     46 uint32_t
     47 test_composite (int      testnum,
     48 		int      verbose)
     49 {
     50     int                i;
     51     pixman_image_t *   src_img;
     52     pixman_image_t *   dst_img;
     53     pixman_region16_t  clip;
     54     int                dst_width, dst_height;
     55     int                dst_stride;
     56     int                dst_x, dst_y;
     57     int                dst_bpp;
     58     pixman_op_t        op;
     59     uint32_t *         dst_bits;
     60     uint32_t           crc32;
     61     pixman_format_code_t mask_format, dst_format;
     62     pixman_trapezoid_t *traps;
     63     int src_x, src_y;
     64     int n_traps;
     65 
     66     static pixman_color_t colors[] =
     67     {
     68 	{ 0xffff, 0xffff, 0xffff, 0xffff },
     69 	{ 0x0000, 0x0000, 0x0000, 0x0000 },
     70 	{ 0xabcd, 0xabcd, 0x0000, 0xabcd },
     71 	{ 0x0000, 0x0000, 0x0000, 0xffff },
     72 	{ 0x0101, 0x0101, 0x0101, 0x0101 },
     73 	{ 0x7777, 0x6666, 0x5555, 0x9999 },
     74     };
     75 
     76     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
     77 
     78     prng_srand (testnum);
     79 
     80     op = RANDOM_ELT (operators);
     81     mask_format = RANDOM_ELT (mask_formats);
     82 
     83     /* Create source image */
     84 
     85     if (prng_rand_n (4) == 0)
     86     {
     87 	src_img = pixman_image_create_solid_fill (
     88 	    &(colors[prng_rand_n (ARRAY_LENGTH (colors))]));
     89 
     90 	src_x = 10;
     91 	src_y = 234;
     92     }
     93     else
     94     {
     95 	pixman_format_code_t src_format = RANDOM_ELT(formats);
     96 	int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
     97 	int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
     98 	int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
     99 	int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
    100 	uint32_t *bits;
    101 
    102 	src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
    103 	src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
    104 
    105 	src_stride = (src_stride + 3) & ~3;
    106 
    107 	bits = (uint32_t *)make_random_bytes (src_stride * src_height);
    108 
    109 	src_img = pixman_image_create_bits (
    110 	    src_format, src_width, src_height, bits, src_stride);
    111 
    112 	pixman_image_set_destroy_function (src_img, destroy_bits, bits);
    113 
    114 	if (prng_rand_n (8) == 0)
    115 	{
    116 	    pixman_box16_t clip_boxes[2];
    117 	    int            n = prng_rand_n (2) + 1;
    118 
    119 	    for (i = 0; i < n; i++)
    120 	    {
    121 		clip_boxes[i].x1 = prng_rand_n (src_width);
    122 		clip_boxes[i].y1 = prng_rand_n (src_height);
    123 		clip_boxes[i].x2 =
    124 		    clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
    125 		clip_boxes[i].y2 =
    126 		    clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
    127 
    128 		if (verbose)
    129 		{
    130 		    printf ("source clip box: [%d,%d-%d,%d]\n",
    131 			    clip_boxes[i].x1, clip_boxes[i].y1,
    132 			    clip_boxes[i].x2, clip_boxes[i].y2);
    133 		}
    134 	    }
    135 
    136 	    pixman_region_init_rects (&clip, clip_boxes, n);
    137 	    pixman_image_set_clip_region (src_img, &clip);
    138 	    pixman_image_set_source_clipping (src_img, 1);
    139 	    pixman_region_fini (&clip);
    140 	}
    141 
    142 	image_endian_swap (src_img);
    143     }
    144 
    145     /* Create destination image */
    146     {
    147 	dst_format = RANDOM_ELT(formats);
    148 	dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
    149 	dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
    150 	dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
    151 	dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
    152 	dst_stride = (dst_stride + 3) & ~3;
    153 
    154 	dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
    155 
    156 	dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
    157 	dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
    158 
    159 	dst_img = pixman_image_create_bits (
    160 	    dst_format, dst_width, dst_height, dst_bits, dst_stride);
    161 
    162 	image_endian_swap (dst_img);
    163     }
    164 
    165     /* Create traps */
    166     {
    167 	int i;
    168 
    169 	n_traps = prng_rand_n (25);
    170 	traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
    171 
    172 	for (i = 0; i < n_traps; ++i)
    173 	{
    174 	    pixman_trapezoid_t *t = &(traps[i]);
    175 
    176 	    t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2;
    177 	    t->bottom = t->top + random_fixed (MAX_DST_HEIGHT);
    178 	    t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
    179 	    t->left.p1.y = t->top - random_fixed (50);
    180 	    t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
    181 	    t->left.p2.y = t->bottom + random_fixed (50);
    182 	    t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH);
    183 	    t->right.p1.y = t->top - random_fixed (50);
    184 	    t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH);
    185 	    t->right.p2.y = t->bottom - random_fixed (50);
    186 	}
    187     }
    188 
    189     if (prng_rand_n (8) == 0)
    190     {
    191 	pixman_box16_t clip_boxes[2];
    192 	int            n = prng_rand_n (2) + 1;
    193 	for (i = 0; i < n; i++)
    194 	{
    195 	    clip_boxes[i].x1 = prng_rand_n (dst_width);
    196 	    clip_boxes[i].y1 = prng_rand_n (dst_height);
    197 	    clip_boxes[i].x2 =
    198 		clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
    199 	    clip_boxes[i].y2 =
    200 		clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
    201 
    202 	    if (verbose)
    203 	    {
    204 		printf ("destination clip box: [%d,%d-%d,%d]\n",
    205 		        clip_boxes[i].x1, clip_boxes[i].y1,
    206 		        clip_boxes[i].x2, clip_boxes[i].y2);
    207 	    }
    208 	}
    209 	pixman_region_init_rects (&clip, clip_boxes, n);
    210 	pixman_image_set_clip_region (dst_img, &clip);
    211 	pixman_region_fini (&clip);
    212     }
    213 
    214     pixman_composite_trapezoids (op, src_img, dst_img, mask_format,
    215 				 src_x, src_y, dst_x, dst_y, n_traps, traps);
    216 
    217     if (dst_format == PIXMAN_x8r8g8b8)
    218     {
    219 	/* ignore unused part */
    220 	for (i = 0; i < dst_stride * dst_height / 4; i++)
    221 	    dst_bits[i] &= 0xFFFFFF;
    222     }
    223 
    224     image_endian_swap (dst_img);
    225 
    226     if (verbose)
    227     {
    228 	int j;
    229 
    230 	for (i = 0; i < dst_height; i++)
    231 	{
    232 	    for (j = 0; j < dst_stride; j++)
    233 		printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j));
    234 
    235 	    printf ("\n");
    236 	}
    237     }
    238 
    239     crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height);
    240 
    241     fence_free (dst_bits);
    242 
    243     pixman_image_unref (src_img);
    244     pixman_image_unref (dst_img);
    245     fence_free (traps);
    246 
    247     FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    248     return crc32;
    249 }
    250 
    251 int
    252 main (int argc, const char *argv[])
    253 {
    254     return fuzzer_test_main("composite traps", 40000, 0x749BCC57,
    255 			    test_composite, argc, argv);
    256 }
    257