pixman/test/alphamap.c
Søren Sandmann Pedersen e46be417ce Plug leak in the alphamap test.
The images are being created with non-NULL data, so we have to free it
outselves. This is important because the Cygwin tinderbox is running
out of memory and produces this:

    mmap failed on 20000 1507328
    mmap failed on 40000 1507328
    mmap failed on 20000 1507328
    mmap failed on 40000 1507328
    mmap failed on 40000 1507328
    mmap failed on 40000 1507328

http://tinderbox.x.org/builds/2010-10-05-0014/logs/pixman/#check
2010-10-11 12:06:20 -04:00

255 lines
5.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include "utils.h"
#define WIDTH 100
#define HEIGHT 100
static const pixman_format_code_t formats[] =
{
PIXMAN_a8r8g8b8,
PIXMAN_a2r10g10b10,
PIXMAN_a4r4g4b4,
PIXMAN_a8
};
static const pixman_format_code_t alpha_formats[] =
{
PIXMAN_null,
PIXMAN_a8,
PIXMAN_a2r10g10b10,
PIXMAN_a4r4g4b4
};
static const int origins[] =
{
0, 10, -100
};
static const char *
format_name (pixman_format_code_t format)
{
if (format == PIXMAN_a8)
return "a8";
else if (format == PIXMAN_a2r10g10b10)
return "a2r10g10b10";
else if (format == PIXMAN_a8r8g8b8)
return "a8r8g8b8";
else if (format == PIXMAN_a4r4g4b4)
return "a4r4g4b4";
else if (format == PIXMAN_null)
return "none";
else
assert (0);
return "<unknown - bug in alphamap.c>";
}
static void
on_destroy (pixman_image_t *image, void *data)
{
uint32_t *bits = pixman_image_get_data (image);
fence_free (bits);
}
static pixman_image_t *
make_image (pixman_format_code_t format)
{
uint32_t *bits;
uint8_t bpp = PIXMAN_FORMAT_BPP (format) / 8;
pixman_image_t *image;
bits = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * bpp);
image = pixman_image_create_bits (format, WIDTH, HEIGHT, bits, WIDTH * bpp);
if (image && bits)
pixman_image_set_destroy_function (image, on_destroy, NULL);
return image;
}
static pixman_image_t *
create_image (pixman_format_code_t format, pixman_format_code_t alpha_format,
int alpha_origin_x, int alpha_origin_y)
{
pixman_image_t *image = make_image (format);
if (alpha_format != PIXMAN_null)
{
pixman_image_t *alpha = make_image (alpha_format);
pixman_image_set_alpha_map (image, alpha,
alpha_origin_x, alpha_origin_y);
}
return image;
}
static uint8_t
get_alpha (pixman_image_t *image, int x, int y, int orig_x, int orig_y)
{
uint8_t *bits;
uint8_t r;
if (image->common.alpha_map)
{
if (x - orig_x >= 0 && x - orig_x < WIDTH &&
y - orig_y >= 0 && y - orig_y < HEIGHT)
{
image = (pixman_image_t *)image->common.alpha_map;
x -= orig_x;
y -= orig_y;
}
else
{
return 0;
}
}
bits = (uint8_t *)image->bits.bits;
if (image->bits.format == PIXMAN_a8)
{
r = bits[y * WIDTH + x];
}
else if (image->bits.format == PIXMAN_a2r10g10b10)
{
r = ((uint32_t *)bits)[y * WIDTH + x] >> 30;
r |= r << 2;
r |= r << 4;
}
else if (image->bits.format == PIXMAN_a8r8g8b8)
{
r = ((uint32_t *)bits)[y * WIDTH + x] >> 24;
}
else if (image->bits.format == PIXMAN_a4r4g4b4)
{
r = ((uint16_t *)bits)[y * WIDTH + x] >> 12;
r |= r << 4;
}
else
{
assert (0);
}
return r;
}
#define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
static int
run_test (int s, int d, int sa, int da, int soff, int doff)
{
pixman_format_code_t sf = formats[s];
pixman_format_code_t df = formats[d];
pixman_format_code_t saf = alpha_formats[sa];
pixman_format_code_t daf = alpha_formats[da];
pixman_image_t *src, *dst, *orig_dst;
pixman_transform_t t1;
int j, k;
int n_alpha_bits;
soff = origins[soff];
doff = origins[doff];
n_alpha_bits = PIXMAN_FORMAT_A (df);
if (daf != PIXMAN_null)
n_alpha_bits = PIXMAN_FORMAT_A (daf);
src = create_image (sf, saf, soff, soff);
orig_dst = create_image (df, daf, doff, doff);
dst = create_image (df, daf, doff, doff);
/* Transformations on destinations should be ignored, so just set some
* random one.
*/
pixman_transform_init_identity (&t1);
pixman_transform_scale (&t1, NULL, pixman_int_to_fixed (100), pixman_int_to_fixed (11));
pixman_transform_rotate (&t1, NULL, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.11));
pixman_transform_translate (&t1, NULL, pixman_int_to_fixed (11), pixman_int_to_fixed (17));
#if 0
/* Unfortunately, this is actually broken at the moment, so we can't
* actually turn it on
*/
pixman_image_set_transform (dst, &t1);
#endif
pixman_image_composite (PIXMAN_OP_SRC, orig_dst, NULL, dst,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
pixman_image_composite (PIXMAN_OP_ADD, src, NULL, dst,
0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
for (j = MAX (doff, 0); j < MIN (HEIGHT, HEIGHT + doff); ++j)
{
for (k = MAX (doff, 0); k < MIN (WIDTH, WIDTH + doff); ++k)
{
uint8_t sa, da, oda, ref;
sa = get_alpha (src, k, j, soff, soff);
da = get_alpha (dst, k, j, doff, doff);
oda = get_alpha (orig_dst, k, j, doff, doff);
if (sa + oda > 255)
ref = 255;
else
ref = sa + oda;
if (da >> (8 - n_alpha_bits) != ref >> (8 - n_alpha_bits))
{
printf ("\nWrong alpha value at (%d, %d). Should be 0x%x; got 0x%x. Source was 0x%x, original dest was 0x%x\n",
k, j, ref, da, sa, oda);
printf ("src: %s, alpha: %s, origin %d %d\ndst: %s, alpha: %s, origin: %d %d\n\n",
format_name (sf),
format_name (saf),
soff, soff,
format_name (df),
format_name (daf),
doff, doff);
return 1;
}
}
}
pixman_image_unref (src);
pixman_image_unref (dst);
pixman_image_unref (orig_dst);
return 0;
}
int
main (int argc, char **argv)
{
int i, j, a, b, x, y;
for (i = 0; i < ARRAY_LENGTH (formats); ++i)
{
for (j = 0; j < ARRAY_LENGTH (formats); ++j)
{
for (a = 0; a < ARRAY_LENGTH (alpha_formats); ++a)
{
for (b = 0; b < ARRAY_LENGTH (alpha_formats); ++b)
{
for (x = 0; x < ARRAY_LENGTH (origins); ++x)
{
for (y = 0; y < ARRAY_LENGTH (origins); ++y)
{
if (run_test (i, j, a, b, x, y) != 0)
return 1;
}
}
}
}
}
}
return 0;
}