alphamap.c revision 9ad247e8
1952204abSmrg#include <stdio.h> 2952204abSmrg#include <stdlib.h> 3952204abSmrg#include "utils.h" 4952204abSmrg 59ad247e8Sjmcneill#define WIDTH 48 69ad247e8Sjmcneill#define HEIGHT 48 7952204abSmrg 81b18d63aSmrgstatic const pixman_format_code_t formats[] = 91b18d63aSmrg{ 101b18d63aSmrg PIXMAN_a8r8g8b8, 111b18d63aSmrg PIXMAN_a2r10g10b10, 121b18d63aSmrg PIXMAN_a4r4g4b4, 131b18d63aSmrg PIXMAN_a8 141b18d63aSmrg}; 151b18d63aSmrg 161b18d63aSmrgstatic const pixman_format_code_t alpha_formats[] = 171b18d63aSmrg{ 181b18d63aSmrg PIXMAN_null, 191b18d63aSmrg PIXMAN_a8, 201b18d63aSmrg PIXMAN_a2r10g10b10, 211b18d63aSmrg PIXMAN_a4r4g4b4 221b18d63aSmrg}; 231b18d63aSmrg 241b18d63aSmrgstatic const int origins[] = 251b18d63aSmrg{ 261b18d63aSmrg 0, 10, -100 271b18d63aSmrg}; 281b18d63aSmrg 291b18d63aSmrgstatic const char * 301b18d63aSmrgformat_name (pixman_format_code_t format) 311b18d63aSmrg{ 321b18d63aSmrg if (format == PIXMAN_a8) 331b18d63aSmrg return "a8"; 341b18d63aSmrg else if (format == PIXMAN_a2r10g10b10) 351b18d63aSmrg return "a2r10g10b10"; 361b18d63aSmrg else if (format == PIXMAN_a8r8g8b8) 371b18d63aSmrg return "a8r8g8b8"; 381b18d63aSmrg else if (format == PIXMAN_a4r4g4b4) 391b18d63aSmrg return "a4r4g4b4"; 401b18d63aSmrg else if (format == PIXMAN_null) 411b18d63aSmrg return "none"; 421b18d63aSmrg else 431b18d63aSmrg assert (0); 441b18d63aSmrg 451b18d63aSmrg return "<unknown - bug in alphamap.c>"; 461b18d63aSmrg} 471b18d63aSmrg 481b18d63aSmrgstatic void 491b18d63aSmrgon_destroy (pixman_image_t *image, void *data) 501b18d63aSmrg{ 511b18d63aSmrg uint32_t *bits = pixman_image_get_data (image); 521b18d63aSmrg 531b18d63aSmrg fence_free (bits); 541b18d63aSmrg} 551b18d63aSmrg 561b18d63aSmrgstatic pixman_image_t * 571b18d63aSmrgmake_image (pixman_format_code_t format) 581b18d63aSmrg{ 591b18d63aSmrg uint32_t *bits; 601b18d63aSmrg uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; 611b18d63aSmrg pixman_image_t *image; 621b18d63aSmrg 631b18d63aSmrg bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); 641b18d63aSmrg 651b18d63aSmrg image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); 661b18d63aSmrg 671b18d63aSmrg if (image && bits) 681b18d63aSmrg pixman_image_set_destroy_function (image, on_destroy, NULL); 691b18d63aSmrg 701b18d63aSmrg return image; 711b18d63aSmrg} 721b18d63aSmrg 731b18d63aSmrgstatic uint8_t 741b18d63aSmrgget_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) 75952204abSmrg{ 761b18d63aSmrg uint8_t *bits; 771b18d63aSmrg uint8_t r; 781b18d63aSmrg 791b18d63aSmrg if (image->common.alpha_map) 801b18d63aSmrg { 811b18d63aSmrg if (x - orig_x >= 0 && x - orig_x < WIDTH && 821b18d63aSmrg y - orig_y >= 0 && y - orig_y < HEIGHT) 831b18d63aSmrg { 841b18d63aSmrg image = (pixman_image_t *)image->common.alpha_map; 851b18d63aSmrg 861b18d63aSmrg x -= orig_x; 871b18d63aSmrg y -= orig_y; 881b18d63aSmrg } 891b18d63aSmrg else 901b18d63aSmrg { 911b18d63aSmrg return 0; 921b18d63aSmrg } 931b18d63aSmrg } 94952204abSmrg 951b18d63aSmrg bits = (uint8_t *)image->bits.bits; 96952204abSmrg 971b18d63aSmrg if (image->bits.format == PIXMAN_a8) 981b18d63aSmrg { 991b18d63aSmrg r = bits[y * WIDTH + x]; 1001b18d63aSmrg } 1011b18d63aSmrg else if (image->bits.format == PIXMAN_a2r10g10b10) 1021b18d63aSmrg { 1031b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; 1041b18d63aSmrg r |= r << 2; 1051b18d63aSmrg r |= r << 4; 1061b18d63aSmrg } 1071b18d63aSmrg else if (image->bits.format == PIXMAN_a8r8g8b8) 1081b18d63aSmrg { 1091b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; 1101b18d63aSmrg } 1111b18d63aSmrg else if (image->bits.format == PIXMAN_a4r4g4b4) 112952204abSmrg { 1131b18d63aSmrg r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; 1141b18d63aSmrg r |= r << 4; 1151b18d63aSmrg } 1161b18d63aSmrg else 1171b18d63aSmrg { 1181b18d63aSmrg assert (0); 1191b18d63aSmrg } 1201b18d63aSmrg 1211b18d63aSmrg return r; 1221b18d63aSmrg} 123952204abSmrg 1249ad247e8Sjmcneillstatic uint16_t 1259ad247e8Sjmcneillget_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) 1269ad247e8Sjmcneill{ 1279ad247e8Sjmcneill uint8_t *bits; 1289ad247e8Sjmcneill uint16_t r; 1299ad247e8Sjmcneill 1309ad247e8Sjmcneill bits = (uint8_t *)image->bits.bits; 1319ad247e8Sjmcneill 1329ad247e8Sjmcneill if (image->bits.format == PIXMAN_a8) 1339ad247e8Sjmcneill { 1349ad247e8Sjmcneill r = 0x00; 1359ad247e8Sjmcneill } 1369ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a2r10g10b10) 1379ad247e8Sjmcneill { 1389ad247e8Sjmcneill r = ((uint32_t *)bits)[y * WIDTH + x] >> 14; 1399ad247e8Sjmcneill r &= 0xffc0; 1409ad247e8Sjmcneill r |= (r >> 10); 1419ad247e8Sjmcneill } 1429ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a8r8g8b8) 1439ad247e8Sjmcneill { 1449ad247e8Sjmcneill r = ((uint32_t *)bits)[y * WIDTH + x] >> 16; 1459ad247e8Sjmcneill r &= 0xff; 1469ad247e8Sjmcneill r |= r << 8; 1479ad247e8Sjmcneill } 1489ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a4r4g4b4) 1499ad247e8Sjmcneill { 1509ad247e8Sjmcneill r = ((uint16_t *)bits)[y * WIDTH + x] >> 8; 1519ad247e8Sjmcneill r &= 0xf; 1529ad247e8Sjmcneill r |= r << 4; 1539ad247e8Sjmcneill r |= r << 8; 1549ad247e8Sjmcneill } 1559ad247e8Sjmcneill else 1569ad247e8Sjmcneill { 1579ad247e8Sjmcneill assert (0); 1589ad247e8Sjmcneill } 1599ad247e8Sjmcneill 1609ad247e8Sjmcneill return r; 1619ad247e8Sjmcneill} 162952204abSmrg 1631b18d63aSmrgstatic int 1641b18d63aSmrgrun_test (int s, int d, int sa, int da, int soff, int doff) 1651b18d63aSmrg{ 1661b18d63aSmrg pixman_format_code_t sf = formats[s]; 1671b18d63aSmrg pixman_format_code_t df = formats[d]; 1681b18d63aSmrg pixman_format_code_t saf = alpha_formats[sa]; 1691b18d63aSmrg pixman_format_code_t daf = alpha_formats[da]; 1709ad247e8Sjmcneill pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha; 1711b18d63aSmrg pixman_transform_t t1; 1721b18d63aSmrg int j, k; 1739ad247e8Sjmcneill int n_alpha_bits, n_red_bits; 1741b18d63aSmrg 1751b18d63aSmrg soff = origins[soff]; 1761b18d63aSmrg doff = origins[doff]; 1771b18d63aSmrg 1781b18d63aSmrg n_alpha_bits = PIXMAN_FORMAT_A (df); 1791b18d63aSmrg if (daf != PIXMAN_null) 1801b18d63aSmrg n_alpha_bits = PIXMAN_FORMAT_A (daf); 1811b18d63aSmrg 1829ad247e8Sjmcneill n_red_bits = PIXMAN_FORMAT_R (df); 1839ad247e8Sjmcneill 1849ad247e8Sjmcneill /* Source */ 1859ad247e8Sjmcneill src = make_image (sf); 1869ad247e8Sjmcneill if (saf != PIXMAN_null) 1879ad247e8Sjmcneill { 1889ad247e8Sjmcneill alpha = make_image (saf); 1899ad247e8Sjmcneill pixman_image_set_alpha_map (src, alpha, soff, soff); 1909ad247e8Sjmcneill pixman_image_unref (alpha); 1919ad247e8Sjmcneill } 1929ad247e8Sjmcneill 1939ad247e8Sjmcneill /* Destination */ 1949ad247e8Sjmcneill orig_dst = make_image (df); 1959ad247e8Sjmcneill dst = make_image (df); 1969ad247e8Sjmcneill pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst, 1979ad247e8Sjmcneill 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 1989ad247e8Sjmcneill 1999ad247e8Sjmcneill if (daf != PIXMAN_null) 2009ad247e8Sjmcneill { 2019ad247e8Sjmcneill orig_alpha = make_image (daf); 2029ad247e8Sjmcneill alpha = make_image (daf); 2039ad247e8Sjmcneill 2049ad247e8Sjmcneill pixman_image_composite (PIXMAN_OP_SRC, orig_alpha, NULL, alpha, 2059ad247e8Sjmcneill 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 2061b18d63aSmrg 2079ad247e8Sjmcneill pixman_image_set_alpha_map (orig_dst, orig_alpha, doff, doff); 2089ad247e8Sjmcneill pixman_image_set_alpha_map (dst, alpha, doff, doff); 2099ad247e8Sjmcneill 2109ad247e8Sjmcneill pixman_image_unref (orig_alpha); 2119ad247e8Sjmcneill pixman_image_unref (alpha); 2129ad247e8Sjmcneill } 213952204abSmrg 214953d7d37Smrg /* Transformations, repeats and filters on destinations should be ignored, 215953d7d37Smrg * so just set some random ones. 2161b18d63aSmrg */ 2171b18d63aSmrg pixman_transform_init_identity (&t1); 2181b18d63aSmrg pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11)); 2191b18d63aSmrg pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11)); 2201b18d63aSmrg pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17)); 2211b18d63aSmrg 2221b18d63aSmrg pixman_image_set_transform (dst, &t1); 223953d7d37Smrg pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0); 224953d7d37Smrg pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT); 2251b18d63aSmrg 2261b18d63aSmrg pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst, 2271b18d63aSmrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 2281b18d63aSmrg 2291b18d63aSmrg for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j) 2301b18d63aSmrg { 2311b18d63aSmrg for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) 232952204abSmrg { 2339ad247e8Sjmcneill uint8_t sa, da, oda, refa; 2349ad247e8Sjmcneill uint16_t sr, dr, odr, refr; 2351b18d63aSmrg 2361b18d63aSmrg sa = get_alpha (src, k, j, soff, soff); 2371b18d63aSmrg da = get_alpha (dst, k, j, doff, doff); 2381b18d63aSmrg oda = get_alpha (orig_dst, k, j, doff, doff); 2391b18d63aSmrg 2401b18d63aSmrg if (sa + oda > 255) 2419ad247e8Sjmcneill refa = 255; 2421b18d63aSmrg else 2439ad247e8Sjmcneill refa = sa + oda; 2441b18d63aSmrg 2459ad247e8Sjmcneill if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits)) 246952204abSmrg { 2471b18d63aSmrg printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", 2489ad247e8Sjmcneill k, j, refa, da, sa, oda); 2491b18d63aSmrg 2501b18d63aSmrg printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", 2511b18d63aSmrg format_name (sf), 2521b18d63aSmrg format_name (saf), 2531b18d63aSmrg soff, soff, 2541b18d63aSmrg format_name (df), 2551b18d63aSmrg format_name (daf), 2561b18d63aSmrg doff, doff); 2571b18d63aSmrg return 1; 2581b18d63aSmrg } 2599ad247e8Sjmcneill 2609ad247e8Sjmcneill /* There are cases where we go through the 8 bit compositing 2619ad247e8Sjmcneill * path even with 10bpc formats. This results in incorrect 2629ad247e8Sjmcneill * results here, so only do the red check for narrow formats 2639ad247e8Sjmcneill */ 2649ad247e8Sjmcneill if (n_red_bits <= 8) 2659ad247e8Sjmcneill { 2669ad247e8Sjmcneill sr = get_red (src, k, j, soff, soff); 2679ad247e8Sjmcneill dr = get_red (dst, k, j, doff, doff); 2689ad247e8Sjmcneill odr = get_red (orig_dst, k, j, doff, doff); 2699ad247e8Sjmcneill 2709ad247e8Sjmcneill if (sr + odr > 0xffff) 2719ad247e8Sjmcneill refr = 0xffff; 2729ad247e8Sjmcneill else 2739ad247e8Sjmcneill refr = sr + odr; 2749ad247e8Sjmcneill 2759ad247e8Sjmcneill if (abs ((dr >> (16 - n_red_bits)) - (refr >> (16 - n_red_bits))) > 1) 2769ad247e8Sjmcneill { 2779ad247e8Sjmcneill printf ("%d red bits\n", n_red_bits); 2789ad247e8Sjmcneill printf ("\nWrong red value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", 2799ad247e8Sjmcneill k, j, refr, dr, sr, odr); 2809ad247e8Sjmcneill 2819ad247e8Sjmcneill printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", 2829ad247e8Sjmcneill format_name (sf), 2839ad247e8Sjmcneill format_name (saf), 2849ad247e8Sjmcneill soff, soff, 2859ad247e8Sjmcneill format_name (df), 2869ad247e8Sjmcneill format_name (daf), 2879ad247e8Sjmcneill doff, doff); 2889ad247e8Sjmcneill return 1; 2899ad247e8Sjmcneill } 2909ad247e8Sjmcneill } 2911b18d63aSmrg } 2921b18d63aSmrg } 2931b18d63aSmrg 2941b18d63aSmrg pixman_image_set_alpha_map (src, NULL, 0, 0); 2951b18d63aSmrg pixman_image_set_alpha_map (dst, NULL, 0, 0); 2961b18d63aSmrg pixman_image_set_alpha_map (orig_dst, NULL, 0, 0); 2971b18d63aSmrg 2981b18d63aSmrg pixman_image_unref (src); 2991b18d63aSmrg pixman_image_unref (dst); 3001b18d63aSmrg pixman_image_unref (orig_dst); 3011b18d63aSmrg 3021b18d63aSmrg return 0; 3031b18d63aSmrg} 3041b18d63aSmrg 3051b18d63aSmrgint 3061b18d63aSmrgmain (int argc, char **argv) 3071b18d63aSmrg{ 3081b18d63aSmrg int i, j, a, b, x, y; 309952204abSmrg 3101b18d63aSmrg for (i = 0; i < ARRAY_LENGTH (formats); ++i) 3111b18d63aSmrg { 3121b18d63aSmrg for (j = 0; j < ARRAY_LENGTH (formats); ++j) 3131b18d63aSmrg { 3141b18d63aSmrg for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a) 3151b18d63aSmrg { 3161b18d63aSmrg for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b) 317952204abSmrg { 3181b18d63aSmrg for (x = 0; x < ARRAY_LENGTH (origins); ++x) 3191b18d63aSmrg { 3201b18d63aSmrg for (y = 0; y < ARRAY_LENGTH (origins); ++y) 3211b18d63aSmrg { 3221b18d63aSmrg if (run_test (i, j, a, b, x, y) != 0) 3231b18d63aSmrg return 1; 3241b18d63aSmrg } 3251b18d63aSmrg } 326952204abSmrg } 327952204abSmrg } 328952204abSmrg } 329952204abSmrg } 330952204abSmrg 331952204abSmrg return 0; 332952204abSmrg} 333