4 static const pixman_format_code_t glyph_formats[] =
15 static const pixman_format_code_t formats[] =
34 /* These use floating point */
61 static const pixman_op_t operators[] =
70 PIXMAN_OP_OVER_REVERSE,
74 PIXMAN_OP_OUT_REVERSE,
76 PIXMAN_OP_ATOP_REVERSE,
83 ALLOW_CLIPPED = (1 << 0),
84 ALLOW_ALPHA_MAP = (1 << 1),
85 ALLOW_SOURCE_CLIPPING = (1 << 2),
86 ALLOW_REPEAT = (1 << 3),
87 ALLOW_SOLID = (1 << 4),
88 ALLOW_FENCED_MEMORY = (1 << 5),
92 destroy_fenced (pixman_image_t *image, void *data)
98 destroy_malloced (pixman_image_t *image, void *data)
103 static pixman_format_code_t
104 random_format (const pixman_format_code_t *formats)
108 while (formats[i] != PIXMAN_null)
110 return formats[prng_rand_n (i)];
113 static pixman_image_t *
114 create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
117 pixman_image_t *image;
118 pixman_format_code_t format;
123 pixman_image_destroy_func_t destroy;
125 if ((flags & ALLOW_SOLID) && prng_rand_n (4) == 0)
127 pixman_color_t color;
129 color.alpha = prng_rand();
130 color.red = prng_rand();
131 color.green = prng_rand();
132 color.blue = prng_rand();
134 return pixman_image_create_solid_fill (&color);
137 width = prng_rand_n (max_size) + 1;
138 height = prng_rand_n (max_size) + 1;
139 format = random_format (formats);
141 bpp = PIXMAN_FORMAT_BPP (format);
142 stride = (width * bpp + 7) / 8 + prng_rand_n (17);
143 stride = (stride + 3) & ~3;
145 if (prng_rand_n (64) == 0)
147 if (!(data = (uint32_t *)make_random_bytes (stride * height)))
149 fprintf (stderr, "Out of memory\n");
152 destroy = destroy_fenced;
156 data = malloc (stride * height);
157 prng_randmemset (data, height * stride, 0);
158 destroy = destroy_malloced;
161 image = pixman_image_create_bits (format, width, height, data, stride);
162 pixman_image_set_destroy_function (image, destroy, data);
164 if ((flags & ALLOW_CLIPPED) && prng_rand_n (8) == 0)
166 pixman_box16_t clip_boxes[8];
167 pixman_region16_t clip;
168 int n = prng_rand_n (8) + 1;
170 for (i = 0; i < n; i++)
172 clip_boxes[i].x1 = prng_rand_n (width);
173 clip_boxes[i].y1 = prng_rand_n (height);
175 clip_boxes[i].x1 + prng_rand_n (width - clip_boxes[i].x1);
177 clip_boxes[i].y1 + prng_rand_n (height - clip_boxes[i].y1);
180 pixman_region_init_rects (&clip, clip_boxes, n);
181 pixman_image_set_clip_region (image, &clip);
182 pixman_region_fini (&clip);
185 if ((flags & ALLOW_SOURCE_CLIPPING) && prng_rand_n (4) == 0)
187 pixman_image_set_source_clipping (image, TRUE);
188 pixman_image_set_has_client_clip (image, TRUE);
191 if ((flags & ALLOW_ALPHA_MAP) && prng_rand_n (16) == 0)
193 pixman_image_t *alpha_map;
194 int alpha_x, alpha_y;
196 alpha_x = prng_rand_n (width);
197 alpha_y = prng_rand_n (height);
199 create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID)));
200 pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
201 pixman_image_unref (alpha_map);
204 if ((flags & ALLOW_REPEAT) && prng_rand_n (2) == 0)
205 pixman_image_set_repeat (image, prng_rand_n (4));
207 image_endian_swap (image);
212 #define KEY1(p) ((void *)(((uintptr_t)p) ^ (0xa7e23dfaUL)))
213 #define KEY2(p) ((void *)(((uintptr_t)p) ^ (0xabcd9876UL)))
215 #define MAX_GLYPHS 32
218 test_glyphs (int testnum, int verbose)
220 pixman_image_t *glyph_images[MAX_GLYPHS];
221 pixman_glyph_t glyphs[4 * MAX_GLYPHS];
223 pixman_image_t *source, *dest;
225 pixman_glyph_cache_t *cache;
227 prng_srand (testnum);
229 cache = pixman_glyph_cache_create ();
231 source = create_image (300, formats,
232 ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
233 ALLOW_SOURCE_CLIPPING |
234 ALLOW_REPEAT | ALLOW_SOLID);
236 dest = create_image (128, formats,
237 ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
238 ALLOW_SOURCE_CLIPPING);
240 pixman_glyph_cache_freeze (cache);
242 n_glyphs = prng_rand_n (MAX_GLYPHS);
243 for (i = 0; i < n_glyphs; ++i)
244 glyph_images[i] = create_image (32, glyph_formats, 0);
246 for (i = 0; i < 4 * n_glyphs; ++i)
248 int g = prng_rand_n (n_glyphs);
249 pixman_image_t *glyph_img = glyph_images[g];
250 void *key1 = KEY1 (glyph_img);
251 void *key2 = KEY2 (glyph_img);
254 if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2)))
257 pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img);
260 glyphs[i].glyph = glyph;
261 glyphs[i].x = prng_rand_n (128);
262 glyphs[i].y = prng_rand_n (128);
265 if (prng_rand_n (2) == 0)
267 int src_x = prng_rand_n (300) - 150;
268 int src_y = prng_rand_n (300) - 150;
269 int mask_x = prng_rand_n (64) - 32;
270 int mask_y = prng_rand_n (64) - 32;
271 int dest_x = prng_rand_n (64) - 32;
272 int dest_y = prng_rand_n (64) - 32;
273 int width = prng_rand_n (64);
274 int height = prng_rand_n (64);
275 pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
276 pixman_format_code_t format = random_format (glyph_formats);
278 pixman_composite_glyphs (
280 source, dest, format,
285 cache, 4 * n_glyphs, glyphs);
289 pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
290 int src_x = prng_rand_n (300) - 150;
291 int src_y = prng_rand_n (300) - 150;
292 int dest_x = prng_rand_n (64) - 32;
293 int dest_y = prng_rand_n (64) - 32;
295 pixman_composite_glyphs_no_mask (
299 cache, 4 * n_glyphs, glyphs);
302 pixman_glyph_cache_thaw (cache);
304 for (i = 0; i < n_glyphs; ++i)
306 pixman_image_t *img = glyph_images[i];
312 pixman_glyph_cache_remove (cache, key1, key2);
313 pixman_image_unref (glyph_images[i]);
316 crc32 = compute_crc32_for_image (0, dest);
318 pixman_image_unref (source);
319 pixman_image_unref (dest);
321 pixman_glyph_cache_destroy (cache);
327 main (int argc, const char *argv[])
329 return fuzzer_test_main ("glyph", 30000,
331 test_glyphs, argc, argv);