alphamap.c revision f4f78bb6
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 void 301b18d63aSmrgon_destroy (pixman_image_t *image, void *data) 311b18d63aSmrg{ 321b18d63aSmrg uint32_t *bits = pixman_image_get_data (image); 331b18d63aSmrg 341b18d63aSmrg fence_free (bits); 351b18d63aSmrg} 361b18d63aSmrg 371b18d63aSmrgstatic pixman_image_t * 381b18d63aSmrgmake_image (pixman_format_code_t format) 391b18d63aSmrg{ 401b18d63aSmrg uint32_t *bits; 411b18d63aSmrg uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8; 421b18d63aSmrg pixman_image_t *image; 431b18d63aSmrg 441b18d63aSmrg bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp); 451b18d63aSmrg 461b18d63aSmrg image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp); 471b18d63aSmrg 481b18d63aSmrg if (image && bits) 491b18d63aSmrg pixman_image_set_destroy_function (image, on_destroy, NULL); 501b18d63aSmrg 511b18d63aSmrg return image; 521b18d63aSmrg} 531b18d63aSmrg 541b18d63aSmrgstatic uint8_t 551b18d63aSmrgget_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) 56952204abSmrg{ 571b18d63aSmrg uint8_t *bits; 581b18d63aSmrg uint8_t r; 591b18d63aSmrg 601b18d63aSmrg if (image->common.alpha_map) 611b18d63aSmrg { 621b18d63aSmrg if (x - orig_x >= 0 && x - orig_x < WIDTH && 631b18d63aSmrg y - orig_y >= 0 && y - orig_y < HEIGHT) 641b18d63aSmrg { 651b18d63aSmrg image = (pixman_image_t *)image->common.alpha_map; 661b18d63aSmrg 671b18d63aSmrg x -= orig_x; 681b18d63aSmrg y -= orig_y; 691b18d63aSmrg } 701b18d63aSmrg else 711b18d63aSmrg { 721b18d63aSmrg return 0; 731b18d63aSmrg } 741b18d63aSmrg } 75952204abSmrg 761b18d63aSmrg bits = (uint8_t *)image->bits.bits; 77952204abSmrg 781b18d63aSmrg if (image->bits.format == PIXMAN_a8) 791b18d63aSmrg { 801b18d63aSmrg r = bits[y * WIDTH + x]; 811b18d63aSmrg } 821b18d63aSmrg else if (image->bits.format == PIXMAN_a2r10g10b10) 831b18d63aSmrg { 841b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; 851b18d63aSmrg r |= r << 2; 861b18d63aSmrg r |= r << 4; 871b18d63aSmrg } 881b18d63aSmrg else if (image->bits.format == PIXMAN_a8r8g8b8) 891b18d63aSmrg { 901b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; 911b18d63aSmrg } 921b18d63aSmrg else if (image->bits.format == PIXMAN_a4r4g4b4) 93952204abSmrg { 941b18d63aSmrg r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; 951b18d63aSmrg r |= r << 4; 961b18d63aSmrg } 971b18d63aSmrg else 981b18d63aSmrg { 991b18d63aSmrg assert (0); 1001b18d63aSmrg } 1011b18d63aSmrg 1021b18d63aSmrg return r; 1031b18d63aSmrg} 104952204abSmrg 1059ad247e8Sjmcneillstatic uint16_t 1069ad247e8Sjmcneillget_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y) 1079ad247e8Sjmcneill{ 1089ad247e8Sjmcneill uint8_t *bits; 1099ad247e8Sjmcneill uint16_t r; 1109ad247e8Sjmcneill 1119ad247e8Sjmcneill bits = (uint8_t *)image->bits.bits; 1129ad247e8Sjmcneill 1139ad247e8Sjmcneill if (image->bits.format == PIXMAN_a8) 1149ad247e8Sjmcneill { 1159ad247e8Sjmcneill r = 0x00; 1169ad247e8Sjmcneill } 1179ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a2r10g10b10) 1189ad247e8Sjmcneill { 1199ad247e8Sjmcneill r = ((uint32_t *)bits)[y * WIDTH + x] >> 14; 1209ad247e8Sjmcneill r &= 0xffc0; 1219ad247e8Sjmcneill r |= (r >> 10); 1229ad247e8Sjmcneill } 1239ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a8r8g8b8) 1249ad247e8Sjmcneill { 1259ad247e8Sjmcneill r = ((uint32_t *)bits)[y * WIDTH + x] >> 16; 1269ad247e8Sjmcneill r &= 0xff; 1279ad247e8Sjmcneill r |= r << 8; 1289ad247e8Sjmcneill } 1299ad247e8Sjmcneill else if (image->bits.format == PIXMAN_a4r4g4b4) 1309ad247e8Sjmcneill { 1319ad247e8Sjmcneill r = ((uint16_t *)bits)[y * WIDTH + x] >> 8; 1329ad247e8Sjmcneill r &= 0xf; 1339ad247e8Sjmcneill r |= r << 4; 1349ad247e8Sjmcneill r |= r << 8; 1359ad247e8Sjmcneill } 1369ad247e8Sjmcneill else 1379ad247e8Sjmcneill { 1389ad247e8Sjmcneill assert (0); 1399ad247e8Sjmcneill } 1409ad247e8Sjmcneill 1419ad247e8Sjmcneill return r; 1429ad247e8Sjmcneill} 143952204abSmrg 1441b18d63aSmrgstatic int 1451b18d63aSmrgrun_test (int s, int d, int sa, int da, int soff, int doff) 1461b18d63aSmrg{ 1471b18d63aSmrg pixman_format_code_t sf = formats[s]; 1481b18d63aSmrg pixman_format_code_t df = formats[d]; 1491b18d63aSmrg pixman_format_code_t saf = alpha_formats[sa]; 1501b18d63aSmrg pixman_format_code_t daf = alpha_formats[da]; 1519ad247e8Sjmcneill pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha; 1521b18d63aSmrg pixman_transform_t t1; 1531b18d63aSmrg int j, k; 1549ad247e8Sjmcneill int n_alpha_bits, n_red_bits; 1551b18d63aSmrg 1561b18d63aSmrg soff = origins[soff]; 1571b18d63aSmrg doff = origins[doff]; 1581b18d63aSmrg 1591b18d63aSmrg n_alpha_bits = PIXMAN_FORMAT_A (df); 1601b18d63aSmrg if (daf != PIXMAN_null) 1611b18d63aSmrg n_alpha_bits = PIXMAN_FORMAT_A (daf); 1621b18d63aSmrg 1639ad247e8Sjmcneill n_red_bits = PIXMAN_FORMAT_R (df); 1649ad247e8Sjmcneill 1659ad247e8Sjmcneill /* Source */ 1669ad247e8Sjmcneill src = make_image (sf); 1679ad247e8Sjmcneill if (saf != PIXMAN_null) 1689ad247e8Sjmcneill { 1699ad247e8Sjmcneill alpha = make_image (saf); 1709ad247e8Sjmcneill pixman_image_set_alpha_map (src, alpha, soff, soff); 1719ad247e8Sjmcneill pixman_image_unref (alpha); 1729ad247e8Sjmcneill } 1739ad247e8Sjmcneill 1749ad247e8Sjmcneill /* Destination */ 1759ad247e8Sjmcneill orig_dst = make_image (df); 1769ad247e8Sjmcneill dst = make_image (df); 1779ad247e8Sjmcneill pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst, 1789ad247e8Sjmcneill 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 1799ad247e8Sjmcneill 1809ad247e8Sjmcneill if (daf != PIXMAN_null) 1819ad247e8Sjmcneill { 1829ad247e8Sjmcneill orig_alpha = make_image (daf); 1839ad247e8Sjmcneill alpha = make_image (daf); 1849ad247e8Sjmcneill 1859ad247e8Sjmcneill pixman_image_composite (PIXMAN_OP_SRC, orig_alpha, NULL, alpha, 1869ad247e8Sjmcneill 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 1871b18d63aSmrg 1889ad247e8Sjmcneill pixman_image_set_alpha_map (orig_dst, orig_alpha, doff, doff); 1899ad247e8Sjmcneill pixman_image_set_alpha_map (dst, alpha, doff, doff); 1909ad247e8Sjmcneill 1919ad247e8Sjmcneill pixman_image_unref (orig_alpha); 1929ad247e8Sjmcneill pixman_image_unref (alpha); 1939ad247e8Sjmcneill } 194952204abSmrg 195953d7d37Smrg /* Transformations, repeats and filters on destinations should be ignored, 196953d7d37Smrg * so just set some random ones. 1971b18d63aSmrg */ 1981b18d63aSmrg pixman_transform_init_identity (&t1); 1991b18d63aSmrg pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11)); 2001b18d63aSmrg pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11)); 2011b18d63aSmrg pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17)); 2021b18d63aSmrg 2031b18d63aSmrg pixman_image_set_transform (dst, &t1); 204953d7d37Smrg pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0); 205953d7d37Smrg pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT); 2061b18d63aSmrg 2071b18d63aSmrg pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst, 2081b18d63aSmrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 2091b18d63aSmrg 2101b18d63aSmrg for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j) 2111b18d63aSmrg { 2121b18d63aSmrg for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) 213952204abSmrg { 2149ad247e8Sjmcneill uint8_t sa, da, oda, refa; 2159ad247e8Sjmcneill uint16_t sr, dr, odr, refr; 2161b18d63aSmrg 2171b18d63aSmrg sa = get_alpha (src, k, j, soff, soff); 2181b18d63aSmrg da = get_alpha (dst, k, j, doff, doff); 2191b18d63aSmrg oda = get_alpha (orig_dst, k, j, doff, doff); 2201b18d63aSmrg 2211b18d63aSmrg if (sa + oda > 255) 2229ad247e8Sjmcneill refa = 255; 2231b18d63aSmrg else 2249ad247e8Sjmcneill refa = sa + oda; 2251b18d63aSmrg 2269ad247e8Sjmcneill if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits)) 227952204abSmrg { 2281b18d63aSmrg printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", 2299ad247e8Sjmcneill k, j, refa, da, sa, oda); 2301b18d63aSmrg 2311b18d63aSmrg printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", 2321b18d63aSmrg format_name (sf), 2331b18d63aSmrg format_name (saf), 2341b18d63aSmrg soff, soff, 2351b18d63aSmrg format_name (df), 2361b18d63aSmrg format_name (daf), 2371b18d63aSmrg doff, doff); 2381b18d63aSmrg return 1; 2391b18d63aSmrg } 2409ad247e8Sjmcneill 2419ad247e8Sjmcneill /* There are cases where we go through the 8 bit compositing 2429ad247e8Sjmcneill * path even with 10bpc formats. This results in incorrect 2439ad247e8Sjmcneill * results here, so only do the red check for narrow formats 2449ad247e8Sjmcneill */ 2459ad247e8Sjmcneill if (n_red_bits <= 8) 2469ad247e8Sjmcneill { 2479ad247e8Sjmcneill sr = get_red (src, k, j, soff, soff); 2489ad247e8Sjmcneill dr = get_red (dst, k, j, doff, doff); 2499ad247e8Sjmcneill odr = get_red (orig_dst, k, j, doff, doff); 2509ad247e8Sjmcneill 2519ad247e8Sjmcneill if (sr + odr > 0xffff) 2529ad247e8Sjmcneill refr = 0xffff; 2539ad247e8Sjmcneill else 2549ad247e8Sjmcneill refr = sr + odr; 2559ad247e8Sjmcneill 2569ad247e8Sjmcneill if (abs ((dr >> (16 - n_red_bits)) - (refr >> (16 - n_red_bits))) > 1) 2579ad247e8Sjmcneill { 2589ad247e8Sjmcneill printf ("%d red bits\n", n_red_bits); 2599ad247e8Sjmcneill printf ("\nWrong red value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", 2609ad247e8Sjmcneill k, j, refr, dr, sr, odr); 2619ad247e8Sjmcneill 2629ad247e8Sjmcneill printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", 2639ad247e8Sjmcneill format_name (sf), 2649ad247e8Sjmcneill format_name (saf), 2659ad247e8Sjmcneill soff, soff, 2669ad247e8Sjmcneill format_name (df), 2679ad247e8Sjmcneill format_name (daf), 2689ad247e8Sjmcneill doff, doff); 2699ad247e8Sjmcneill return 1; 2709ad247e8Sjmcneill } 2719ad247e8Sjmcneill } 2721b18d63aSmrg } 2731b18d63aSmrg } 2741b18d63aSmrg 2751b18d63aSmrg pixman_image_set_alpha_map (src, NULL, 0, 0); 2761b18d63aSmrg pixman_image_set_alpha_map (dst, NULL, 0, 0); 2771b18d63aSmrg pixman_image_set_alpha_map (orig_dst, NULL, 0, 0); 2781b18d63aSmrg 2791b18d63aSmrg pixman_image_unref (src); 2801b18d63aSmrg pixman_image_unref (dst); 2811b18d63aSmrg pixman_image_unref (orig_dst); 2821b18d63aSmrg 2831b18d63aSmrg return 0; 2841b18d63aSmrg} 2851b18d63aSmrg 2861b18d63aSmrgint 2871b18d63aSmrgmain (int argc, char **argv) 2881b18d63aSmrg{ 2891b18d63aSmrg int i, j, a, b, x, y; 290952204abSmrg 291f4f78bb6Smrg prng_srand (0); 292f4f78bb6Smrg 2931b18d63aSmrg for (i = 0; i < ARRAY_LENGTH (formats); ++i) 2941b18d63aSmrg { 2951b18d63aSmrg for (j = 0; j < ARRAY_LENGTH (formats); ++j) 2961b18d63aSmrg { 2971b18d63aSmrg for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a) 2981b18d63aSmrg { 2991b18d63aSmrg for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b) 300952204abSmrg { 3011b18d63aSmrg for (x = 0; x < ARRAY_LENGTH (origins); ++x) 3021b18d63aSmrg { 3031b18d63aSmrg for (y = 0; y < ARRAY_LENGTH (origins); ++y) 3041b18d63aSmrg { 3051b18d63aSmrg if (run_test (i, j, a, b, x, y) != 0) 3061b18d63aSmrg return 1; 3071b18d63aSmrg } 3081b18d63aSmrg } 309952204abSmrg } 310952204abSmrg } 311952204abSmrg } 312952204abSmrg } 313952204abSmrg 314952204abSmrg return 0; 315952204abSmrg} 316