alphamap.c revision 1b18d63a
1952204abSmrg#include <stdio.h> 2952204abSmrg#include <stdlib.h> 3952204abSmrg#include "utils.h" 4952204abSmrg 51b18d63aSmrg#define WIDTH 100 61b18d63aSmrg#define HEIGHT 100 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 pixman_image_t * 741b18d63aSmrgcreate_image (pixman_format_code_t format, pixman_format_code_t alpha_format, 751b18d63aSmrg int alpha_origin_x, int alpha_origin_y) 761b18d63aSmrg{ 771b18d63aSmrg pixman_image_t *image = make_image (format); 781b18d63aSmrg 791b18d63aSmrg if (alpha_format != PIXMAN_null) 801b18d63aSmrg { 811b18d63aSmrg pixman_image_t *alpha = make_image (alpha_format); 821b18d63aSmrg 831b18d63aSmrg pixman_image_set_alpha_map (image, alpha, 841b18d63aSmrg alpha_origin_x, alpha_origin_y); 851b18d63aSmrg pixman_image_unref (alpha); 861b18d63aSmrg } 871b18d63aSmrg 881b18d63aSmrg return image; 891b18d63aSmrg} 901b18d63aSmrg 911b18d63aSmrgstatic uint8_t 921b18d63aSmrgget_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y) 93952204abSmrg{ 941b18d63aSmrg uint8_t *bits; 951b18d63aSmrg uint8_t r; 961b18d63aSmrg 971b18d63aSmrg if (image->common.alpha_map) 981b18d63aSmrg { 991b18d63aSmrg if (x - orig_x >= 0 && x - orig_x < WIDTH && 1001b18d63aSmrg y - orig_y >= 0 && y - orig_y < HEIGHT) 1011b18d63aSmrg { 1021b18d63aSmrg image = (pixman_image_t *)image->common.alpha_map; 1031b18d63aSmrg 1041b18d63aSmrg x -= orig_x; 1051b18d63aSmrg y -= orig_y; 1061b18d63aSmrg } 1071b18d63aSmrg else 1081b18d63aSmrg { 1091b18d63aSmrg return 0; 1101b18d63aSmrg } 1111b18d63aSmrg } 112952204abSmrg 1131b18d63aSmrg bits = (uint8_t *)image->bits.bits; 114952204abSmrg 1151b18d63aSmrg if (image->bits.format == PIXMAN_a8) 1161b18d63aSmrg { 1171b18d63aSmrg r = bits[y * WIDTH + x]; 1181b18d63aSmrg } 1191b18d63aSmrg else if (image->bits.format == PIXMAN_a2r10g10b10) 1201b18d63aSmrg { 1211b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 30; 1221b18d63aSmrg r |= r << 2; 1231b18d63aSmrg r |= r << 4; 1241b18d63aSmrg } 1251b18d63aSmrg else if (image->bits.format == PIXMAN_a8r8g8b8) 1261b18d63aSmrg { 1271b18d63aSmrg r = ((uint32_t *)bits)[y * WIDTH + x] >> 24; 1281b18d63aSmrg } 1291b18d63aSmrg else if (image->bits.format == PIXMAN_a4r4g4b4) 130952204abSmrg { 1311b18d63aSmrg r = ((uint16_t *)bits)[y * WIDTH + x] >> 12; 1321b18d63aSmrg r |= r << 4; 1331b18d63aSmrg } 1341b18d63aSmrg else 1351b18d63aSmrg { 1361b18d63aSmrg assert (0); 1371b18d63aSmrg } 1381b18d63aSmrg 1391b18d63aSmrg return r; 1401b18d63aSmrg} 141952204abSmrg 1421b18d63aSmrg#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0]))) 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]; 1511b18d63aSmrg pixman_image_t *src, *dst, *orig_dst; 1521b18d63aSmrg pixman_transform_t t1; 1531b18d63aSmrg int j, k; 1541b18d63aSmrg int n_alpha_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 1631b18d63aSmrg 1641b18d63aSmrg src = create_image (sf, saf, soff, soff); 1651b18d63aSmrg orig_dst = create_image (df, daf, doff, doff); 1661b18d63aSmrg dst = create_image (df, daf, doff, doff); 167952204abSmrg 1681b18d63aSmrg /* Transformations on destinations should be ignored, so just set some 1691b18d63aSmrg * random one. 1701b18d63aSmrg */ 1711b18d63aSmrg pixman_transform_init_identity (&t1); 1721b18d63aSmrg pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11)); 1731b18d63aSmrg pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11)); 1741b18d63aSmrg pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17)); 1751b18d63aSmrg 1761b18d63aSmrg#if 0 1771b18d63aSmrg /* Unfortunately, this is actually broken at the moment, so we can't 1781b18d63aSmrg * actually turn it on 1791b18d63aSmrg */ 1801b18d63aSmrg pixman_image_set_transform (dst, &t1); 1811b18d63aSmrg#endif 1821b18d63aSmrg 1831b18d63aSmrg pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst, 1841b18d63aSmrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 1851b18d63aSmrg 1861b18d63aSmrg pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst, 1871b18d63aSmrg 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT); 1881b18d63aSmrg 1891b18d63aSmrg for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j) 1901b18d63aSmrg { 1911b18d63aSmrg for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k) 192952204abSmrg { 1931b18d63aSmrg uint8_t sa, da, oda, ref; 1941b18d63aSmrg 1951b18d63aSmrg sa = get_alpha (src, k, j, soff, soff); 1961b18d63aSmrg da = get_alpha (dst, k, j, doff, doff); 1971b18d63aSmrg oda = get_alpha (orig_dst, k, j, doff, doff); 1981b18d63aSmrg 1991b18d63aSmrg if (sa + oda > 255) 2001b18d63aSmrg ref = 255; 2011b18d63aSmrg else 2021b18d63aSmrg ref = sa + oda; 2031b18d63aSmrg 2041b18d63aSmrg if (da >> (8 - n_alpha_bits) != ref >> (8 - n_alpha_bits)) 205952204abSmrg { 2061b18d63aSmrg printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n", 2071b18d63aSmrg k, j, ref, da, sa, oda); 2081b18d63aSmrg 2091b18d63aSmrg printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n", 2101b18d63aSmrg format_name (sf), 2111b18d63aSmrg format_name (saf), 2121b18d63aSmrg soff, soff, 2131b18d63aSmrg format_name (df), 2141b18d63aSmrg format_name (daf), 2151b18d63aSmrg doff, doff); 2161b18d63aSmrg return 1; 2171b18d63aSmrg } 2181b18d63aSmrg } 2191b18d63aSmrg } 2201b18d63aSmrg 2211b18d63aSmrg pixman_image_set_alpha_map (src, NULL, 0, 0); 2221b18d63aSmrg pixman_image_set_alpha_map (dst, NULL, 0, 0); 2231b18d63aSmrg pixman_image_set_alpha_map (orig_dst, NULL, 0, 0); 2241b18d63aSmrg 2251b18d63aSmrg pixman_image_unref (src); 2261b18d63aSmrg pixman_image_unref (dst); 2271b18d63aSmrg pixman_image_unref (orig_dst); 2281b18d63aSmrg 2291b18d63aSmrg return 0; 2301b18d63aSmrg} 2311b18d63aSmrg 2321b18d63aSmrgint 2331b18d63aSmrgmain (int argc, char **argv) 2341b18d63aSmrg{ 2351b18d63aSmrg int i, j, a, b, x, y; 236952204abSmrg 2371b18d63aSmrg for (i = 0; i < ARRAY_LENGTH (formats); ++i) 2381b18d63aSmrg { 2391b18d63aSmrg for (j = 0; j < ARRAY_LENGTH (formats); ++j) 2401b18d63aSmrg { 2411b18d63aSmrg for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a) 2421b18d63aSmrg { 2431b18d63aSmrg for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b) 244952204abSmrg { 2451b18d63aSmrg for (x = 0; x < ARRAY_LENGTH (origins); ++x) 2461b18d63aSmrg { 2471b18d63aSmrg for (y = 0; y < ARRAY_LENGTH (origins); ++y) 2481b18d63aSmrg { 2491b18d63aSmrg if (run_test (i, j, a, b, x, y) != 0) 2501b18d63aSmrg return 1; 2511b18d63aSmrg } 2521b18d63aSmrg } 253952204abSmrg } 254952204abSmrg } 255952204abSmrg } 256952204abSmrg } 257952204abSmrg 258952204abSmrg return 0; 259952204abSmrg} 260