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