Exemplo n.º 1
0
static pixman_image_t *
create_image (pixman_image_t **clone)
{
    pixman_format_code_t format = RANDOM_ELT (formats);
    pixman_image_t *image;
    int width = prng_rand_n (MAX_WIDTH);
    int height = prng_rand_n (MAX_HEIGHT);
    int stride = ((width * (PIXMAN_FORMAT_BPP (format) / 8)) + 3) & ~3;
    uint32_t *bytes = malloc (stride * height);

    prng_randmemset (bytes, stride * height, RANDMEMSET_MORE_00_AND_FF);

    image = pixman_image_create_bits (
        format, width, height, bytes, stride);

    pixman_image_set_destroy_function (image, free_bits, NULL);

    assert (image);

    if (clone)
    {
        uint32_t *bytes_dup = malloc (stride * height);

        memcpy (bytes_dup, bytes, stride * height);

        *clone = pixman_image_create_bits (
            format, width, height, bytes_dup, stride);

        pixman_image_set_destroy_function (*clone, free_bits, NULL);
    }
    
    return image;
}
Exemplo n.º 2
0
static pixman_image_t *
load_jpeg(FILE *fp)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	pixman_image_t *pixman_image = NULL;
	unsigned int i;
	int stride, first;
	JSAMPLE *data, *rows[4];
	jmp_buf env;

	cinfo.err = jpeg_std_error(&jerr);
	jerr.error_exit = error_exit;
	cinfo.client_data = env;
	if (setjmp(env))
		return NULL;

	jpeg_create_decompress(&cinfo);

	jpeg_stdio_src(&cinfo, fp);

	jpeg_read_header(&cinfo, TRUE);

	cinfo.out_color_space = JCS_RGB;
	jpeg_start_decompress(&cinfo);

	stride = cinfo.output_width * 4;
	data = malloc(stride * cinfo.output_height);
	if (data == NULL) {
		fprintf(stderr, "couldn't allocate image data\n");
		return NULL;
	}

	while (cinfo.output_scanline < cinfo.output_height) {
		first = cinfo.output_scanline;
		for (i = 0; i < ARRAY_LENGTH(rows); i++)
			rows[i] = data + (first + i) * stride;

		jpeg_read_scanlines(&cinfo, rows, ARRAY_LENGTH(rows));
		for (i = 0; first + i < cinfo.output_scanline; i++)
			swizzle_row(rows[i], cinfo.output_width);
	}

	jpeg_finish_decompress(&cinfo);

	jpeg_destroy_decompress(&cinfo);

	pixman_image = pixman_image_create_bits(PIXMAN_a8r8g8b8,
					cinfo.output_width,
					cinfo.output_height,
					(uint32_t *) data, stride);

	pixman_image_set_destroy_function(pixman_image,
				pixman_image_destroy_func, data);

	return pixman_image;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
static PixmanData *
pixman_image_add_data(pixman_image_t *image)
{
    PixmanData *data;

    data = (PixmanData *)pixman_image_get_destroy_data(image);
    if (data == NULL) {
        data = (PixmanData *)calloc(1, sizeof(PixmanData));
        if (data == NULL) {
            spice_error("out of memory");
        }
        pixman_image_set_destroy_function(image,
                                          release_data,
                                          data);
    }

    return data;
}
Exemplo n.º 5
0
void PixmanBitmap::Init(int width, int height, void* data, int pitch, bool destroy) {
	if (!pitch)
		pitch = width * bytes();

	bitmap = pixman_image_create_bits(pixman_format, width, height, (uint32_t*) data, pitch);

	if (bitmap == NULL) {
		Output::Error("Couldn't create %dx%d image.\n", width, height);
	}

	if (format.bits == 8) {
		initialize_palette();
		pixman_image_set_indexed(bitmap, &palette);
	}

	if (data != NULL && destroy)
		pixman_image_set_destroy_function(bitmap, destroy_func, data);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
/*
 * 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;
}
Exemplo n.º 8
0
static cairo_surface_t *
_get_image (cairo_xcb_surface_t		 *surface,
	    cairo_bool_t		  use_shm,
	    int x, int y,
	    int width, int height)
{
    cairo_surface_t *image;
    cairo_xcb_connection_t *connection;
    xcb_get_image_reply_t *reply;
    cairo_int_status_t status;

    assert (surface->fallback == NULL);
    assert (x >= 0);
    assert (y >= 0);
    assert (x + width <= surface->width);
    assert (y + height <= surface->height);

    if (surface->deferred_clear) {
	image =
	    _cairo_image_surface_create_with_pixman_format (NULL,
							    surface->pixman_format,
							    width, height,
							    0);
	if (surface->deferred_clear_color.alpha_short > 0x00ff) {
	    cairo_solid_pattern_t solid;

	    _cairo_pattern_init_solid (&solid, &surface->deferred_clear_color);
	    status = _cairo_surface_paint (image,
					   CAIRO_OPERATOR_SOURCE,
					   &solid.base,
					   NULL);
	    if (unlikely (status)) {
		cairo_surface_destroy (image);
		image = _cairo_surface_create_in_error (status);
	    }
	}
	return image;
    }

    connection = surface->connection;

    status = _cairo_xcb_connection_acquire (connection);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    if (use_shm) {
	image = _get_shm_image (surface, x, y, width, height);
	if (image) {
	    if (image->status) {
		_cairo_xcb_connection_release (connection);
		return image;
	    }
	    cairo_surface_destroy (image);
	}
    }

    status = _cairo_xcb_connection_get_image (connection,
					      surface->drawable,
					      x, y,
					      width, height,
					      &reply);
    if (unlikely (status))
	goto FAIL;

    if (reply == NULL && ! surface->owns_pixmap) {
	/* xcb_get_image_t from a window is dangerous because it can
	 * produce errors if the window is unmapped or partially
	 * outside the screen. We could check for errors and
	 * retry, but to keep things simple, we just create a
	 * temporary pixmap
	 *
	 * If we hit this fallback too often, we should remember so and
	 * skip the round-trip from the above GetImage request,
	 * similar to what cairo-xlib does.
	 */
	xcb_pixmap_t pixmap;
	xcb_gcontext_t gc;

	gc = _cairo_xcb_screen_get_gc (surface->screen,
				       surface->drawable,
				       surface->depth);
	pixmap = _cairo_xcb_connection_create_pixmap (connection,
						      surface->depth,
						      surface->drawable,
						      width, height);

	/* XXX IncludeInferiors? */
	_cairo_xcb_connection_copy_area (connection,
					 surface->drawable,
					 pixmap, gc,
					 x, y,
					 0, 0,
					 width, height);

	_cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc);

	status = _cairo_xcb_connection_get_image (connection,
						  pixmap,
						  0, 0,
						  width, height,
						  &reply);
	_cairo_xcb_connection_free_pixmap (connection, pixmap);

	if (unlikely (status))
	    goto FAIL;
    }

    if (unlikely (reply == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto FAIL;
    }

    /* XXX byte swap */
    /* XXX format conversion */
    assert (reply->depth == surface->depth);

    image = _cairo_image_surface_create_with_pixman_format
	(xcb_get_image_data (reply),
	 surface->pixman_format,
	 width, height,
	 CAIRO_STRIDE_FOR_WIDTH_BPP (width,
				     PIXMAN_FORMAT_BPP (surface->pixman_format)));
    status = image->status;
    if (unlikely (status)) {
	free (reply);
	goto FAIL;
    }

    /* XXX */
    pixman_image_set_destroy_function (((cairo_image_surface_t *)image)->pixman_image, _destroy_image, reply);

    _cairo_xcb_connection_release (connection);

    return image;

FAIL:
    _cairo_xcb_connection_release (connection);
    return _cairo_surface_create_in_error (status);
}
Exemplo n.º 9
0
static pixman_image_t *
load_png(FILE *fp)
{
	png_struct *png;
	png_info *info;
	png_byte *data = NULL;
	png_byte **row_pointers = NULL;
	png_uint_32 width, height;
	int depth, color_type, interlace, stride;
	unsigned int i;
	pixman_image_t *pixman_image = NULL;

	png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
				     png_error_callback, NULL);
	if (!png)
		return NULL;

	info = png_create_info_struct(png);
	if (!info) {
		png_destroy_read_struct(&png, &info, NULL);
		return NULL;
	}

	if (setjmp(png_jmpbuf(png))) {
		if (data)
			free(data);
		if (row_pointers)
			free(row_pointers);
		png_destroy_read_struct(&png, &info, NULL);
		return NULL;
	}

	png_set_read_fn(png, fp, read_func);
	png_read_info(png, info);
	png_get_IHDR(png, info,
		     &width, &height, &depth,
		     &color_type, &interlace, NULL, NULL);

	if (color_type == PNG_COLOR_TYPE_PALETTE)
		png_set_palette_to_rgb(png);

	if (color_type == PNG_COLOR_TYPE_GRAY)
		png_set_expand_gray_1_2_4_to_8(png);

	if (png_get_valid(png, info, PNG_INFO_tRNS))
		png_set_tRNS_to_alpha(png);

	if (depth == 16)
		png_set_strip_16(png);

	if (depth < 8)
		png_set_packing(png);

	if (color_type == PNG_COLOR_TYPE_GRAY ||
	    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
		png_set_gray_to_rgb(png);

	if (interlace != PNG_INTERLACE_NONE)
		png_set_interlace_handling(png);

	png_set_filler(png, 0xff, PNG_FILLER_AFTER);
	png_set_read_user_transform_fn(png, premultiply_data);
	png_read_update_info(png, info);
	png_get_IHDR(png, info,
		     &width, &height, &depth,
		     &color_type, &interlace, NULL, NULL);


	stride = stride_for_width(width);
	data = malloc(stride * height);
	if (!data) {
		png_destroy_read_struct(&png, &info, NULL);
		return NULL;
	}

	row_pointers = malloc(height * sizeof row_pointers[0]);
	if (row_pointers == NULL) {
		free(data);
		png_destroy_read_struct(&png, &info, NULL);
		return NULL;
	}

	for (i = 0; i < height; i++)
		row_pointers[i] = &data[i * stride];

	png_read_image(png, row_pointers);
	png_read_end(png, info);

	free(row_pointers);
	png_destroy_read_struct(&png, &info, NULL);

	pixman_image = pixman_image_create_bits(PIXMAN_a8r8g8b8,
				width, height, (uint32_t *) data, stride);

	pixman_image_set_destroy_function(pixman_image,
				pixman_image_destroy_func, data);

	return pixman_image;
}
Exemplo n.º 10
0
static void
set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
                     int *xoff, int *yoff, Bool is_alpha_map)
{
    pixman_repeat_t repeat;
    pixman_filter_t filter;

    if (pict->transform) {
        /* For source images, adjust the transform to account
         * for the drawable offset within the pixman image,
         * then set the offset to 0 as it will be used
         * to compute positions within the transformed image.
         */
        if (!has_clip) {
            struct pixman_transform adjusted;

            adjusted = *pict->transform;
            pixman_transform_translate(&adjusted,
                                       NULL,
                                       pixman_int_to_fixed(*xoff),
                                       pixman_int_to_fixed(*yoff));
            pixman_image_set_transform(image, &adjusted);
            *xoff = 0;
            *yoff = 0;
        }
        else
            pixman_image_set_transform(image, pict->transform);
    }

    switch (pict->repeatType) {
    default:
    case RepeatNone:
        repeat = PIXMAN_REPEAT_NONE;
        break;

    case RepeatPad:
        repeat = PIXMAN_REPEAT_PAD;
        break;

    case RepeatNormal:
        repeat = PIXMAN_REPEAT_NORMAL;
        break;

    case RepeatReflect:
        repeat = PIXMAN_REPEAT_REFLECT;
        break;
    }

    pixman_image_set_repeat(image, repeat);

    /* Fetch alpha map unless 'pict' is being used
     * as the alpha map for this operation
     */
    if (pict->alphaMap && !is_alpha_map) {
        int alpha_xoff, alpha_yoff;
        pixman_image_t *alpha_map =
            image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff,
                                     &alpha_yoff, TRUE);

        pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x,
                                   pict->alphaOrigin.y);

        free_pixman_pict(pict->alphaMap, alpha_map);
    }

    pixman_image_set_component_alpha(image, pict->componentAlpha);

    switch (pict->filter) {
    default:
    case PictFilterNearest:
    case PictFilterFast:
        filter = PIXMAN_FILTER_NEAREST;
        break;

    case PictFilterBilinear:
    case PictFilterGood:
        filter = PIXMAN_FILTER_BILINEAR;
        break;

    case PictFilterConvolution:
        filter = PIXMAN_FILTER_CONVOLUTION;
        break;
    }

    if (pict->pDrawable)
        pixman_image_set_destroy_function(image, &image_destroy,
                                          pict->pDrawable);

    pixman_image_set_filter(image, filter,
                            (pixman_fixed_t *) pict->filter_params,
                            pict->filter_nparams);
    pixman_image_set_source_clipping(image, TRUE);
}
Exemplo n.º 11
0
static cairo_status_t
_get_image (cairo_xcb_surface_t		 *surface,
	    cairo_bool_t		  use_shm,
	    cairo_image_surface_t	**image_out)
{
    cairo_image_surface_t *image;
    cairo_xcb_connection_t *connection;
    xcb_get_image_reply_t *reply;
    cairo_status_t status;

    if (surface->base.is_clear || surface->deferred_clear) {
	image = (cairo_image_surface_t *)
	    _cairo_image_surface_create_with_pixman_format (NULL,
							    surface->pixman_format,
							    surface->width,
							    surface->height,
							    0);
	*image_out = image;
	return image->base.status;
    }

    connection = surface->connection;

    status = _cairo_xcb_connection_acquire (connection);
    if (unlikely (status))
	return status;

    status = _cairo_xcb_connection_take_socket (connection);
    if (unlikely (status))
	goto FAIL;

    if (use_shm) {
	status = _get_shm_image (surface, image_out);
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    goto FAIL;
    }

    if (surface->use_pixmap == 0) {
	status = _cairo_xcb_connection_get_image (connection,
						  surface->drawable,
						  0, 0,
						  surface->width,
						  surface->height,
						  &reply);
	if (unlikely (status))
	    goto FAIL;
    } else {
	surface->use_pixmap--;
	reply = NULL;
    }

    if (reply == NULL && ! surface->owns_pixmap) {
	/* xcb_get_image_t from a window is dangerous because it can
	 * produce errors if the window is unmapped or partially
	 * outside the screen. We could check for errors and
	 * retry, but to keep things simple, we just create a
	 * temporary pixmap
	 */
	xcb_pixmap_t pixmap;
	xcb_gcontext_t gc;

	gc = _cairo_xcb_screen_get_gc (surface->screen,
				       surface->drawable,
				       surface->depth);
	pixmap = _cairo_xcb_connection_create_pixmap (connection,
						      surface->depth,
						      surface->drawable,
						      surface->width,
						      surface->height);

	/* XXX IncludeInferiors? */
	_cairo_xcb_connection_copy_area (connection,
					 surface->drawable,
					 pixmap, gc,
					 0, 0,
					 0, 0,
					 surface->width,
					 surface->height);

	_cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc);

	status = _cairo_xcb_connection_get_image (connection,
						  pixmap,
						  0, 0,
						  surface->width,
						  surface->height,
						  &reply);
	_cairo_xcb_connection_free_pixmap (connection, pixmap);

	if (unlikely (status))
	    goto FAIL;
    }

    if (unlikely (reply == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto FAIL;
    }

    /* XXX byte swap */
    /* XXX format conversion */
    assert (reply->depth == surface->depth);

    image = (cairo_image_surface_t *)
	_cairo_image_surface_create_with_pixman_format
	(xcb_get_image_data (reply),
	 surface->pixman_format,
	 surface->width,
	 surface->height,
	 CAIRO_STRIDE_FOR_WIDTH_BPP (surface->width,
				     PIXMAN_FORMAT_BPP (surface->pixman_format)));
    status = image->base.status;
    if (unlikely (status)) {
	free (reply);
	goto FAIL;
    }

    assert (xcb_get_image_data_length (reply) == image->height * image->stride);

    pixman_image_set_destroy_function (image->pixman_image, _destroy_image, reply);

    _cairo_xcb_connection_release (connection);

    /* synchronisation point */
    surface->marked_dirty = FALSE;

    *image_out = image;
    return CAIRO_STATUS_SUCCESS;

FAIL:
    _cairo_xcb_connection_release (connection);
    return status;
}
Exemplo n.º 12
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;
}