mirror of
https://salsa.debian.org/xorg-team/lib/pixman
synced 2025-09-06 12:25:16 +00:00

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
255 lines
5.6 KiB
C
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;
|
|
}
|