示例#1
0
/* Create random image for testing purposes */
static pixman_image_t *
create_random_image (pixman_format_code_t *allowed_formats,
		     int                   max_width,
		     int                   max_height,
		     int                   max_extra_stride,
		     pixman_format_code_t *used_fmt)
{
    int n = 0, i, width, height, stride;
    pixman_format_code_t fmt;
    uint32_t *buf;
    pixman_image_t *img;

    while (allowed_formats[n] != PIXMAN_null)
	n++;

    if (n > N_MOST_LIKELY_FORMATS && lcg_rand_n (4) != 0)
	n = N_MOST_LIKELY_FORMATS;
    fmt = allowed_formats[lcg_rand_n (n)];

    width = lcg_rand_n (max_width) + 1;
    height = lcg_rand_n (max_height) + 1;
    stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
	lcg_rand_n (max_extra_stride + 1);
    stride = (stride + 3) & ~3;

    /* do the allocation */
    buf = aligned_malloc (64, stride * height);

    /* initialize image with random data */
    for (i = 0; i < stride * height; i++)
    {
	/* generation is biased to having more 0 or 255 bytes as
	 * they are more likely to be special-cased in code
	 */
	*((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
	    (lcg_rand_n (2) ? 0 : 255);
    }

    img = pixman_image_create_bits (fmt, width, height, buf, stride);

    if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
    {
	pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
    }
    else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
    {
	pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
    }

    image_endian_swap (img);

    if (used_fmt) *used_fmt = fmt;
    return img;
}
示例#2
0
/* Free random image, and optionally update crc32 based on its data */
static uint32_t
free_random_image (uint32_t initcrc,
		   pixman_image_t *img,
		   pixman_format_code_t fmt)
{
    uint32_t crc32 = 0;
    int stride = pixman_image_get_stride (img);
    uint32_t *data = pixman_image_get_data (img);
    int height = pixman_image_get_height (img);

    if (fmt != PIXMAN_null)
    {
	/* mask unused 'x' part */
	if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
	    PIXMAN_FORMAT_DEPTH (fmt) != 0)
	{
	    int i;
	    uint32_t *data = pixman_image_get_data (img);
	    uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;

	    if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
		PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
	    {
		mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
	    }

	    for (i = 0; i < 32; i++)
		mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));

	    for (i = 0; i < stride * height / 4; i++)
		data[i] &= mask;
	}

	/* swap endiannes in order to provide identical results on both big
	 * and litte endian systems
	 */
	image_endian_swap (img);
	crc32 = compute_crc32 (initcrc, data, stride * height);
    }

    pixman_image_unref (img);
    free (data);

    return crc32;
}
static pixman_image_t *
make_image (void)
{
    pixman_format_code_t format = RANDOM_FORMAT();
    uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
    pixman_image_t *image;

    prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0);

    image = pixman_image_create_bits (
	format, WIDTH, HEIGHT, bytes, WIDTH * 4);

    pixman_image_set_transform (image, RANDOM_TRANSFORM());
    pixman_image_set_destroy_function (image, on_destroy, bytes);
    pixman_image_set_repeat (image, PIXMAN_REPEAT_NORMAL);

    image_endian_swap (image);

    return image;
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int      testnum,
		int      verbose)
{
    int                i;
    pixman_image_t *   src_img;
    pixman_image_t *   dst_img;
    pixman_region16_t  clip;
    int                dst_width, dst_height;
    int                dst_stride;
    int                dst_x, dst_y;
    int                dst_bpp;
    pixman_op_t        op;
    uint32_t *         dst_bits;
    uint32_t           crc32;
    pixman_format_code_t mask_format, dst_format;
    pixman_trapezoid_t *traps;
    int src_x, src_y;
    int n_traps;

    static pixman_color_t colors[] =
    {
	{ 0xffff, 0xffff, 0xffff, 0xffff },
	{ 0x0000, 0x0000, 0x0000, 0x0000 },
	{ 0xabcd, 0xabcd, 0x0000, 0xabcd },
	{ 0x0000, 0x0000, 0x0000, 0xffff },
	{ 0x0101, 0x0101, 0x0101, 0x0101 },
	{ 0x7777, 0x6666, 0x5555, 0x9999 },
    };
    
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    lcg_srand (testnum);

    op = RANDOM_ELT (operators);
    mask_format = RANDOM_ELT (mask_formats);

    /* Create source image */
    
    if (lcg_rand_n (4) == 0)
    {
	src_img = pixman_image_create_solid_fill (
	    &(colors[lcg_rand_n (ARRAY_LENGTH (colors))]));

	src_x = 10;
	src_y = 234;
    }
    else
    {
	pixman_format_code_t src_format = RANDOM_ELT(formats);
	int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
	int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
	int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
	int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
	uint32_t *bits;

	src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
	src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);

	src_stride = (src_stride + 3) & ~3;
	
	bits = (uint32_t *)make_random_bytes (src_stride * src_height);

	src_img = pixman_image_create_bits (
	    src_format, src_width, src_height, bits, src_stride);

	pixman_image_set_destroy_function (src_img, destroy_bits, bits);

	if (lcg_rand_n (8) == 0)
	{
	    pixman_box16_t clip_boxes[2];
	    int            n = lcg_rand_n (2) + 1;
	    
	    for (i = 0; i < n; i++)
	    {
		clip_boxes[i].x1 = lcg_rand_n (src_width);
		clip_boxes[i].y1 = lcg_rand_n (src_height);
		clip_boxes[i].x2 =
		    clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
		clip_boxes[i].y2 =
		    clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
		
		if (verbose)
		{
		    printf ("source clip box: [%d,%d-%d,%d]\n",
			    clip_boxes[i].x1, clip_boxes[i].y1,
			    clip_boxes[i].x2, clip_boxes[i].y2);
		}
	    }
	    
	    pixman_region_init_rects (&clip, clip_boxes, n);
	    pixman_image_set_clip_region (src_img, &clip);
	    pixman_image_set_source_clipping (src_img, 1);
	    pixman_region_fini (&clip);
	}

	image_endian_swap (src_img);
    }

    /* Create destination image */
    {
	dst_format = RANDOM_ELT(formats);
	dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
	dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
	dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
	dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
	dst_stride = (dst_stride + 3) & ~3;
	
	dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);

	dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
	dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
	
	dst_img = pixman_image_create_bits (
	    dst_format, dst_width, dst_height, dst_bits, dst_stride);

	image_endian_swap (dst_img);
    }

    /* Create traps */
    {
	int i;

	n_traps = lcg_rand_n (25);
	traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));

	for (i = 0; i < n_traps; ++i)
	{
	    pixman_trapezoid_t *t = &(traps[i]);
	    
	    t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2;
	    t->bottom = t->top + random_fixed (MAX_DST_HEIGHT);
	    t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
	    t->left.p1.y = t->top - random_fixed (50);
	    t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2;
	    t->left.p2.y = t->bottom + random_fixed (50);
	    t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH);
	    t->right.p1.y = t->top - random_fixed (50);
	    t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH);
	    t->right.p2.y = t->bottom - random_fixed (50);
	}
    }
    
    if (lcg_rand_n (8) == 0)
    {
	pixman_box16_t clip_boxes[2];
	int            n = lcg_rand_n (2) + 1;
	for (i = 0; i < n; i++)
	{
	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
	    clip_boxes[i].x2 =
		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
	    clip_boxes[i].y2 =
		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);

	    if (verbose)
	    {
		printf ("destination clip box: [%d,%d-%d,%d]\n",
		        clip_boxes[i].x1, clip_boxes[i].y1,
		        clip_boxes[i].x2, clip_boxes[i].y2);
	    }
	}
	pixman_region_init_rects (&clip, clip_boxes, n);
	pixman_image_set_clip_region (dst_img, &clip);
	pixman_region_fini (&clip);
    }

    pixman_composite_trapezoids (op, src_img, dst_img, mask_format,
				 src_x, src_y, dst_x, dst_y, n_traps, traps);

    if (dst_format == PIXMAN_x8r8g8b8)
    {
	/* ignore unused part */
	for (i = 0; i < dst_stride * dst_height / 4; i++)
	    dst_bits[i] &= 0xFFFFFF;
    }

    image_endian_swap (dst_img);

    if (verbose)
    {
	int j;
	
	for (i = 0; i < dst_height; i++)
	{
	    for (j = 0; j < dst_stride; j++)
		printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j));

	    printf ("\n");
	}
    }

    crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height);

    fence_free (dst_bits);
    
    pixman_image_unref (src_img);
    pixman_image_unref (dst_img);
    fence_free (traps);

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
/* Create random image for testing purposes */
static pixman_image_t *
create_random_image (pixman_format_code_t *allowed_formats,
		     int                   max_width,
		     int                   max_height,
		     int                   max_extra_stride,
		     pixman_format_code_t *used_fmt)
{
    int n = 0, width, height, stride;
    pixman_format_code_t fmt;
    uint32_t *buf;
    pixman_image_t *img;

    while (allowed_formats[n] != PIXMAN_null)
	n++;

    if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0)
	n = N_MOST_LIKELY_FORMATS;
    fmt = allowed_formats[prng_rand_n (n)];

    width = prng_rand_n (max_width) + 1;
    height = prng_rand_n (max_height) + 1;
    stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
	prng_rand_n (max_extra_stride + 1);
    stride = (stride + 3) & ~3;

    /* do the allocation */
    buf = aligned_malloc (64, stride * height);

    if (prng_rand_n (4) == 0)
    {
	/* uniform distribution */
	prng_randmemset (buf, stride * height, 0);
    }
    else
    {
	/* significantly increased probability for 0x00 and 0xFF */
	prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
    }

    /* test negative stride */
    if (prng_rand_n (4) == 0)
    {
	buf += (stride / 4) * (height - 1);
	stride = - stride;
    }
    
    img = pixman_image_create_bits (fmt, width, height, buf, stride);

    if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_COLOR)
    {
	pixman_image_set_indexed (img, &(rgb_palette[PIXMAN_FORMAT_BPP (fmt)]));
    }
    else if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_GRAY)
    {
	pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
    }

    if (prng_rand_n (16) == 0)
	pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0);

    image_endian_swap (img);

    if (used_fmt) *used_fmt = fmt;
    return img;
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int      testnum,
		int      verbose)
{
    int                i;
    pixman_image_t *   src_img;
    pixman_image_t *   dst_img;
    pixman_transform_t transform;
    pixman_region16_t  clip;
    int                src_width, src_height;
    int                dst_width, dst_height;
    int                src_stride, dst_stride;
    int                src_x, src_y;
    int                dst_x, dst_y;
    int                src_bpp;
    int                dst_bpp;
    int                w, h;
    pixman_fixed_t     scale_x = 65536, scale_y = 65536;
    pixman_fixed_t     translate_x = 0, translate_y = 0;
    int                op;
    int                repeat = 0;
    int                src_fmt, dst_fmt;
    uint32_t *         srcbuf;
    uint32_t *         dstbuf;
    uint32_t           crc32;

    lcg_srand (testnum);

    src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
    dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
    op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;

    src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
    src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
    dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
    dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
    src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
    dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;

    if (src_stride & 3)
	src_stride += 2;

    if (dst_stride & 3)
	dst_stride += 2;

    src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
    src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
    dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
    dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
    w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
    h = lcg_rand_n (dst_height * 3 / 2 - dst_y);

    srcbuf = (uint32_t *)malloc (src_stride * src_height);
    dstbuf = (uint32_t *)malloc (dst_stride * dst_height);

    for (i = 0; i < src_stride * src_height; i++)
	*((uint8_t *)srcbuf + i) = lcg_rand_n (256);

    for (i = 0; i < dst_stride * dst_height; i++)
	*((uint8_t *)dstbuf + i) = lcg_rand_n (256);

    src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;

    dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;

    src_img = pixman_image_create_bits (
        src_fmt, src_width, src_height, srcbuf, src_stride);

    dst_img = pixman_image_create_bits (
        dst_fmt, dst_width, dst_height, dstbuf, dst_stride);

    image_endian_swap (src_img, src_bpp * 8);
    image_endian_swap (dst_img, dst_bpp * 8);

    if (lcg_rand_n (8) > 0)
    {
	scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
	scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
	translate_x = lcg_rand_N (65536);
	translate_y = lcg_rand_N (65536);
	pixman_transform_init_scale (&transform, scale_x, scale_y);
	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
	pixman_image_set_transform (src_img, &transform);
    }

    switch (lcg_rand_n (4))
    {
    case 0:
	repeat = PIXMAN_REPEAT_NONE;
	break;

    case 1:
	repeat = PIXMAN_REPEAT_NORMAL;
	break;

    case 2:
	repeat = PIXMAN_REPEAT_PAD;
	break;

    case 3:
	repeat = PIXMAN_REPEAT_REFLECT;
	break;

    default:
        break;
    }
    pixman_image_set_repeat (src_img, repeat);

    if (lcg_rand_n (2))
	pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
    else
	pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);

    if (verbose)
    {
	printf ("src_fmt=%08X, dst_fmt=%08X\n", src_fmt, dst_fmt);
	printf ("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n",
	        op, scale_x, scale_y, repeat);
	printf ("translate_x=%d, translate_y=%d\n",
	        translate_x, translate_y);
	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
	        src_width, src_height, dst_width, dst_height);
	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
	        src_x, src_y, dst_x, dst_y);
	printf ("w=%d, h=%d\n", w, h);
    }

    if (lcg_rand_n (8) == 0)
    {
	pixman_box16_t clip_boxes[2];
	int            n = lcg_rand_n (2) + 1;

	for (i = 0; i < n; i++)
	{
	    clip_boxes[i].x1 = lcg_rand_n (src_width);
	    clip_boxes[i].y1 = lcg_rand_n (src_height);
	    clip_boxes[i].x2 =
		clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
	    clip_boxes[i].y2 =
		clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);

	    if (verbose)
	    {
		printf ("source clip box: [%d,%d-%d,%d]\n",
		        clip_boxes[i].x1, clip_boxes[i].y1,
		        clip_boxes[i].x2, clip_boxes[i].y2);
	    }
	}

	pixman_region_init_rects (&clip, clip_boxes, n);
	pixman_image_set_clip_region (src_img, &clip);
	pixman_image_set_source_clipping (src_img, 1);
	pixman_region_fini (&clip);
    }

    if (lcg_rand_n (8) == 0)
    {
	pixman_box16_t clip_boxes[2];
	int            n = lcg_rand_n (2) + 1;
	for (i = 0; i < n; i++)
	{
	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
	    clip_boxes[i].x2 =
		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
	    clip_boxes[i].y2 =
		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);

	    if (verbose)
	    {
		printf ("destination clip box: [%d,%d-%d,%d]\n",
		        clip_boxes[i].x1, clip_boxes[i].y1,
		        clip_boxes[i].x2, clip_boxes[i].y2);
	    }
	}
	pixman_region_init_rects (&clip, clip_boxes, n);
	pixman_image_set_clip_region (dst_img, &clip);
	pixman_region_fini (&clip);
    }

    pixman_image_composite (op, src_img, NULL, dst_img,
                            src_x, src_y, 0, 0, dst_x, dst_y, w, h);

    if (dst_fmt == PIXMAN_x8r8g8b8)
    {
	/* ignore unused part */
	for (i = 0; i < dst_stride * dst_height / 4; i++)
	    dstbuf[i] &= 0xFFFFFF;
    }

    image_endian_swap (dst_img, dst_bpp * 8);

    if (verbose)
    {
	int j;
	
	for (i = 0; i < dst_height; i++)
	{
	    for (j = 0; j < dst_stride; j++)
		printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));

	    printf ("\n");
	}
    }

    pixman_image_unref (src_img);
    pixman_image_unref (dst_img);

    crc32 = compute_crc32 (0, dstbuf, dst_stride * dst_height);
    free (srcbuf);
    free (dstbuf);
    return crc32;
}
示例#7
0
static pixman_image_t *
create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
{
    int width, height;
    pixman_image_t *image;
    pixman_format_code_t format;
    uint32_t *data;
    int bpp;
    int stride;
    int i;
    pixman_image_destroy_func_t destroy;

    if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0)
    {
	pixman_color_t color;

	color.alpha = lcg_rand_u32();
	color.red = lcg_rand_u32();
	color.green = lcg_rand_u32();
	color.blue = lcg_rand_u32();

	return pixman_image_create_solid_fill (&color);
    }

    width = lcg_rand_n (max_size) + 1;
    height = lcg_rand_n (max_size) + 1;
    format = random_format (formats);

    bpp = PIXMAN_FORMAT_BPP (format);
    stride = (width * bpp + 7) / 8 + lcg_rand_n (17);
    stride = (stride + 3) & ~3;

    if (lcg_rand_n (64) == 0)
    {
	if (!(data = (uint32_t *)make_random_bytes (stride * height)))
	{
	    fprintf (stderr, "Out of memory\n");
	    abort ();
	}
	destroy = destroy_fenced;
    }
    else
    {
	uint8_t *d8;

	data = malloc (stride * height);

	d8 = (uint8_t *)data;
	for (i = 0; i < height * stride; ++i)
	    d8[i] = lcg_rand_n (256);

	destroy = destroy_malloced;
    }

    image = pixman_image_create_bits (format, width, height, data, stride);
    pixman_image_set_destroy_function (image, destroy, data);

    if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0)
    {
	pixman_box16_t clip_boxes[8];
	pixman_region16_t clip;
	int n = lcg_rand_n (8) + 1;

	for (i = 0; i < n; i++)
	{
	    clip_boxes[i].x1 = lcg_rand_n (width);
	    clip_boxes[i].y1 = lcg_rand_n (height);
	    clip_boxes[i].x2 =
		clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1);
	    clip_boxes[i].y2 =
		clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1);
	}

	pixman_region_init_rects (&clip, clip_boxes, n);
	pixman_image_set_clip_region (image, &clip);
	pixman_region_fini (&clip);
    }

    if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0)
    {
	pixman_image_set_source_clipping (image, TRUE);
	pixman_image_set_has_client_clip (image, TRUE);
    }

    if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0)
    {
	pixman_image_t *alpha_map;
	int alpha_x, alpha_y;

	alpha_x = lcg_rand_n (width);
	alpha_y = lcg_rand_n (height);
	alpha_map =
	    create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID)));
	pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
	pixman_image_unref (alpha_map);
    }

    if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0)
	pixman_image_set_repeat (image, lcg_rand_n (4));

    image_endian_swap (image);

    return image;
}