glyph-test.c revision 9ad247e8
19ad247e8Sjmcneill#include <stdlib.h> 29ad247e8Sjmcneill#include "utils.h" 39ad247e8Sjmcneill 49ad247e8Sjmcneillstatic const pixman_format_code_t glyph_formats[] = 59ad247e8Sjmcneill{ 69ad247e8Sjmcneill PIXMAN_a8r8g8b8, 79ad247e8Sjmcneill PIXMAN_a8, 89ad247e8Sjmcneill PIXMAN_a4, 99ad247e8Sjmcneill PIXMAN_a1, 109ad247e8Sjmcneill PIXMAN_x8r8g8b8, 119ad247e8Sjmcneill PIXMAN_r3g3b2, 129ad247e8Sjmcneill PIXMAN_null, 139ad247e8Sjmcneill}; 149ad247e8Sjmcneill 159ad247e8Sjmcneillstatic const pixman_format_code_t formats[] = 169ad247e8Sjmcneill{ 179ad247e8Sjmcneill PIXMAN_a8r8g8b8, 189ad247e8Sjmcneill PIXMAN_a8b8g8r8, 199ad247e8Sjmcneill PIXMAN_x8r8g8b8, 209ad247e8Sjmcneill PIXMAN_x8b8g8r8, 219ad247e8Sjmcneill PIXMAN_r5g6b5, 229ad247e8Sjmcneill PIXMAN_b5g6r5, 239ad247e8Sjmcneill PIXMAN_a8, 249ad247e8Sjmcneill PIXMAN_a1, 259ad247e8Sjmcneill PIXMAN_r3g3b2, 269ad247e8Sjmcneill PIXMAN_b8g8r8a8, 279ad247e8Sjmcneill PIXMAN_b8g8r8x8, 289ad247e8Sjmcneill PIXMAN_r8g8b8a8, 299ad247e8Sjmcneill PIXMAN_r8g8b8x8, 309ad247e8Sjmcneill PIXMAN_x14r6g6b6, 319ad247e8Sjmcneill PIXMAN_r8g8b8, 329ad247e8Sjmcneill PIXMAN_b8g8r8, 339ad247e8Sjmcneill#if 0 349ad247e8Sjmcneill /* These use floating point */ 359ad247e8Sjmcneill PIXMAN_x2r10g10b10, 369ad247e8Sjmcneill PIXMAN_a2r10g10b10, 379ad247e8Sjmcneill PIXMAN_x2b10g10r10, 389ad247e8Sjmcneill PIXMAN_a2b10g10r10, 399ad247e8Sjmcneill#endif 409ad247e8Sjmcneill PIXMAN_a1r5g5b5, 419ad247e8Sjmcneill PIXMAN_x1r5g5b5, 429ad247e8Sjmcneill PIXMAN_a1b5g5r5, 439ad247e8Sjmcneill PIXMAN_x1b5g5r5, 449ad247e8Sjmcneill PIXMAN_a4r4g4b4, 459ad247e8Sjmcneill PIXMAN_x4r4g4b4, 469ad247e8Sjmcneill PIXMAN_a4b4g4r4, 479ad247e8Sjmcneill PIXMAN_x4b4g4r4, 489ad247e8Sjmcneill PIXMAN_r3g3b2, 499ad247e8Sjmcneill PIXMAN_b2g3r3, 509ad247e8Sjmcneill PIXMAN_a2r2g2b2, 519ad247e8Sjmcneill PIXMAN_a2b2g2r2, 529ad247e8Sjmcneill PIXMAN_x4a4, 539ad247e8Sjmcneill PIXMAN_a4, 549ad247e8Sjmcneill PIXMAN_r1g2b1, 559ad247e8Sjmcneill PIXMAN_b1g2r1, 569ad247e8Sjmcneill PIXMAN_a1r1g1b1, 579ad247e8Sjmcneill PIXMAN_a1b1g1r1, 589ad247e8Sjmcneill PIXMAN_null, 599ad247e8Sjmcneill}; 609ad247e8Sjmcneill 619ad247e8Sjmcneillstatic const pixman_op_t operators[] = 629ad247e8Sjmcneill{ 639ad247e8Sjmcneill PIXMAN_OP_SRC, 649ad247e8Sjmcneill PIXMAN_OP_OVER, 659ad247e8Sjmcneill PIXMAN_OP_ADD, 669ad247e8Sjmcneill PIXMAN_OP_CLEAR, 679ad247e8Sjmcneill PIXMAN_OP_SRC, 689ad247e8Sjmcneill PIXMAN_OP_DST, 699ad247e8Sjmcneill PIXMAN_OP_OVER, 709ad247e8Sjmcneill PIXMAN_OP_OVER_REVERSE, 719ad247e8Sjmcneill PIXMAN_OP_IN, 729ad247e8Sjmcneill PIXMAN_OP_IN_REVERSE, 739ad247e8Sjmcneill PIXMAN_OP_OUT, 749ad247e8Sjmcneill PIXMAN_OP_OUT_REVERSE, 759ad247e8Sjmcneill PIXMAN_OP_ATOP, 769ad247e8Sjmcneill PIXMAN_OP_ATOP_REVERSE, 779ad247e8Sjmcneill PIXMAN_OP_XOR, 789ad247e8Sjmcneill PIXMAN_OP_ADD 799ad247e8Sjmcneill}; 809ad247e8Sjmcneill 819ad247e8Sjmcneillenum 829ad247e8Sjmcneill{ 839ad247e8Sjmcneill ALLOW_CLIPPED = (1 << 0), 849ad247e8Sjmcneill ALLOW_ALPHA_MAP = (1 << 1), 859ad247e8Sjmcneill ALLOW_SOURCE_CLIPPING = (1 << 2), 869ad247e8Sjmcneill ALLOW_REPEAT = (1 << 3), 879ad247e8Sjmcneill ALLOW_SOLID = (1 << 4), 889ad247e8Sjmcneill ALLOW_FENCED_MEMORY = (1 << 5), 899ad247e8Sjmcneill}; 909ad247e8Sjmcneill 919ad247e8Sjmcneillstatic void 929ad247e8Sjmcneilldestroy_fenced (pixman_image_t *image, void *data) 939ad247e8Sjmcneill{ 949ad247e8Sjmcneill fence_free (data); 959ad247e8Sjmcneill} 969ad247e8Sjmcneill 979ad247e8Sjmcneillstatic void 989ad247e8Sjmcneilldestroy_malloced (pixman_image_t *image, void *data) 999ad247e8Sjmcneill{ 1009ad247e8Sjmcneill free (data); 1019ad247e8Sjmcneill} 1029ad247e8Sjmcneill 1039ad247e8Sjmcneillstatic pixman_format_code_t 1049ad247e8Sjmcneillrandom_format (const pixman_format_code_t *formats) 1059ad247e8Sjmcneill{ 1069ad247e8Sjmcneill int i; 1079ad247e8Sjmcneill i = 0; 1089ad247e8Sjmcneill while (formats[i] != PIXMAN_null) 1099ad247e8Sjmcneill ++i; 1109ad247e8Sjmcneill return formats[lcg_rand_n (i)]; 1119ad247e8Sjmcneill} 1129ad247e8Sjmcneill 1139ad247e8Sjmcneillstatic pixman_image_t * 1149ad247e8Sjmcneillcreate_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) 1159ad247e8Sjmcneill{ 1169ad247e8Sjmcneill int width, height; 1179ad247e8Sjmcneill pixman_image_t *image; 1189ad247e8Sjmcneill pixman_format_code_t format; 1199ad247e8Sjmcneill uint32_t *data; 1209ad247e8Sjmcneill int bpp; 1219ad247e8Sjmcneill int stride; 1229ad247e8Sjmcneill int i; 1239ad247e8Sjmcneill pixman_image_destroy_func_t destroy; 1249ad247e8Sjmcneill 1259ad247e8Sjmcneill if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0) 1269ad247e8Sjmcneill { 1279ad247e8Sjmcneill pixman_color_t color; 1289ad247e8Sjmcneill 1299ad247e8Sjmcneill color.alpha = lcg_rand_u32(); 1309ad247e8Sjmcneill color.red = lcg_rand_u32(); 1319ad247e8Sjmcneill color.green = lcg_rand_u32(); 1329ad247e8Sjmcneill color.blue = lcg_rand_u32(); 1339ad247e8Sjmcneill 1349ad247e8Sjmcneill return pixman_image_create_solid_fill (&color); 1359ad247e8Sjmcneill } 1369ad247e8Sjmcneill 1379ad247e8Sjmcneill width = lcg_rand_n (max_size) + 1; 1389ad247e8Sjmcneill height = lcg_rand_n (max_size) + 1; 1399ad247e8Sjmcneill format = random_format (formats); 1409ad247e8Sjmcneill 1419ad247e8Sjmcneill bpp = PIXMAN_FORMAT_BPP (format); 1429ad247e8Sjmcneill stride = (width * bpp + 7) / 8 + lcg_rand_n (17); 1439ad247e8Sjmcneill stride = (stride + 3) & ~3; 1449ad247e8Sjmcneill 1459ad247e8Sjmcneill if (lcg_rand_n (64) == 0) 1469ad247e8Sjmcneill { 1479ad247e8Sjmcneill if (!(data = (uint32_t *)make_random_bytes (stride * height))) 1489ad247e8Sjmcneill { 1499ad247e8Sjmcneill fprintf (stderr, "Out of memory\n"); 1509ad247e8Sjmcneill abort (); 1519ad247e8Sjmcneill } 1529ad247e8Sjmcneill destroy = destroy_fenced; 1539ad247e8Sjmcneill } 1549ad247e8Sjmcneill else 1559ad247e8Sjmcneill { 1569ad247e8Sjmcneill uint8_t *d8; 1579ad247e8Sjmcneill 1589ad247e8Sjmcneill data = malloc (stride * height); 1599ad247e8Sjmcneill 1609ad247e8Sjmcneill d8 = (uint8_t *)data; 1619ad247e8Sjmcneill for (i = 0; i < height * stride; ++i) 1629ad247e8Sjmcneill d8[i] = lcg_rand_n (256); 1639ad247e8Sjmcneill 1649ad247e8Sjmcneill destroy = destroy_malloced; 1659ad247e8Sjmcneill } 1669ad247e8Sjmcneill 1679ad247e8Sjmcneill image = pixman_image_create_bits (format, width, height, data, stride); 1689ad247e8Sjmcneill pixman_image_set_destroy_function (image, destroy, data); 1699ad247e8Sjmcneill 1709ad247e8Sjmcneill if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0) 1719ad247e8Sjmcneill { 1729ad247e8Sjmcneill pixman_box16_t clip_boxes[8]; 1739ad247e8Sjmcneill pixman_region16_t clip; 1749ad247e8Sjmcneill int n = lcg_rand_n (8) + 1; 1759ad247e8Sjmcneill 1769ad247e8Sjmcneill for (i = 0; i < n; i++) 1779ad247e8Sjmcneill { 1789ad247e8Sjmcneill clip_boxes[i].x1 = lcg_rand_n (width); 1799ad247e8Sjmcneill clip_boxes[i].y1 = lcg_rand_n (height); 1809ad247e8Sjmcneill clip_boxes[i].x2 = 1819ad247e8Sjmcneill clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1); 1829ad247e8Sjmcneill clip_boxes[i].y2 = 1839ad247e8Sjmcneill clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1); 1849ad247e8Sjmcneill } 1859ad247e8Sjmcneill 1869ad247e8Sjmcneill pixman_region_init_rects (&clip, clip_boxes, n); 1879ad247e8Sjmcneill pixman_image_set_clip_region (image, &clip); 1889ad247e8Sjmcneill pixman_region_fini (&clip); 1899ad247e8Sjmcneill } 1909ad247e8Sjmcneill 1919ad247e8Sjmcneill if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0) 1929ad247e8Sjmcneill { 1939ad247e8Sjmcneill pixman_image_set_source_clipping (image, TRUE); 1949ad247e8Sjmcneill pixman_image_set_has_client_clip (image, TRUE); 1959ad247e8Sjmcneill } 1969ad247e8Sjmcneill 1979ad247e8Sjmcneill if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0) 1989ad247e8Sjmcneill { 1999ad247e8Sjmcneill pixman_image_t *alpha_map; 2009ad247e8Sjmcneill int alpha_x, alpha_y; 2019ad247e8Sjmcneill 2029ad247e8Sjmcneill alpha_x = lcg_rand_n (width); 2039ad247e8Sjmcneill alpha_y = lcg_rand_n (height); 2049ad247e8Sjmcneill alpha_map = 2059ad247e8Sjmcneill create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID))); 2069ad247e8Sjmcneill pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y); 2079ad247e8Sjmcneill pixman_image_unref (alpha_map); 2089ad247e8Sjmcneill } 2099ad247e8Sjmcneill 2109ad247e8Sjmcneill if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0) 2119ad247e8Sjmcneill pixman_image_set_repeat (image, lcg_rand_n (4)); 2129ad247e8Sjmcneill 2139ad247e8Sjmcneill image_endian_swap (image); 2149ad247e8Sjmcneill 2159ad247e8Sjmcneill return image; 2169ad247e8Sjmcneill} 2179ad247e8Sjmcneill 2189ad247e8Sjmcneill#define KEY1(p) ((void *)(((unsigned long)p) ^ (0xa7e23dfaUL))) 2199ad247e8Sjmcneill#define KEY2(p) ((void *)(((unsigned long)p) ^ (0xabcd9876UL))) 2209ad247e8Sjmcneill 2219ad247e8Sjmcneill#define MAX_GLYPHS 32 2229ad247e8Sjmcneill 2239ad247e8Sjmcneilluint32_t 2249ad247e8Sjmcneilltest_glyphs (int testnum, int verbose) 2259ad247e8Sjmcneill{ 2269ad247e8Sjmcneill pixman_image_t *glyph_images[MAX_GLYPHS]; 2279ad247e8Sjmcneill pixman_glyph_t glyphs[4 * MAX_GLYPHS]; 2289ad247e8Sjmcneill uint32_t crc32 = 0; 2299ad247e8Sjmcneill pixman_image_t *source, *dest; 2309ad247e8Sjmcneill int n_glyphs, i; 2319ad247e8Sjmcneill pixman_glyph_cache_t *cache; 2329ad247e8Sjmcneill 2339ad247e8Sjmcneill lcg_srand (testnum); 2349ad247e8Sjmcneill 2359ad247e8Sjmcneill cache = pixman_glyph_cache_create (); 2369ad247e8Sjmcneill 2379ad247e8Sjmcneill source = create_image (300, formats, 2389ad247e8Sjmcneill ALLOW_CLIPPED | ALLOW_ALPHA_MAP | 2399ad247e8Sjmcneill ALLOW_SOURCE_CLIPPING | 2409ad247e8Sjmcneill ALLOW_REPEAT | ALLOW_SOLID); 2419ad247e8Sjmcneill 2429ad247e8Sjmcneill dest = create_image (128, formats, 2439ad247e8Sjmcneill ALLOW_CLIPPED | ALLOW_ALPHA_MAP | 2449ad247e8Sjmcneill ALLOW_SOURCE_CLIPPING); 2459ad247e8Sjmcneill 2469ad247e8Sjmcneill pixman_glyph_cache_freeze (cache); 2479ad247e8Sjmcneill 2489ad247e8Sjmcneill n_glyphs = lcg_rand_n (MAX_GLYPHS); 2499ad247e8Sjmcneill for (i = 0; i < n_glyphs; ++i) 2509ad247e8Sjmcneill glyph_images[i] = create_image (32, glyph_formats, 0); 2519ad247e8Sjmcneill 2529ad247e8Sjmcneill for (i = 0; i < 4 * n_glyphs; ++i) 2539ad247e8Sjmcneill { 2549ad247e8Sjmcneill int g = lcg_rand_n (n_glyphs); 2559ad247e8Sjmcneill pixman_image_t *glyph_img = glyph_images[g]; 2569ad247e8Sjmcneill void *key1 = KEY1 (glyph_img); 2579ad247e8Sjmcneill void *key2 = KEY2 (glyph_img); 2589ad247e8Sjmcneill const void *glyph; 2599ad247e8Sjmcneill 2609ad247e8Sjmcneill if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2))) 2619ad247e8Sjmcneill { 2629ad247e8Sjmcneill glyph = 2639ad247e8Sjmcneill pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img); 2649ad247e8Sjmcneill } 2659ad247e8Sjmcneill 2669ad247e8Sjmcneill glyphs[i].glyph = glyph; 2679ad247e8Sjmcneill glyphs[i].x = lcg_rand_n (128); 2689ad247e8Sjmcneill glyphs[i].y = lcg_rand_n (128); 2699ad247e8Sjmcneill } 2709ad247e8Sjmcneill 2719ad247e8Sjmcneill if (lcg_rand_n (2) == 0) 2729ad247e8Sjmcneill { 2739ad247e8Sjmcneill int src_x = lcg_rand_n (300) - 150; 2749ad247e8Sjmcneill int src_y = lcg_rand_n (300) - 150; 2759ad247e8Sjmcneill int mask_x = lcg_rand_n (64) - 32; 2769ad247e8Sjmcneill int mask_y = lcg_rand_n (64) - 32; 2779ad247e8Sjmcneill int dest_x = lcg_rand_n (64) - 32; 2789ad247e8Sjmcneill int dest_y = lcg_rand_n (64) - 32; 2799ad247e8Sjmcneill int width = lcg_rand_n (64); 2809ad247e8Sjmcneill int height = lcg_rand_n (64); 2819ad247e8Sjmcneill pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; 2829ad247e8Sjmcneill pixman_format_code_t format = random_format (glyph_formats); 2839ad247e8Sjmcneill 2849ad247e8Sjmcneill pixman_composite_glyphs ( 2859ad247e8Sjmcneill op, 2869ad247e8Sjmcneill source, dest, format, 2879ad247e8Sjmcneill src_x, src_y, 2889ad247e8Sjmcneill mask_x, mask_y, 2899ad247e8Sjmcneill dest_x, dest_y, 2909ad247e8Sjmcneill width, height, 2919ad247e8Sjmcneill cache, 4 * n_glyphs, glyphs); 2929ad247e8Sjmcneill } 2939ad247e8Sjmcneill else 2949ad247e8Sjmcneill { 2959ad247e8Sjmcneill pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))]; 2969ad247e8Sjmcneill int src_x = lcg_rand_n (300) - 150; 2979ad247e8Sjmcneill int src_y = lcg_rand_n (300) - 150; 2989ad247e8Sjmcneill int dest_x = lcg_rand_n (64) - 32; 2999ad247e8Sjmcneill int dest_y = lcg_rand_n (64) - 32; 3009ad247e8Sjmcneill 3019ad247e8Sjmcneill pixman_composite_glyphs_no_mask ( 3029ad247e8Sjmcneill op, source, dest, 3039ad247e8Sjmcneill src_x, src_y, 3049ad247e8Sjmcneill dest_x, dest_y, 3059ad247e8Sjmcneill cache, 4 * n_glyphs, glyphs); 3069ad247e8Sjmcneill } 3079ad247e8Sjmcneill 3089ad247e8Sjmcneill pixman_glyph_cache_thaw (cache); 3099ad247e8Sjmcneill 3109ad247e8Sjmcneill for (i = 0; i < n_glyphs; ++i) 3119ad247e8Sjmcneill { 3129ad247e8Sjmcneill pixman_image_t *img = glyph_images[i]; 3139ad247e8Sjmcneill void *key1, *key2; 3149ad247e8Sjmcneill 3159ad247e8Sjmcneill key1 = KEY1 (img); 3169ad247e8Sjmcneill key2 = KEY2 (img); 3179ad247e8Sjmcneill 3189ad247e8Sjmcneill pixman_glyph_cache_remove (cache, key1, key2); 3199ad247e8Sjmcneill pixman_image_unref (glyph_images[i]); 3209ad247e8Sjmcneill } 3219ad247e8Sjmcneill 3229ad247e8Sjmcneill crc32 = compute_crc32_for_image (0, dest); 3239ad247e8Sjmcneill 3249ad247e8Sjmcneill pixman_image_unref (source); 3259ad247e8Sjmcneill pixman_image_unref (dest); 3269ad247e8Sjmcneill 3279ad247e8Sjmcneill pixman_glyph_cache_destroy (cache); 3289ad247e8Sjmcneill 3299ad247e8Sjmcneill return crc32; 3309ad247e8Sjmcneill} 3319ad247e8Sjmcneill 3329ad247e8Sjmcneillint 3339ad247e8Sjmcneillmain (int argc, const char *argv[]) 3349ad247e8Sjmcneill{ 3359ad247e8Sjmcneill return fuzzer_test_main ("glyph", 30000, 3369ad247e8Sjmcneill 0x79E74996, 3379ad247e8Sjmcneill test_glyphs, argc, argv); 3389ad247e8Sjmcneill} 339