Blame test/glyph-test.c

Packit 030a23
#include <stdlib.h>
Packit 030a23
#include "utils.h"
Packit 030a23
Packit 030a23
static const pixman_format_code_t glyph_formats[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_a8r8g8b8,
Packit 030a23
    PIXMAN_a8,
Packit 030a23
    PIXMAN_a4,
Packit 030a23
    PIXMAN_a1,
Packit 030a23
    PIXMAN_x8r8g8b8,
Packit 030a23
    PIXMAN_r3g3b2,
Packit 030a23
    PIXMAN_null,
Packit 030a23
};
Packit 030a23
Packit 030a23
static const pixman_format_code_t formats[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_a8r8g8b8,
Packit 030a23
    PIXMAN_a8b8g8r8,
Packit 030a23
    PIXMAN_x8r8g8b8,
Packit 030a23
    PIXMAN_x8b8g8r8,
Packit 030a23
    PIXMAN_r5g6b5,
Packit 030a23
    PIXMAN_b5g6r5,
Packit 030a23
    PIXMAN_a8,
Packit 030a23
    PIXMAN_a1,
Packit 030a23
    PIXMAN_r3g3b2,
Packit 030a23
    PIXMAN_b8g8r8a8,
Packit 030a23
    PIXMAN_b8g8r8x8,
Packit 030a23
    PIXMAN_r8g8b8a8,
Packit 030a23
    PIXMAN_r8g8b8x8,
Packit 030a23
    PIXMAN_x14r6g6b6,
Packit 030a23
    PIXMAN_r8g8b8,
Packit 030a23
    PIXMAN_b8g8r8,
Packit 030a23
#if 0
Packit 030a23
    /* These use floating point */
Packit 030a23
    PIXMAN_x2r10g10b10,
Packit 030a23
    PIXMAN_a2r10g10b10,
Packit 030a23
    PIXMAN_x2b10g10r10,
Packit 030a23
    PIXMAN_a2b10g10r10,
Packit 030a23
#endif
Packit 030a23
    PIXMAN_a1r5g5b5,
Packit 030a23
    PIXMAN_x1r5g5b5,
Packit 030a23
    PIXMAN_a1b5g5r5,
Packit 030a23
    PIXMAN_x1b5g5r5,
Packit 030a23
    PIXMAN_a4r4g4b4,
Packit 030a23
    PIXMAN_x4r4g4b4,
Packit 030a23
    PIXMAN_a4b4g4r4,
Packit 030a23
    PIXMAN_x4b4g4r4,
Packit 030a23
    PIXMAN_r3g3b2,
Packit 030a23
    PIXMAN_b2g3r3,
Packit 030a23
    PIXMAN_a2r2g2b2,
Packit 030a23
    PIXMAN_a2b2g2r2,
Packit 030a23
    PIXMAN_x4a4,
Packit 030a23
    PIXMAN_a4,
Packit 030a23
    PIXMAN_r1g2b1,
Packit 030a23
    PIXMAN_b1g2r1,
Packit 030a23
    PIXMAN_a1r1g1b1,
Packit 030a23
    PIXMAN_a1b1g1r1,
Packit 030a23
    PIXMAN_null,
Packit 030a23
};
Packit 030a23
Packit 030a23
static const pixman_op_t operators[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_OP_SRC,
Packit 030a23
    PIXMAN_OP_OVER,
Packit 030a23
    PIXMAN_OP_ADD,
Packit 030a23
    PIXMAN_OP_CLEAR,
Packit 030a23
    PIXMAN_OP_SRC,
Packit 030a23
    PIXMAN_OP_DST,
Packit 030a23
    PIXMAN_OP_OVER,
Packit 030a23
    PIXMAN_OP_OVER_REVERSE,
Packit 030a23
    PIXMAN_OP_IN,
Packit 030a23
    PIXMAN_OP_IN_REVERSE,
Packit 030a23
    PIXMAN_OP_OUT,
Packit 030a23
    PIXMAN_OP_OUT_REVERSE,
Packit 030a23
    PIXMAN_OP_ATOP,
Packit 030a23
    PIXMAN_OP_ATOP_REVERSE,
Packit 030a23
    PIXMAN_OP_XOR,
Packit 030a23
    PIXMAN_OP_ADD
Packit 030a23
};
Packit 030a23
Packit 030a23
enum
Packit 030a23
{
Packit 030a23
    ALLOW_CLIPPED		= (1 << 0),
Packit 030a23
    ALLOW_ALPHA_MAP		= (1 << 1),
Packit 030a23
    ALLOW_SOURCE_CLIPPING	= (1 << 2),
Packit 030a23
    ALLOW_REPEAT		= (1 << 3),
Packit 030a23
    ALLOW_SOLID			= (1 << 4),
Packit 030a23
    ALLOW_FENCED_MEMORY		= (1 << 5),
Packit 030a23
};
Packit 030a23
Packit 030a23
static void
Packit 030a23
destroy_fenced (pixman_image_t *image, void *data)
Packit 030a23
{
Packit 030a23
    fence_free (data);
Packit 030a23
}
Packit 030a23
Packit 030a23
static void
Packit 030a23
destroy_malloced (pixman_image_t *image, void *data)
Packit 030a23
{
Packit 030a23
    free (data);
Packit 030a23
}
Packit 030a23
Packit 030a23
static pixman_format_code_t
Packit 030a23
random_format (const pixman_format_code_t *formats)
Packit 030a23
{
Packit 030a23
    int i;
Packit 030a23
    i = 0;
Packit 030a23
    while (formats[i] != PIXMAN_null)
Packit 030a23
	++i;
Packit 030a23
    return formats[prng_rand_n (i)];
Packit 030a23
}
Packit 030a23
Packit 030a23
static pixman_image_t *
Packit 030a23
create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
Packit 030a23
{
Packit 030a23
    int width, height;
Packit 030a23
    pixman_image_t *image;
Packit 030a23
    pixman_format_code_t format;
Packit 030a23
    uint32_t *data;
Packit 030a23
    int bpp;
Packit 030a23
    int stride;
Packit 030a23
    int i;
Packit 030a23
    pixman_image_destroy_func_t destroy;
Packit 030a23
Packit 030a23
    if ((flags & ALLOW_SOLID) && prng_rand_n (4) == 0)
Packit 030a23
    {
Packit 030a23
	pixman_color_t color;
Packit 030a23
Packit 030a23
	color.alpha = prng_rand();
Packit 030a23
	color.red = prng_rand();
Packit 030a23
	color.green = prng_rand();
Packit 030a23
	color.blue = prng_rand();
Packit 030a23
Packit 030a23
	return pixman_image_create_solid_fill (&color;;
Packit 030a23
    }
Packit 030a23
Packit 030a23
    width = prng_rand_n (max_size) + 1;
Packit 030a23
    height = prng_rand_n (max_size) + 1;
Packit 030a23
    format = random_format (formats);
Packit 030a23
Packit 030a23
    bpp = PIXMAN_FORMAT_BPP (format);
Packit 030a23
    stride = (width * bpp + 7) / 8 + prng_rand_n (17);
Packit 030a23
    stride = (stride + 3) & ~3;
Packit 030a23
Packit 030a23
    if (prng_rand_n (64) == 0)
Packit 030a23
    {
Packit 030a23
	if (!(data = (uint32_t *)make_random_bytes (stride * height)))
Packit 030a23
	{
Packit 030a23
	    fprintf (stderr, "Out of memory\n");
Packit 030a23
	    abort ();
Packit 030a23
	}
Packit 030a23
	destroy = destroy_fenced;
Packit 030a23
    }
Packit 030a23
    else
Packit 030a23
    {
Packit 030a23
	data = malloc (stride * height);
Packit 030a23
	prng_randmemset (data, height * stride, 0);
Packit 030a23
	destroy = destroy_malloced;
Packit 030a23
    }
Packit 030a23
Packit 030a23
    image = pixman_image_create_bits (format, width, height, data, stride);
Packit 030a23
    pixman_image_set_destroy_function (image, destroy, data);
Packit 030a23
Packit 030a23
    if ((flags & ALLOW_CLIPPED) && prng_rand_n (8) == 0)
Packit 030a23
    {
Packit 030a23
	pixman_box16_t clip_boxes[8];
Packit 030a23
	pixman_region16_t clip;
Packit 030a23
	int n = prng_rand_n (8) + 1;
Packit 030a23
Packit 030a23
	for (i = 0; i < n; i++)
Packit 030a23
	{
Packit 030a23
	    clip_boxes[i].x1 = prng_rand_n (width);
Packit 030a23
	    clip_boxes[i].y1 = prng_rand_n (height);
Packit 030a23
	    clip_boxes[i].x2 =
Packit 030a23
		clip_boxes[i].x1 + prng_rand_n (width - clip_boxes[i].x1);
Packit 030a23
	    clip_boxes[i].y2 =
Packit 030a23
		clip_boxes[i].y1 + prng_rand_n (height - clip_boxes[i].y1);
Packit 030a23
	}
Packit 030a23
Packit 030a23
	pixman_region_init_rects (&clip, clip_boxes, n);
Packit 030a23
	pixman_image_set_clip_region (image, &clip);
Packit 030a23
	pixman_region_fini (&clip);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    if ((flags & ALLOW_SOURCE_CLIPPING) && prng_rand_n (4) == 0)
Packit 030a23
    {
Packit 030a23
	pixman_image_set_source_clipping (image, TRUE);
Packit 030a23
	pixman_image_set_has_client_clip (image, TRUE);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    if ((flags & ALLOW_ALPHA_MAP) && prng_rand_n (16) == 0)
Packit 030a23
    {
Packit 030a23
	pixman_image_t *alpha_map;
Packit 030a23
	int alpha_x, alpha_y;
Packit 030a23
Packit 030a23
	alpha_x = prng_rand_n (width);
Packit 030a23
	alpha_y = prng_rand_n (height);
Packit 030a23
	alpha_map =
Packit 030a23
	    create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID)));
Packit 030a23
	pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
Packit 030a23
	pixman_image_unref (alpha_map);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    if ((flags & ALLOW_REPEAT) && prng_rand_n (2) == 0)
Packit 030a23
	pixman_image_set_repeat (image, prng_rand_n (4));
Packit 030a23
Packit 030a23
    image_endian_swap (image);
Packit 030a23
Packit 030a23
    return image;
Packit 030a23
}
Packit 030a23
Packit 030a23
#define KEY1(p) ((void *)(((uintptr_t)p) ^ (0xa7e23dfaUL)))
Packit 030a23
#define KEY2(p) ((void *)(((uintptr_t)p) ^ (0xabcd9876UL)))
Packit 030a23
Packit 030a23
#define MAX_GLYPHS 32
Packit 030a23
Packit 030a23
uint32_t
Packit 030a23
test_glyphs (int testnum, int verbose)
Packit 030a23
{
Packit 030a23
    pixman_image_t *glyph_images[MAX_GLYPHS];
Packit 030a23
    pixman_glyph_t glyphs[4 * MAX_GLYPHS];
Packit 030a23
    uint32_t crc32 = 0;
Packit 030a23
    pixman_image_t *source, *dest;
Packit 030a23
    int n_glyphs, i;
Packit 030a23
    pixman_glyph_cache_t *cache;
Packit 030a23
Packit 030a23
    prng_srand (testnum);
Packit 030a23
Packit 030a23
    cache = pixman_glyph_cache_create ();
Packit 030a23
Packit 030a23
    source = create_image (300, formats,
Packit 030a23
			   ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
Packit 030a23
			   ALLOW_SOURCE_CLIPPING |
Packit 030a23
			   ALLOW_REPEAT | ALLOW_SOLID);
Packit 030a23
Packit 030a23
    dest = create_image (128, formats,
Packit 030a23
			 ALLOW_CLIPPED | ALLOW_ALPHA_MAP |
Packit 030a23
			 ALLOW_SOURCE_CLIPPING);
Packit 030a23
Packit 030a23
    pixman_glyph_cache_freeze (cache);
Packit 030a23
Packit 030a23
    n_glyphs = prng_rand_n (MAX_GLYPHS);
Packit 030a23
    for (i = 0; i < n_glyphs; ++i)
Packit 030a23
	glyph_images[i] = create_image (32, glyph_formats, 0);
Packit 030a23
Packit 030a23
    for (i = 0; i < 4 * n_glyphs; ++i)
Packit 030a23
    {
Packit 030a23
	int g = prng_rand_n (n_glyphs);
Packit 030a23
	pixman_image_t *glyph_img = glyph_images[g];
Packit 030a23
	void *key1 = KEY1 (glyph_img);
Packit 030a23
	void *key2 = KEY2 (glyph_img);
Packit 030a23
	const void *glyph;
Packit 030a23
Packit 030a23
	if (!(glyph = pixman_glyph_cache_lookup (cache, key1, key2)))
Packit 030a23
	{
Packit 030a23
	    glyph =
Packit 030a23
		pixman_glyph_cache_insert (cache, key1, key2, 5, 8, glyph_img);
Packit 030a23
	}
Packit 030a23
Packit 030a23
	glyphs[i].glyph = glyph;
Packit 030a23
	glyphs[i].x = prng_rand_n (128);
Packit 030a23
	glyphs[i].y = prng_rand_n (128);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    if (prng_rand_n (2) == 0)
Packit 030a23
    {
Packit 030a23
	int src_x = prng_rand_n (300) - 150;
Packit 030a23
	int src_y = prng_rand_n (300) - 150;
Packit 030a23
	int mask_x = prng_rand_n (64) - 32;
Packit 030a23
	int mask_y = prng_rand_n (64) - 32;
Packit 030a23
	int dest_x = prng_rand_n (64) - 32;
Packit 030a23
	int dest_y = prng_rand_n (64) - 32;
Packit 030a23
	int width = prng_rand_n (64);
Packit 030a23
	int height = prng_rand_n (64);
Packit 030a23
	pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
Packit 030a23
	pixman_format_code_t format = random_format (glyph_formats);
Packit 030a23
Packit 030a23
	pixman_composite_glyphs (
Packit 030a23
	    op,
Packit 030a23
	    source, dest, format,
Packit 030a23
	    src_x, src_y,
Packit 030a23
	    mask_x, mask_y,
Packit 030a23
	    dest_x, dest_y,
Packit 030a23
	    width, height,
Packit 030a23
	    cache, 4 * n_glyphs, glyphs);
Packit 030a23
    }
Packit 030a23
    else
Packit 030a23
    {
Packit 030a23
	pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
Packit 030a23
	int src_x = prng_rand_n (300) - 150;
Packit 030a23
	int src_y = prng_rand_n (300) - 150;
Packit 030a23
	int dest_x = prng_rand_n (64) - 32;
Packit 030a23
	int dest_y = prng_rand_n (64) - 32;
Packit 030a23
Packit 030a23
	pixman_composite_glyphs_no_mask (
Packit 030a23
	    op, source, dest,
Packit 030a23
	    src_x, src_y,
Packit 030a23
	    dest_x, dest_y,
Packit 030a23
	    cache, 4 * n_glyphs, glyphs);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    pixman_glyph_cache_thaw (cache);
Packit 030a23
Packit 030a23
    for (i = 0; i < n_glyphs; ++i)
Packit 030a23
    {
Packit 030a23
	pixman_image_t *img = glyph_images[i];
Packit 030a23
	void *key1, *key2;
Packit 030a23
Packit 030a23
	key1 = KEY1 (img);
Packit 030a23
	key2 = KEY2 (img);
Packit 030a23
Packit 030a23
	pixman_glyph_cache_remove (cache, key1, key2);
Packit 030a23
	pixman_image_unref (glyph_images[i]);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    crc32 = compute_crc32_for_image (0, dest);
Packit 030a23
Packit 030a23
    pixman_image_unref (source);
Packit 030a23
    pixman_image_unref (dest);
Packit 030a23
Packit 030a23
    pixman_glyph_cache_destroy (cache);
Packit 030a23
Packit 030a23
    return crc32;
Packit 030a23
}
Packit 030a23
Packit 030a23
int
Packit 030a23
main (int argc, const char *argv[])
Packit 030a23
{
Packit 030a23
    return fuzzer_test_main ("glyph", 30000,	
Packit 030a23
			     0xFA478A79,
Packit 030a23
			     test_glyphs, argc, argv);
Packit 030a23
}