Blame test/alphamap.c

Packit 030a23
#include <stdio.h>
Packit 030a23
#include <stdlib.h>
Packit 030a23
#include "utils.h"
Packit 030a23
Packit 030a23
#define WIDTH 48
Packit 030a23
#define HEIGHT 48
Packit 030a23
Packit 030a23
static const pixman_format_code_t formats[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_a8r8g8b8,
Packit 030a23
    PIXMAN_a2r10g10b10,
Packit 030a23
    PIXMAN_a4r4g4b4,
Packit 030a23
    PIXMAN_a8
Packit 030a23
};
Packit 030a23
Packit 030a23
static const pixman_format_code_t alpha_formats[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_null,
Packit 030a23
    PIXMAN_a8,
Packit 030a23
    PIXMAN_a2r10g10b10,
Packit 030a23
    PIXMAN_a4r4g4b4
Packit 030a23
};
Packit 030a23
Packit 030a23
static const int origins[] =
Packit 030a23
{
Packit 030a23
    0, 10, -100
Packit 030a23
};
Packit 030a23
Packit 030a23
static void
Packit 030a23
on_destroy (pixman_image_t *image, void *data)
Packit 030a23
{
Packit 030a23
    uint32_t *bits = pixman_image_get_data (image);
Packit 030a23
Packit 030a23
    fence_free (bits);
Packit 030a23
}
Packit 030a23
Packit 030a23
static pixman_image_t *
Packit 030a23
make_image (pixman_format_code_t format)
Packit 030a23
{
Packit 030a23
    uint32_t *bits;
Packit 030a23
    uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
Packit 030a23
    pixman_image_t *image;
Packit 030a23
Packit 030a23
    bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
Packit 030a23
Packit 030a23
    image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
Packit 030a23
Packit 030a23
    if (image && bits)
Packit 030a23
	pixman_image_set_destroy_function (image, on_destroy, NULL);
Packit 030a23
Packit 030a23
    return image;
Packit 030a23
}
Packit 030a23
Packit 030a23
static uint8_t
Packit 030a23
get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
Packit 030a23
{
Packit 030a23
    uint8_t *bits;
Packit 030a23
    uint8_t r;
Packit 030a23
Packit 030a23
    if (image->common.alpha_map)
Packit 030a23
    {
Packit 030a23
	if (x - orig_x >= 0 && x - orig_x < WIDTH &&
Packit 030a23
	    y - orig_y >= 0 && y - orig_y < HEIGHT)
Packit 030a23
	{
Packit 030a23
	    image = (pixman_image_t *)image->common.alpha_map;
Packit 030a23
Packit 030a23
	    x -= orig_x;
Packit 030a23
	    y -= orig_y;
Packit 030a23
	}
Packit 030a23
	else
Packit 030a23
	{
Packit 030a23
	    return 0;
Packit 030a23
	}
Packit 030a23
    }
Packit 030a23
Packit 030a23
    bits = (uint8_t *)image->bits.bits;
Packit 030a23
Packit 030a23
    if (image->bits.format == PIXMAN_a8)
Packit 030a23
    {
Packit 030a23
	r = bits[y * WIDTH + x];
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a2r10g10b10)
Packit 030a23
    {
Packit 030a23
	r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
Packit 030a23
	r |= r << 2;
Packit 030a23
	r |= r << 4;
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a8r8g8b8)
Packit 030a23
    {
Packit 030a23
	r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a4r4g4b4)
Packit 030a23
    {
Packit 030a23
	r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
Packit 030a23
	r |= r << 4;
Packit 030a23
    }
Packit 030a23
    else
Packit 030a23
    {
Packit 030a23
	assert (0);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    return r;
Packit 030a23
}
Packit 030a23
Packit 030a23
static uint16_t
Packit 030a23
get_red (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
Packit 030a23
{
Packit 030a23
    uint8_t *bits;
Packit 030a23
    uint16_t r;
Packit 030a23
Packit 030a23
    bits = (uint8_t *)image->bits.bits;
Packit 030a23
Packit 030a23
    if (image->bits.format == PIXMAN_a8)
Packit 030a23
    {
Packit 030a23
	r = 0x00;
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a2r10g10b10)
Packit 030a23
    {
Packit 030a23
	r = ((uint32_t *)bits)[y * WIDTH + x] >> 14;
Packit 030a23
	r &= 0xffc0;
Packit 030a23
	r |= (r >> 10);
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a8r8g8b8)
Packit 030a23
    {
Packit 030a23
	r = ((uint32_t *)bits)[y * WIDTH + x] >> 16;
Packit 030a23
	r &= 0xff;
Packit 030a23
	r |= r << 8;
Packit 030a23
    }
Packit 030a23
    else if (image->bits.format == PIXMAN_a4r4g4b4)
Packit 030a23
    {
Packit 030a23
	r = ((uint16_t *)bits)[y * WIDTH + x] >> 8;
Packit 030a23
	r &= 0xf;
Packit 030a23
	r |= r << 4;
Packit 030a23
	r |= r << 8;
Packit 030a23
    }
Packit 030a23
    else
Packit 030a23
    {
Packit 030a23
	assert (0);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    return r;
Packit 030a23
}
Packit 030a23
Packit 030a23
static int
Packit 030a23
run_test (int s, int d, int sa, int da, int soff, int doff)
Packit 030a23
{
Packit 030a23
    pixman_format_code_t sf = formats[s];
Packit 030a23
    pixman_format_code_t df = formats[d];
Packit 030a23
    pixman_format_code_t saf = alpha_formats[sa];
Packit 030a23
    pixman_format_code_t daf = alpha_formats[da];
Packit 030a23
    pixman_image_t *src, *dst, *orig_dst, *alpha, *orig_alpha;
Packit 030a23
    pixman_transform_t t1;
Packit 030a23
    int j, k;
Packit 030a23
    int n_alpha_bits, n_red_bits;
Packit 030a23
Packit 030a23
    soff = origins[soff];
Packit 030a23
    doff = origins[doff];
Packit 030a23
Packit 030a23
    n_alpha_bits = PIXMAN_FORMAT_A (df);
Packit 030a23
    if (daf != PIXMAN_null)
Packit 030a23
	n_alpha_bits = PIXMAN_FORMAT_A (daf);
Packit 030a23
Packit 030a23
    n_red_bits = PIXMAN_FORMAT_R (df);
Packit 030a23
Packit 030a23
    /* Source */
Packit 030a23
    src = make_image (sf);
Packit 030a23
    if (saf != PIXMAN_null)
Packit 030a23
    {
Packit 030a23
	alpha = make_image (saf);
Packit 030a23
	pixman_image_set_alpha_map (src, alpha, soff, soff);
Packit 030a23
	pixman_image_unref (alpha);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    /* Destination */
Packit 030a23
    orig_dst = make_image (df);
Packit 030a23
    dst = make_image (df);
Packit 030a23
    pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
Packit 030a23
			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
Packit 030a23
Packit 030a23
    if (daf != PIXMAN_null)
Packit 030a23
    {
Packit 030a23
	orig_alpha = make_image (daf);
Packit 030a23
	alpha = make_image (daf);
Packit 030a23
Packit 030a23
	pixman_image_composite (PIXMAN_OP_SRC, orig_alpha, NULL, alpha,
Packit 030a23
				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
Packit 030a23
Packit 030a23
	pixman_image_set_alpha_map (orig_dst, orig_alpha, doff, doff);
Packit 030a23
	pixman_image_set_alpha_map (dst, alpha, doff, doff);
Packit 030a23
Packit 030a23
	pixman_image_unref (orig_alpha);
Packit 030a23
	pixman_image_unref (alpha);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    /* Transformations, repeats and filters on destinations should be ignored,
Packit 030a23
     * so just set some random ones.
Packit 030a23
     */
Packit 030a23
    pixman_transform_init_identity (&t1;;
Packit 030a23
    pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
Packit 030a23
    pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
Packit 030a23
    pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
Packit 030a23
Packit 030a23
    pixman_image_set_transform (dst, &t1;;
Packit 030a23
    pixman_image_set_filter (dst, PIXMAN_FILTER_BILINEAR, NULL, 0);
Packit 030a23
    pixman_image_set_repeat (dst, PIXMAN_REPEAT_REFLECT);
Packit 030a23
Packit 030a23
    pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
Packit 030a23
			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
Packit 030a23
Packit 030a23
    for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
Packit 030a23
    {
Packit 030a23
	for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
Packit 030a23
	{
Packit 030a23
	    uint8_t sa, da, oda, refa;
Packit 030a23
	    uint16_t sr, dr, odr, refr;
Packit 030a23
Packit 030a23
	    sa = get_alpha (src, k, j, soff, soff);
Packit 030a23
	    da = get_alpha (dst, k, j, doff, doff);
Packit 030a23
	    oda = get_alpha (orig_dst, k, j, doff, doff);
Packit 030a23
Packit 030a23
	    if (sa + oda > 255)
Packit 030a23
		refa = 255;
Packit 030a23
	    else
Packit 030a23
		refa = sa + oda;
Packit 030a23
Packit 030a23
	    if (da >> (8 - n_alpha_bits) != refa >> (8 - n_alpha_bits))
Packit 030a23
	    {
Packit 030a23
		printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
Packit 030a23
			k, j, refa, da, sa, oda);
Packit 030a23
Packit 030a23
		printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
Packit 030a23
			format_name (sf),
Packit 030a23
			format_name (saf),
Packit 030a23
			soff, soff,
Packit 030a23
			format_name (df),
Packit 030a23
			format_name (daf),
Packit 030a23
			doff, doff);
Packit 030a23
		return 1;
Packit 030a23
	    }
Packit 030a23
Packit 030a23
	    /* There are cases where we go through the 8 bit compositing
Packit 030a23
	     * path even with 10bpc formats. This results in incorrect
Packit 030a23
	     * results here, so only do the red check for narrow formats
Packit 030a23
	     */
Packit 030a23
	    if (n_red_bits <= 8)
Packit 030a23
	    {
Packit 030a23
		sr = get_red (src, k, j, soff, soff);
Packit 030a23
		dr = get_red (dst, k, j, doff, doff);
Packit 030a23
		odr = get_red (orig_dst, k, j, doff, doff);
Packit 030a23
Packit 030a23
		if (sr + odr > 0xffff)
Packit 030a23
		    refr = 0xffff;
Packit 030a23
		else
Packit 030a23
		    refr = sr + odr;
Packit 030a23
Packit 030a23
		if (abs ((dr >> (16 - n_red_bits)) - (refr >> (16 - n_red_bits))) > 1)
Packit 030a23
		{
Packit 030a23
		    printf ("%d red bits\n", n_red_bits);
Packit 030a23
		    printf ("\nWrong red value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
Packit 030a23
			    k, j, refr, dr, sr, odr);
Packit 030a23
Packit 030a23
		    printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
Packit 030a23
			    format_name (sf),
Packit 030a23
			    format_name (saf),
Packit 030a23
			    soff, soff,
Packit 030a23
			    format_name (df),
Packit 030a23
			    format_name (daf),
Packit 030a23
			    doff, doff);
Packit 030a23
		    return 1;
Packit 030a23
		}
Packit 030a23
	    }
Packit 030a23
	}
Packit 030a23
    }
Packit 030a23
Packit 030a23
    pixman_image_set_alpha_map (src, NULL, 0, 0);
Packit 030a23
    pixman_image_set_alpha_map (dst, NULL, 0, 0);
Packit 030a23
    pixman_image_set_alpha_map (orig_dst, NULL, 0, 0);
Packit 030a23
Packit 030a23
    pixman_image_unref (src);
Packit 030a23
    pixman_image_unref (dst);
Packit 030a23
    pixman_image_unref (orig_dst);
Packit 030a23
Packit 030a23
    return 0;
Packit 030a23
}
Packit 030a23
Packit 030a23
int
Packit 030a23
main (int argc, char **argv)
Packit 030a23
{
Packit 030a23
    int i, j, a, b, x, y;
Packit 030a23
Packit 030a23
    prng_srand (0);
Packit 030a23
Packit 030a23
    for (i = 0; i < ARRAY_LENGTH (formats); ++i)
Packit 030a23
    {
Packit 030a23
	for (j = 0; j < ARRAY_LENGTH (formats); ++j)
Packit 030a23
	{
Packit 030a23
	    for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
Packit 030a23
	    {
Packit 030a23
		for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
Packit 030a23
		{
Packit 030a23
		    for (x = 0; x < ARRAY_LENGTH (origins); ++x)
Packit 030a23
		    {
Packit 030a23
			for (y = 0; y < ARRAY_LENGTH (origins); ++y)
Packit 030a23
			{
Packit 030a23
			    if (run_test (i, j, a, b, x, y) != 0)
Packit 030a23
				return 1;
Packit 030a23
			}
Packit 030a23
		    }
Packit 030a23
		}
Packit 030a23
	    }
Packit 030a23
	}
Packit 030a23
    }
Packit 030a23
Packit 030a23
    return 0;
Packit 030a23
}