• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
destroy_bits(pixman_image_t * image,void * data)32 destroy_bits (pixman_image_t *image, void *data)
33 {
34     fence_free (data);
35 }
36 
37 static pixman_fixed_t
random_fixed(int n)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
test_composite(int testnum,int verbose)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
main(int argc,const char * argv[])252 main (int argc, const char *argv[])
253 {
254     return fuzzer_test_main("composite traps", 40000, 0x749BCC57,
255 			    test_composite, argc, argv);
256 }
257