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