7 #define fence_malloc malloc
8 #define fence_free free
9 #define make_random_bytes malloc
12 static const pixman_format_code_t image_formats[] =
63 static pixman_filter_t filters[] =
65 PIXMAN_FILTER_NEAREST,
66 PIXMAN_FILTER_BILINEAR,
70 PIXMAN_FILTER_CONVOLUTION
76 switch (lcg_rand_n (28))
86 return lcg_rand_n (200);
89 return lcg_rand_n (2000) + 1000;
98 return lcg_rand_N (64000) + 63000;
103 destroy (pixman_image_t *image, void *data)
105 if (image->type == BITS && image->bits.free_me != image->bits.bits)
109 if (image->bits.bits != (void *)0x01)
111 bits = image->bits.bits;
113 if (image->bits.rowstride < 0)
114 bits -= (- image->bits.rowstride * (image->bits.height - 1));
124 real_reader (const void *src, int size)
129 return *(uint8_t *)src;
131 return *(uint16_t *)src;
133 return *(uint32_t *)src;
136 return 0; /* silence MSVC */
141 real_writer (void *src, uint32_t value, int size)
146 *(uint8_t *)src = value;
150 *(uint16_t *)src = value;
154 *(uint32_t *)src = value;
164 fake_reader (const void *src, int size)
166 uint32_t r = lcg_rand_u32 ();
168 assert (size == 1 || size == 2 || size == 4);
170 return r >> (32 - (size * 8));
174 fake_writer (void *src, uint32_t value, int size)
176 assert (size == 1 || size == 2 || size == 4);
184 mask = (1 << lcg_rand_n (31)) - 1;
186 return (lcg_rand () & mask) - (mask >> 1);
189 static pixman_image_t *
190 create_random_bits_image (void)
192 pixman_format_code_t format;
193 pixman_indexed_t *indexed;
194 pixman_image_t *image;
195 int width, height, stride;
197 pixman_read_memory_func_t read_func = NULL;
198 pixman_write_memory_func_t write_func = NULL;
199 pixman_filter_t filter;
200 pixman_fixed_t *coefficients = NULL;
201 int n_coefficients = 0;
204 format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))];
207 if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
209 indexed = malloc (sizeof (pixman_indexed_t));
211 initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), TRUE);
213 else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY)
215 indexed = malloc (sizeof (pixman_indexed_t));
217 initialize_palette (indexed, PIXMAN_FORMAT_BPP (format), FALSE);
226 height = get_size ();
228 if ((uint64_t)width * height > 200000)
230 if (lcg_rand_n(2) == 0)
231 height = 200000 / width;
233 width = 200000 / height;
242 switch (lcg_rand_n (7))
246 stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
247 stride = (stride + 3) & (~3);
248 bits = (uint32_t *)make_random_bytes (height * stride);
256 case 2: /* Zero-filled */
257 stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
258 stride = (stride + 3) & (~3);
259 bits = fence_malloc (height * stride);
262 memset (bits, 0, height * stride);
265 case 3: /* Filled with 0xFF */
266 stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
267 stride = (stride + 3) & (~3);
268 bits = fence_malloc (height * stride);
271 memset (bits, 0xff, height * stride);
274 case 4: /* bits is a bad pointer, has read/write functions */
277 read_func = fake_reader;
278 write_func = fake_writer;
281 case 5: /* bits is a real pointer, has read/write functions */
282 stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
283 stride = (stride + 3) & (~3);
284 bits = fence_malloc (height * stride);
287 memset (bits, 0xff, height * stride);
288 read_func = real_reader;
289 write_func = real_writer;
292 case 6: /* bits is a real pointer, stride is negative */
293 stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17));
294 stride = (stride + 3) & (~3);
295 bits = (uint32_t *)make_random_bytes (height * stride);
298 bits += ((height - 1) * stride) / 4;
304 filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))];
305 if (filter == PIXMAN_FILTER_CONVOLUTION)
307 int width = lcg_rand_n (17);
308 int height = lcg_rand_n (19);
310 n_coefficients = width * height + 2;
311 coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t));
317 for (i = 0; i < width * height; ++i)
318 coefficients[i + 2] = lcg_rand_u32();
320 coefficients[0] = width << 16;
321 coefficients[1] = height << 16;
325 filter = PIXMAN_FILTER_BEST;
329 /* Finally create the image */
330 image = pixman_image_create_bits (format, width, height, bits, stride);
334 pixman_image_set_indexed (image, indexed);
335 pixman_image_set_destroy_function (image, destroy, indexed);
336 pixman_image_set_accessors (image, read_func, write_func);
337 pixman_image_set_filter (image, filter, coefficients, n_coefficients);
342 static pixman_repeat_t repeats[] =
345 PIXMAN_REPEAT_NORMAL,
346 PIXMAN_REPEAT_REFLECT,
353 return i < 0? -i : i;
357 set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
359 pixman_repeat_t repeat;
361 /* Set properties that are generic to all images */
364 repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))];
365 pixman_image_set_repeat (image, repeat);
368 if (allow_alpha_map && lcg_rand_n (3) == 0)
370 pixman_image_t *alpha_map;
373 alpha_map = create_random_bits_image ();
377 set_general_properties (alpha_map, FALSE);
379 x = lcg_rand_N (100000) - 65536;
380 y = lcg_rand_N (100000) - 65536;
382 pixman_image_set_alpha_map (image, alpha_map, x, y);
384 pixman_image_unref (alpha_map);
388 /* Component alpha */
389 pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0);
392 if (lcg_rand_n (8) != 0)
394 pixman_region32_t region;
397 pixman_region32_init (®ion);
399 switch (lcg_rand_n (10))
405 case 1: case 2: case 3:
417 n_rects = lcg_rand_n (100);
421 for (i = 0; i < n_rects; ++i)
423 uint32_t width, height;
428 width = absolute (log_rand ()) + 1;
429 height = absolute (log_rand ()) + 1;
431 pixman_region32_union_rect (
432 ®ion, ®ion, x, y, width, height);
435 pixman_image_set_clip_region32 (image, ®ion);
437 pixman_region32_fini (®ion);
440 /* Whether source clipping is enabled */
441 pixman_image_set_source_clipping (image, !!lcg_rand_n (2));
444 pixman_image_set_has_client_clip (image, !!lcg_rand_n (2));
447 if (lcg_rand_n (5) < 2)
449 pixman_transform_t xform;
451 uint32_t tx, ty, sx, sy;
454 memset (&xform, 0, sizeof xform);
455 xform.matrix[0][0] = pixman_fixed_1;
456 xform.matrix[1][1] = pixman_fixed_1;
457 xform.matrix[2][2] = pixman_fixed_1;
459 for (k = 0; k < 3; ++k)
461 switch (lcg_rand_n (4))
465 c = lcg_rand_N (2 * 65536) - 65536;
466 s = lcg_rand_N (2 * 65536) - 65536;
467 pixman_transform_rotate (&xform, NULL, c, s);
474 pixman_transform_translate (&xform, NULL, tx, ty);
481 pixman_transform_scale (&xform, NULL, sx, sy);
485 if (lcg_rand_n (16) == 0)
488 for (i = 0; i < 3; ++i)
489 for (j = 0; j < 3; ++j)
490 xform.matrix[i][j] = lcg_rand_u32();
493 else if (lcg_rand_n (16) == 0)
496 memset (&xform, 0, sizeof xform);
502 pixman_image_set_transform (image, &xform);
506 static pixman_color_t
509 pixman_color_t color =
521 static pixman_image_t *
522 create_random_solid_image (void)
524 pixman_color_t color = random_color();
525 pixman_image_t *image = pixman_image_create_solid_fill (&color);
530 static pixman_gradient_stop_t *
531 create_random_stops (int *n_stops)
536 pixman_gradient_stop_t *stops;
538 *n_stops = lcg_rand_n (50) + 1;
540 step = pixman_fixed_1 / *n_stops;
542 stops = malloc (*n_stops * sizeof (pixman_gradient_stop_t));
545 for (i = 0; i < (*n_stops) - 1; ++i)
548 stops[i].color = random_color();
553 stops[*n_stops - 1].x = pixman_fixed_1;
554 stops[*n_stops - 1].color = random_color();
559 static pixman_point_fixed_t
560 create_random_point (void)
562 pixman_point_fixed_t p;
570 static pixman_image_t *
571 create_random_linear_image (void)
574 pixman_gradient_stop_t *stops;
575 pixman_point_fixed_t p1, p2;
576 pixman_image_t *result;
578 stops = create_random_stops (&n_stops);
582 p1 = create_random_point ();
583 p2 = create_random_point ();
585 result = pixman_image_create_linear_gradient (&p1, &p2, stops, n_stops);
592 static pixman_image_t *
593 create_random_radial_image (void)
596 pixman_gradient_stop_t *stops;
597 pixman_point_fixed_t inner_c, outer_c;
598 pixman_fixed_t inner_r, outer_r;
599 pixman_image_t *result;
601 inner_c = create_random_point();
602 outer_c = create_random_point();
603 inner_r = lcg_rand();
604 outer_r = lcg_rand();
606 stops = create_random_stops (&n_stops);
611 result = pixman_image_create_radial_gradient (
612 &inner_c, &outer_c, inner_r, outer_r, stops, n_stops);
619 static pixman_image_t *
620 create_random_conical_image (void)
622 pixman_gradient_stop_t *stops;
624 pixman_point_fixed_t c;
625 pixman_fixed_t angle;
626 pixman_image_t *result;
628 c = create_random_point();
631 stops = create_random_stops (&n_stops);
636 result = pixman_image_create_conical_gradient (&c, angle, stops, n_stops);
643 static pixman_image_t *
644 create_random_image (void)
646 pixman_image_t *result;
648 switch (lcg_rand_n (5))
652 result = create_random_bits_image ();
656 result = create_random_solid_image ();
660 result = create_random_linear_image ();
664 result = create_random_radial_image ();
668 result = create_random_conical_image ();
673 set_general_properties (result, TRUE);
678 static const pixman_op_t op_list[] =
687 PIXMAN_OP_OVER_REVERSE,
689 PIXMAN_OP_IN_REVERSE,
691 PIXMAN_OP_OUT_REVERSE,
693 PIXMAN_OP_ATOP_REVERSE,
697 PIXMAN_OP_DISJOINT_CLEAR,
698 PIXMAN_OP_DISJOINT_SRC,
699 PIXMAN_OP_DISJOINT_DST,
700 PIXMAN_OP_DISJOINT_OVER,
701 PIXMAN_OP_DISJOINT_OVER_REVERSE,
702 PIXMAN_OP_DISJOINT_IN,
703 PIXMAN_OP_DISJOINT_IN_REVERSE,
704 PIXMAN_OP_DISJOINT_OUT,
705 PIXMAN_OP_DISJOINT_OUT_REVERSE,
706 PIXMAN_OP_DISJOINT_ATOP,
707 PIXMAN_OP_DISJOINT_ATOP_REVERSE,
708 PIXMAN_OP_DISJOINT_XOR,
709 PIXMAN_OP_CONJOINT_CLEAR,
710 PIXMAN_OP_CONJOINT_SRC,
711 PIXMAN_OP_CONJOINT_DST,
712 PIXMAN_OP_CONJOINT_OVER,
713 PIXMAN_OP_CONJOINT_OVER_REVERSE,
714 PIXMAN_OP_CONJOINT_IN,
715 PIXMAN_OP_CONJOINT_IN_REVERSE,
716 PIXMAN_OP_CONJOINT_OUT,
717 PIXMAN_OP_CONJOINT_OUT_REVERSE,
718 PIXMAN_OP_CONJOINT_ATOP,
719 PIXMAN_OP_CONJOINT_ATOP_REVERSE,
720 PIXMAN_OP_CONJOINT_XOR,
726 PIXMAN_OP_COLOR_DODGE,
727 PIXMAN_OP_COLOR_BURN,
728 PIXMAN_OP_HARD_LIGHT,
729 PIXMAN_OP_DIFFERENCE,
731 PIXMAN_OP_SOFT_LIGHT,
733 PIXMAN_OP_HSL_SATURATION,
735 PIXMAN_OP_HSL_LUMINOSITY,
739 run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
741 pixman_image_t *source, *mask, *dest;
746 if (mod == 0 || (seed % mod) == 0)
747 printf ("Seed 0x%08x\n", seed);
752 source = create_random_image ();
753 mask = create_random_image ();
754 dest = create_random_bits_image ();
756 if (source && mask && dest)
758 set_general_properties (dest, TRUE);
760 op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))];
762 pixman_image_composite32 (op,
764 log_rand(), log_rand(),
765 log_rand(), log_rand(),
766 log_rand(), log_rand(),
767 absolute (log_rand()),
768 absolute (log_rand()));
771 pixman_image_unref (source);
773 pixman_image_unref (mask);
775 pixman_image_unref (dest);
779 get_int (char *s, uint32_t *i)
784 p = strtol (s, &end, 0);
786 if (end != s && *end == 0)
796 main (int argc, char **argv)
800 uint32_t n_tests = 0xffffffff;
802 pixman_bool_t use_threads = TRUE;
805 pixman_disable_out_of_bounds_workaround ();
807 enable_fp_exceptions();
809 if (getenv ("VERBOSE") != NULL)
812 for (i = 1; i < argc; ++i)
814 if (strcmp (argv[i], "-v") == 0)
820 get_int (argv[i + 1], &mod);
824 else if (strcmp (argv[i], "-s") == 0 && i + 1 < argc)
826 get_int (argv[i + 1], &seed);
830 else if (strcmp (argv[i], "-n") == 0 && i + 1 < argc)
832 get_int (argv[i + 1], &n_tests);
837 if (strcmp (argv[i], "-h") != 0)
838 printf ("Unknown option '%s'\n\n", argv[i]);
840 printf ("Options:\n\n"
841 "-n <number> Number of tests to run\n"
842 "-s <seed> Seed of first test (ignored if PIXMAN_RANDOMIZE_TESTS is set)\n"
843 "-v Print out seeds\n"
844 "-v <n> Print out every n'th seed\n\n");
850 if (n_tests == 0xffffffff)
853 if (getenv ("PIXMAN_RANDOMIZE_TESTS"))
855 seed = get_random_seed();
856 printf ("First seed: 0x%08x\n", seed);
862 # pragma omp parallel for default(none) shared(verbose, n_tests, mod, seed)
864 for (i = seed; i < seed + n_tests; ++i)
865 run_test (i, verbose, mod);
869 for (i = seed; i < seed + n_tests; ++i)
870 run_test (i, verbose, mod);