예제 #1
0
static void
fill (pixman_image_t *image, uint32_t pixel)
{
    uint8_t *data = (uint8_t *)pixman_image_get_data (image);
    int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8;
    int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image);
    int i;

    switch (bytes_per_pixel)
    {
    case 4:
	for (i = 0; i < n_bytes / 4; ++i)
	    ((uint32_t *)data)[i] = pixel;
	break;

    case 2:
	pixel &= 0xffff;
	for (i = 0; i < n_bytes / 2; ++i)
	    ((uint16_t *)data)[i] = pixel;
	break;

    case 1:
	pixel &= 0xff;
	for (i = 0; i < n_bytes; ++i)
	    ((uint8_t *)data)[i] = pixel;
	break;

    default:
	assert (0);
	break;
    }
}
예제 #2
0
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
					      cairo_format_t  format)
{
    cairo_image_surface_t *surface;

    surface = malloc (sizeof (cairo_image_surface_t));
    if (surface == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return (cairo_surface_t*) &_cairo_surface_nil;
    }

    _cairo_surface_init (&surface->base, &cairo_image_surface_backend);

    surface->pixman_image = pixman_image;

    surface->format = format;
    surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->has_clip = FALSE;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    return &surface->base;
}
예제 #3
0
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
					      pixman_format_code_t	 pixman_format)
{
    cairo_image_surface_t *surface;

    surface = malloc (sizeof (cairo_image_surface_t));
    if (surface == NULL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base, &_cairo_image_surface_backend,
			 _cairo_content_from_pixman_format (pixman_format));

    surface->pixman_image = pixman_image;

    surface->pixman_format = pixman_format;
    surface->format = _cairo_format_from_pixman_format (pixman_format);
    surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->has_clip = FALSE;
    surface->transparency = CAIRO_IMAGE_UNKNOWN;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    return &surface->base;
}
예제 #4
0
파일: alphamap.c 프로젝트: aosm/X11libs
static void
on_destroy (pixman_image_t *image, void *data)
{
    uint32_t *bits = pixman_image_get_data (image);

    fence_free (bits);
}
예제 #5
0
struct texture_t * sw_render_alloc_texture(struct render_t * render, void * pixels, u32_t w, u32_t h, enum pixel_format_t format)
{
	struct texture_t * texture;
	pixman_image_t * img;
	u32_t pitch;

	if(!render)
		return NULL;

	if( (w <= 0) && (h <= 0) )
		return NULL;

	texture = (struct texture_t *)malloc(sizeof(struct texture_t));
	if(! texture)
		return NULL;

	switch(format)
	{
	case PIXEL_FORMAT_ARGB32:
		pitch = w * 4;
		break;
	case PIXEL_FORMAT_RGB24:
		pitch = w * 3;
		break;
	case PIXEL_FORMAT_A8:
		pitch = w * 1;
		break;
	case PIXEL_FORMAT_A1:
		pitch = (w + 7) / 8;
		break;
	case PIXEL_FORMAT_RGB16_565:
		pitch = w * 2;
		break;
	case PIXEL_FORMAT_RGB30:
		pitch = w * 4;
		break;
	default:
		pitch = w * 4;
		break;
	}
	pitch = (pitch + 0x3) & ~0x3;

	img = pixman_image_create_bits_no_clear(pixel_format_to_pixman_format_code(format), w, h, pixels, pitch);
	if(!img)
	{
		free(texture);
		return NULL;
	}

	texture->width = w;
	texture->height = h;
	texture->pitch = pitch;
	texture->format = format;
	texture->pixels = pixman_image_get_data(img);
	texture->priv = img;

	return texture;
}
예제 #6
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;
}
예제 #7
0
static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
{
    static const int blksize = 32;
    int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
    int dirty_top[blocks];
    int y, yoff, x, xoff, blk, bw;
    int bpp = surface_bytes_per_pixel(ssd->ds);
    uint8_t *guest, *mirror;

    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
        return;
    };

    if (ssd->surface == NULL) {
        ssd->surface = pixman_image_ref(ssd->ds->image);
        ssd->mirror  = qemu_pixman_mirror_create(ssd->ds->format,
                                                 ssd->ds->image);
    }

    for (blk = 0; blk < blocks; blk++) {
        dirty_top[blk] = -1;
    }

    guest = surface_data(ssd->ds);
    mirror = (void *)pixman_image_get_data(ssd->mirror);
    for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
        yoff = y * surface_stride(ssd->ds);
        for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
            xoff = x * bpp;
            blk = x / blksize;
            bw = MIN(blksize, ssd->dirty.right - x);
            if (memcmp(guest + yoff + xoff,
                       mirror + yoff + xoff,
                       bw * bpp) == 0) {
                if (dirty_top[blk] != -1) {
                    QXLRect update = {
                        .top    = dirty_top[blk],
                        .bottom = y,
                        .left   = x,
                        .right  = x + bw,
                    };
                    qemu_spice_create_one_update(ssd, &update);
                    dirty_top[blk] = -1;
                }
            } else {
                if (dirty_top[blk] == -1) {
                    dirty_top[blk] = y;
                }
            }
        }
    }
예제 #8
0
파일: vfs0050.c 프로젝트: Jack-Q/libfprint
static void process_image_data(struct fp_img_dev *dev, char **output, int *output_height)
{
    //pixman stuff taken from libfprint/pixman.c, adapted for my purposes.
    pixman_image_t *orig, *resized;
    pixman_transform_t transform;
    struct vfs0050_dev *vfs_dev = dev->priv;
    struct vfs0050_line *line, *calibration_line;
    char *buf = malloc(vfs_dev->scanbuf_idx);
    int lines = vfs_dev->scanbuf_idx / VFS0050_FRAME_SIZE;
    int i, x, sum, last_sum, diff;
    int new_height;
    //just grab one around middle, there should be 100
    calibration_line = (struct vfs0050_line *) ((char *) vfs_dev->calbuf + (50 * VFS0050_FRAME_SIZE));

    new_height = 0;
    for (i = 0; i < lines; i++) {
        line = (struct vfs0050_line *) ((char *) vfs_dev->scanbuf + (i * VFS0050_FRAME_SIZE));
        if (!is_noise(line))
            memcpy(buf + (new_height++ * VFS0050_IMG_WIDTH), line->row, VFS0050_IMG_WIDTH);
        else
            fp_dbg("removed noise at line: %d\n", i);
    }

    orig = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, (uint32_t *) buf, VFS0050_IMG_WIDTH);
    new_height *= VFS0050_SCALE_FACTOR; //scale for resized image
    resized = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, NULL, VFS0050_IMG_WIDTH);
    pixman_transform_init_identity(&transform);
    pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(1), pixman_double_to_fixed(0.2));
    pixman_image_set_transform(orig, &transform);
    pixman_image_set_filter(orig, PIXMAN_FILTER_BEST, NULL, 0);
    pixman_image_composite32(PIXMAN_OP_SRC,
                             orig,
                             NULL,
                             resized,
                             0, 0,
                             0, 0,
                             0, 0,
                             VFS0050_IMG_WIDTH, new_height
                            );
    memcpy(buf, pixman_image_get_data(resized), VFS0050_IMG_WIDTH * new_height);

    pixman_image_unref(orig);
    pixman_image_unref(resized);

    *output_height = new_height;
    *output = buf;
}
예제 #9
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;
    uint32_t *data = pixman_image_get_data (img);

    if (fmt != PIXMAN_null)
	crc32 = compute_crc32_for_image (initcrc, img);

    if (img->bits.rowstride < 0)
	data += img->bits.rowstride * (img->bits.height - 1);

    pixman_image_unref (img);
    free (data);

    return crc32;
}
예제 #10
0
static inline void copy_to_gldrawable_from_pixmap(const RedDrawable_p* dest,
                                                  const SpiceRect& area,
                                                  const SpicePoint& offset,
                                                  const PixelsSource_p* source,
                                                  int src_x, int src_y)
{
    uint8_t *addr;
    GLXContext context = NULL;
    GLXPbuffer pbuffer;
    RenderType rendertype;
    Window win;

    rendertype = dest->source.x_drawable.rendertype;
    if (rendertype == RENDER_TYPE_FBO) {
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    } else {
        context = dest->source.x_drawable.context;
        win = dest->source.x_drawable.drawable;
        glXMakeCurrent(XPlatform::get_display(), win, context);
        glDisable(GL_TEXTURE_2D);
    }

    glPixelStorei(GL_UNPACK_ROW_LENGTH, pixman_image_get_stride(source->pixmap.pixman_image) / 4);

    glPixelZoom(1, -1);
    addr = (uint8_t *)pixman_image_get_data(source->pixmap.pixman_image);
    addr += (src_x * 4 + src_y * pixman_image_get_stride(source->pixmap.pixman_image));
    glWindowPos2i(area.left + offset.x, dest->source.x_drawable.height -
                  (area.top + offset.y));  //+ (area.bottom - area.top)));
    glDrawPixels(area.right - area.left, area.bottom - area.top,
                 GL_BGRA, GL_UNSIGNED_BYTE, addr);

    if (rendertype == RENDER_TYPE_FBO) {
        GLuint fbo;

        fbo = dest->source.x_drawable.fbo;
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    } else {
        pbuffer = dest->source.x_drawable.pbuff;
        glXMakeCurrent(XPlatform::get_display(), pbuffer, context);
    }
}
예제 #11
0
static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest,
                                                 const SpiceRect& area,
                                                 const SpicePoint& offset,
                                                 const PixelsSource_p* source,
                                                 int src_x, int src_y)
{
    int y, height;
    GLXContext context = NULL;
    GLXPbuffer pbuffer;
    Window win;
    RenderType rendertype;

    y = source->gl.height - src_y;
    height = area.bottom - area.top;

    rendertype = source->gl.rendertype;
    if (rendertype == RENDER_TYPE_FBO) {
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, source->gl.fbo);
        glBindTexture(GL_TEXTURE_2D, 0);
    } else {
        context = source->gl.context;
        pbuffer = source->gl.pbuff;
        glXMakeCurrent(XPlatform::get_display(), pbuffer, context);
        glDisable(GL_TEXTURE_2D);
    }
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glPixelStorei(GL_PACK_ROW_LENGTH,
                  pixman_image_get_stride(dest->source.pixmap.pixman_image) / 4);

    while (height > 0) {
        glReadPixels(src_x, y - height, area.right - area.left, 1,
                     GL_BGRA, GL_UNSIGNED_BYTE,
                     (uint8_t *)pixman_image_get_data(dest->source.pixmap.pixman_image) +
                     (area.left + offset.x) * 4 +
                     (area.top + offset.y + height - 1) *
                     pixman_image_get_stride(dest->source.pixmap.pixman_image));
        height--;
    }
    if (rendertype != RENDER_TYPE_FBO) {
        win = source->gl.win;
        glXMakeCurrent(XPlatform::get_display(), win, context);
    }
}
예제 #12
0
pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
        unsigned int ch)
{
    pixman_image_t *glyph;
    uint8_t *data;
    bool bit;
    int x, y;

    glyph = pixman_image_create_bits(PIXMAN_a8, 8, height,
                                     NULL, 0);
    data = (uint8_t *)pixman_image_get_data(glyph);

    font += height * ch;
    for (y = 0; y < height; y++, font++) {
        for (x = 0; x < 8; x++, data++) {
            bit = (*font) & (1 << (7-x));
            *data = bit ? 0xff : 0x00;
        }
    }
    return glyph;
}
예제 #13
0
static void
create_border(struct wayland_compositor *c)
{
	pixman_image_t *image;
	int32_t edges[4];

	image = load_image(DATADIR "/weston/border.png");
	if (!image) {
		weston_log("could'nt load border image\n");
		return;
	}

	edges[0] = c->border.left;
	edges[1] = c->border.right;
	edges[2] = c->border.top;
	edges[3] = c->border.bottom;

	gl_renderer_set_border(&c->base, pixman_image_get_width(image),
		pixman_image_get_height(image),
		pixman_image_get_data(image), edges);

	pixman_image_unref(image);
}
예제 #14
0
파일: pixman.c 프로젝트: Gnate/libfprint
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor)
{
	int new_width = img->width * w_factor;
	int new_height = img->height * h_factor;
	pixman_image_t *orig, *resized;
	pixman_transform_t transform;
	struct fp_img *newimg;

	orig = pixman_image_create_bits(PIXMAN_a8, img->width, img->height, (uint32_t *)img->data, img->width);
	resized = pixman_image_create_bits(PIXMAN_a8, new_width, new_height, NULL, new_width);

	pixman_transform_init_identity(&transform);
	pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(w_factor), pixman_int_to_fixed(h_factor));
	pixman_image_set_transform(orig, &transform);
	pixman_image_set_filter(orig, PIXMAN_FILTER_BILINEAR, NULL, 0);
	pixman_image_composite32(PIXMAN_OP_SRC,
		orig, /* src */
		NULL, /* mask */
		resized, /* dst */
		0, 0, /* src x y */
		0, 0, /* mask x y */
		0, 0, /* dst x y */
		new_width, new_height /* width height */
		);

	newimg = fpi_img_new(new_width * new_height);
	newimg->width = new_width;
	newimg->height = new_height;
	newimg->flags = img->flags;

	memcpy(newimg->data, pixman_image_get_data(resized), new_width * new_height);

	pixman_image_unref(orig);
	pixman_image_unref(resized);

	return newimg;
}
예제 #15
0
void
_cairo_image_surface_init (cairo_image_surface_t *surface,
			   pixman_image_t	*pixman_image,
			   pixman_format_code_t	 pixman_format)
{
    surface->parent = NULL;
    surface->pixman_image = pixman_image;

    surface->pixman_format = pixman_format;
    surface->format = _cairo_format_from_pixman_format (pixman_format);
    surface->data = (uint8_t *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->transparency = CAIRO_IMAGE_UNKNOWN;
    surface->color = CAIRO_IMAGE_UNKNOWN_COLOR;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    surface->base.is_clear = surface->width == 0 || surface->height == 0;

    surface->compositor = _cairo_image_spans_compositor_get ();
}
예제 #16
0
void* PixmanBitmap::pixels() {
	return (void*) pixman_image_get_data(bitmap);
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    int i;
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    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 mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *dstbuf, *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    lcg_srand (testnum);

    op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];

    if (lcg_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    dstbuf = pixman_image_get_data (dst_img);
    srcbuf = pixman_image_get_data (src_img);

    src_x = lcg_rand_n (src_width);
    src_y = lcg_rand_n (src_height);
    dst_x = lcg_rand_n (dst_width);
    dst_y = lcg_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(lcg_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (lcg_rand_n (2))
    {
	if (lcg_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (lcg_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
	mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
    }


    w = lcg_rand_n (dst_width - dst_x + 1);
    h = lcg_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
	printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
	    op, src_fmt, dst_fmt, mask_fmt);
	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 ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
    {
	int j;

	printf ("---\n");
	for (i = 0; i < dst_height; i++)
	{
	    for (j = 0; j < dst_stride; j++)
	    {
		if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
		    printf ("| ");

		printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
	    }
	    printf ("\n");
	}
	printf ("---\n");
    }

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
예제 #18
0
/**
 * glamor_trapezoids will generate trapezoid mask accumulating in
 * system memory.
 */
void
glamor_trapezoids(CARD8 op,
                  PicturePtr src, PicturePtr dst,
                  PictFormatPtr mask_format, INT16 x_src, INT16 y_src,
                  int ntrap, xTrapezoid *traps)
{
    ScreenPtr screen = dst->pDrawable->pScreen;
    BoxRec bounds;
    PicturePtr picture;
    INT16 x_dst, y_dst;
    INT16 x_rel, y_rel;
    int width, height, stride;
    PixmapPtr pixmap;
    pixman_image_t *image = NULL;

    /* If a mask format wasn't provided, we get to choose, but behavior should
     * be as if there was no temporary mask the traps were accumulated into.
     */
    if (!mask_format) {
        if (dst->polyEdge == PolyEdgeSharp)
            mask_format = PictureMatchFormat(screen, 1, PICT_a1);
        else
            mask_format = PictureMatchFormat(screen, 8, PICT_a8);
        for (; ntrap; ntrap--, traps++)
            glamor_trapezoids(op, src, dst, mask_format, x_src,
                              y_src, 1, traps);
        return;
    }

    miTrapezoidBounds(ntrap, traps, &bounds);

    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
        return;

    x_dst = traps[0].left.p1.x >> 16;
    y_dst = traps[0].left.p1.y >> 16;

    width = bounds.x2 - bounds.x1;
    height = bounds.y2 - bounds.y1;
    stride = PixmapBytePad(width, mask_format->depth);

    picture = glamor_create_mask_picture(screen, dst, mask_format,
                                         width, height);
    if (!picture)
        return;

    image = pixman_image_create_bits(picture->format,
                                     width, height, NULL, stride);
    if (!image) {
        FreePicture(picture, 0);
        return;
    }

    for (; ntrap; ntrap--, traps++)
        pixman_rasterize_trapezoid(image,
                                   (pixman_trapezoid_t *) traps,
                                   -bounds.x1, -bounds.y1);

    pixmap = glamor_get_drawable_pixmap(picture->pDrawable);

    screen->ModifyPixmapHeader(pixmap, width, height,
                               mask_format->depth,
                               BitsPerPixel(mask_format->depth),
                               PixmapBytePad(width,
                                             mask_format->depth),
                               pixman_image_get_data(image));

    x_rel = bounds.x1 + x_src - x_dst;
    y_rel = bounds.y1 + y_src - y_dst;

    CompositePicture(op, src, picture, dst,
                     x_rel, y_rel,
                     0, 0,
                     bounds.x1, bounds.y1,
                     bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);

    if (image)
        pixman_image_unref(image);

    FreePicture(picture, 0);
}
static void
uxa_check_glyphs(CARD8 op,
		 PicturePtr src,
		 PicturePtr dst,
		 PictFormatPtr maskFormat,
		 INT16 xSrc,
		 INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
	pixman_image_t *image;
	PixmapPtr scratch;
	PicturePtr mask, mask_src = NULL, mask_dst = NULL, white = NULL;
	int width = 0, height = 0;
	int x, y, n;
	int xDst = list->xOff, yDst = list->yOff;
	BoxRec extents = { 0, 0, 0, 0 };
	CARD8 mask_op = 0;

	if (maskFormat) {
		pixman_format_code_t format;
		CARD32 component_alpha;
		xRenderColor color;
		int error;

		uxa_glyph_extents(nlist, list, glyphs, &extents);
		if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
			return;

		width = extents.x2 - extents.x1;
		height = extents.y2 - extents.y1;

		format = maskFormat->format |
			(BitsPerPixel(maskFormat->depth) << 24);
		image =
			pixman_image_create_bits(format, width, height, NULL, 0);
		if (!image)
			return;

		scratch = GetScratchPixmapHeader(dst->pDrawable->pScreen, width, height,
						 PIXMAN_FORMAT_DEPTH(format),
						 PIXMAN_FORMAT_BPP(format),
						 pixman_image_get_stride(image),
						 pixman_image_get_data(image));

		if (!scratch) {
			pixman_image_unref(image);
			return;
		}

		component_alpha = NeedsComponent(maskFormat->format);
		mask = CreatePicture(0, &scratch->drawable,
				     maskFormat, CPComponentAlpha,
				     &component_alpha, serverClient, &error);
		if (!mask) {
			FreeScratchPixmapHeader(scratch);
			pixman_image_unref(image);
			return;
		}
		ValidatePicture(mask);

		x = -extents.x1;
		y = -extents.y1;

		color.red = color.green = color.blue = color.alpha = 0xffff;
		white = CreateSolidPicture(0, &color, &error);

		mask_op = op;
		op = PictOpAdd;

		mask_src = src;
		src = white;

		mask_dst = dst;
		dst = mask;
	} else {
		mask = dst;
		x = 0;
		y = 0;
	}

	while (nlist--) {
		x += list->xOff;
		y += list->yOff;
		n = list->len;
		while (n--) {
			GlyphPtr glyph = *glyphs++;
			PicturePtr g = GetGlyphPicture(glyph, dst->pDrawable->pScreen);
			if (g) {
				CompositePicture(op, src, g, dst,
						 xSrc + (x - glyph->info.x) - xDst,
						 ySrc + (y - glyph->info.y) - yDst,
						 0, 0,
						 x - glyph->info.x,
						 y - glyph->info.y,
						 glyph->info.width,
						 glyph->info.height);
			}

			x += glyph->info.xOff;
			y += glyph->info.yOff;
		}
		list++;
	}

	if (white)
		FreePicture(white, 0);

	if (maskFormat) {
		x = extents.x1;
		y = extents.y1;
		CompositePicture(mask_op, mask_src, mask, mask_dst,
				 xSrc + x - xDst,
				 ySrc + y - yDst,
				 0, 0,
				 x, y,
				 width, height);
		FreePicture(mask, 0);
		FreeScratchPixmapHeader(scratch);
		pixman_image_unref(image);
	}
}
예제 #20
0
int
main (int argc, char **argv)
{
#define d2f pixman_double_to_fixed
    
    GtkWidget *window, *swindow;
    GtkWidget *table;
    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
    pixman_image_t *src_img;
    pixman_image_t *dest_img;
    pixman_point_fixed_t p1 = { -10 << 0, 0 };
    pixman_point_fixed_t p2 = { WIDTH << 16, (HEIGHT - 10) << 16 };
    uint16_t full = 0xcfff;
    uint16_t low  = 0x5000;
    uint16_t alpha = 0xffff;
    pixman_gradient_stop_t stops[6] =
    {
	{ d2f (0.0), { full, low, low, alpha } },
	{ d2f (0.25), { full, full, low, alpha } },
	{ d2f (0.4), { low, full, low, alpha } },
	{ d2f (0.6), { low, full, full, alpha } },
	{ d2f (0.8), { low, low, full, alpha } },
	{ d2f (1.0), { full, low, full, alpha } },
    };

    int i;

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
    
    g_signal_connect (window, "delete-event",
		      G_CALLBACK (gtk_main_quit),
		      NULL);
    table = gtk_table_new (G_N_ELEMENTS (operators) / 6, 6, TRUE);

    src_img = pixman_image_create_linear_gradient (&p1, &p2, stops,
						   G_N_ELEMENTS (stops));

    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_PAD);
    
    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					 WIDTH, HEIGHT,
					 dest,
					 WIDTH * 4);
    pixman_image_set_accessors (dest_img, reader, writer);

    for (i = 0; i < G_N_ELEMENTS (operators); ++i)
    {
	GtkWidget *image;
	GdkPixbuf *pixbuf;
	GtkWidget *vbox;
	GtkWidget *label;
	int j, k;

	vbox = gtk_vbox_new (FALSE, 0);

	label = gtk_label_new (operators[i].name);
	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
	gtk_widget_show (label);

	for (j = 0; j < HEIGHT; ++j)
	{
	    for (k = 0; k < WIDTH; ++k)
		dest[j * WIDTH + k] = 0x7f6f6f00;
	}
	pixman_image_composite (operators[i].op, src_img, NULL, dest_img,
				0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
	pixbuf = pixbuf_from_argb32 (pixman_image_get_data (dest_img), TRUE,
				     WIDTH, HEIGHT, WIDTH * 4);
	image = gtk_image_new_from_pixbuf (pixbuf);
	gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
	gtk_widget_show (image);

	gtk_table_attach_defaults (GTK_TABLE (table), vbox,
				   i % 6, (i % 6) + 1, i / 6, (i / 6) + 1);
	gtk_widget_show (vbox);

	g_object_unref (pixbuf);
    }

    pixman_image_unref (src_img);
    free (src);
    pixman_image_unref (dest_img);
    free (dest);

    swindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
				    GTK_POLICY_AUTOMATIC,
				    GTK_POLICY_AUTOMATIC);
    
    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), table);
    gtk_widget_show (table);

    gtk_container_add (GTK_CONTAINER (window), swindow);
    gtk_widget_show (swindow);

    gtk_widget_show (window);

    gtk_main ();

    return 0;
}
예제 #21
0
파일: core.c 프로젝트: bmiklautz/FreeRDS
int freerds_send_bitmap_update(rdsConnection* connection, int bpp, RDS_MSG_PAINT_RECT* msg)
{
	BYTE* data;
	BYTE* tile;
	BYTE* buffer;
	int i, j, k;
	wStream* s;
	wStream* ts;
	int e, lines;
	int scanline;
	int rows, cols;
	int MaxRegionWidth;
	int MaxRegionHeight;
	INT32 nWidth, nHeight;
	pixman_image_t* image;
	pixman_image_t* fbImage;
	BITMAP_DATA* bitmapData;
	BITMAP_UPDATE bitmapUpdate;
	rdpUpdate* update = connection->client->update;

	//printf("%s\n", __FUNCTION__);

	MaxRegionWidth = 64 * 4;
	MaxRegionHeight = 64 * 1;

	if ((msg->nLeftRect % 4) != 0)
	{
		msg->nWidth += (msg->nLeftRect % 4);
		msg->nLeftRect -= (msg->nLeftRect % 4);
	}

	if ((msg->nTopRect % 4) != 0)
	{
		msg->nHeight += (msg->nTopRect % 4);
		msg->nTopRect -= (msg->nTopRect % 4);
	}

	if ((msg->nWidth * msg->nHeight) > (MaxRegionWidth * MaxRegionHeight))
	{
		RDS_MSG_PAINT_RECT subMsg;

		rows = (msg->nWidth + (MaxRegionWidth - (msg->nWidth % MaxRegionWidth))) / MaxRegionWidth;
		cols = (msg->nHeight + (MaxRegionHeight - (msg->nHeight % MaxRegionHeight))) / MaxRegionHeight;

		//printf("Partitioning x: %d y: %d width: %d height: %d in %d partitions (%d rows, %d cols)\n",
		//		msg->nLeftRect, msg->nTopRect, msg->nWidth, msg->nHeight, rows * cols, rows, cols);

		for (i = 0; i < rows; i++)
		{
			for (j = 0; j < cols; j++)
			{
				CopyMemory(&subMsg, msg, sizeof(RDS_MSG_PAINT_RECT));

				subMsg.nLeftRect = msg->nLeftRect + (i * MaxRegionWidth);
				subMsg.nTopRect = msg->nTopRect + (j * MaxRegionHeight);

				subMsg.nWidth = (i < (rows - 1)) ? MaxRegionWidth : msg->nWidth - (i * MaxRegionWidth);
				subMsg.nHeight = (j < (cols - 1)) ? MaxRegionHeight : msg->nHeight - (j * MaxRegionHeight);

				//printf("\t[%d, %d]: x: %d y: %d width: %d height: %d\n",
				//		i, j, subMsg.nLeftRect, subMsg.nTopRect, subMsg.nWidth, subMsg.nHeight);

				if ((subMsg.nWidth * subMsg.nHeight) > 0)
					freerds_send_bitmap_update(connection, bpp, &subMsg);
			}
		}

		return 0;
	}

	tile = (BYTE*) malloc(64 * 64 * 4);
	fbImage = (pixman_image_t*) msg->framebuffer->image;

	rows = (msg->nWidth + (64 - (msg->nWidth % 64))) / 64;
	cols = (msg->nHeight + (64 - (msg->nHeight % 64))) / 64;

	k = 0;
	bitmapUpdate.count = bitmapUpdate.number = rows * cols;
	bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number);
	bitmapUpdate.rectangles = bitmapData;

	if ((msg->nWidth % 4) != 0)
	{
		msg->nLeftRect -= (msg->nWidth % 4);
		msg->nWidth += (msg->nWidth % 4);
	}

	if ((msg->nHeight % 4) != 0)
	{
		msg->nTopRect -= (msg->nHeight % 4);
		msg->nHeight += (msg->nHeight % 4);
	}

	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			nWidth = (i < (rows - 1)) ? 64 : msg->nWidth - (i * 64);
			nHeight = (j < (cols - 1)) ? 64 : msg->nHeight - (j * 64);

			bitmapData[k].bitsPerPixel = 16;
			bitmapData[k].width = nWidth;
			bitmapData[k].height = nHeight;
			bitmapData[k].destLeft = msg->nLeftRect + (i * 64);
			bitmapData[k].destTop = msg->nTopRect + (j * 64);
			bitmapData[k].destRight = bitmapData[k].destLeft + nWidth - 1;
			bitmapData[k].destBottom = bitmapData[k].destTop + nHeight - 1;
			bitmapData[k].compressed = TRUE;

			if (((nWidth * nHeight) > 0) && (nWidth >= 4) && (nHeight >= 4))
			{
				e = nWidth % 4;

				if (e != 0)
					e = 4 - e;

				//printf("k: %d destLeft: %d destTop: %d destRight: %d destBottom: %d nWidth: %d nHeight: %d\n",
				//		k, bitmapData[k].destLeft, bitmapData[k].destTop,
				//		bitmapData[k].destRight, bitmapData[k].destBottom, nWidth, nHeight);

				s = connection->encoder->bs;
				ts = connection->encoder->bts;

				Stream_SetPosition(s, 0);
				Stream_SetPosition(ts, 0);

				data = msg->framebuffer->fbSharedMemory;
				data = &data[(bitmapData[k].destTop * msg->framebuffer->fbScanline) +
				             (bitmapData[k].destLeft * msg->framebuffer->fbBytesPerPixel)];

				scanline = msg->framebuffer->fbScanline;

				if (bpp > 16)
				{
					int dstSize;
					UINT32 format;

					format = FREERDP_PIXEL_FORMAT(msg->framebuffer->fbBitsPerPixel,
							FREERDP_PIXEL_FORMAT_TYPE_ARGB, FREERDP_PIXEL_FLIP_NONE);

					buffer = connection->encoder->grid[k];

					buffer = freerdp_bitmap_compress_planar(connection->encoder->planar_context,
							data, format, nWidth, nHeight, scanline, buffer, &dstSize);

					bitmapData[k].bitmapDataStream = buffer;
					bitmapData[k].bitmapLength = dstSize;

					bitmapData[k].bitsPerPixel = 32;
					bitmapData[k].cbScanWidth = nWidth * 4;
					bitmapData[k].cbUncompressedSize = nWidth * nHeight * 4;
				}
				else
				{
					image = pixman_image_create_bits(PIXMAN_r5g6b5, nWidth, nHeight, (uint32_t*) tile, nWidth * 2);

					pixman_image_composite(PIXMAN_OP_OVER, fbImage, NULL, image,
							bitmapData[k].destLeft, bitmapData[k].destTop, 0, 0, 0, 0, nWidth, nHeight);

					lines = freerdp_bitmap_compress((char*) pixman_image_get_data(image),
							nWidth, nHeight, s, 16, 16384, nHeight - 1, ts, e);
					Stream_SealLength(s);

					bitmapData[k].bitmapDataStream = Stream_Buffer(s);
					bitmapData[k].bitmapLength = Stream_Length(s);

					buffer = connection->encoder->grid[k];
					CopyMemory(buffer, bitmapData[k].bitmapDataStream, bitmapData[k].bitmapLength);
					bitmapData[k].bitmapDataStream = buffer;

					bitmapData[k].bitsPerPixel = 16;
					bitmapData[k].cbScanWidth = nWidth * 2;
					bitmapData[k].cbUncompressedSize = nWidth * nHeight * 2;

					pixman_image_unref(image);
				}

				bitmapData[k].cbCompFirstRowSize = 0;
				bitmapData[k].cbCompMainBodySize = bitmapData[k].bitmapLength;

				k++;
			}
		}
	}

	bitmapUpdate.count = bitmapUpdate.number = k;

	IFCALL(update->BitmapUpdate, (rdpContext*) connection, &bitmapUpdate);

	free(bitmapData);
	free(tile);

	return 0;
}
예제 #22
0
static void
composite_clipped(pixman_image_t *src,
		  pixman_image_t *mask,
		  pixman_image_t *dest,
		  const pixman_transform_t *transform,
		  pixman_filter_t filter,
		  pixman_region32_t *src_clip)
{
	int n_box;
	pixman_box32_t *boxes;
	int32_t dest_width;
	int32_t dest_height;
	int src_stride;
	int bitspp;
	pixman_format_code_t src_format;
	void *src_data;
	int i;

	/* Hardcoded to use PIXMAN_OP_OVER, because sampling outside of
	 * a Pixman image produces (0,0,0,0) instead of discarding the
	 * fragment.
	 */

	dest_width = pixman_image_get_width(dest);
	dest_height = pixman_image_get_height(dest);
	src_format = pixman_image_get_format(src);
	src_stride = pixman_image_get_stride(src);
	bitspp = PIXMAN_FORMAT_BPP(src_format);
	src_data = pixman_image_get_data(src);

	assert(src_format);

	/* This would be massive overdraw, except when n_box is 1. */
	boxes = pixman_region32_rectangles(src_clip, &n_box);
	for (i = 0; i < n_box; i++) {
		uint8_t *ptr = src_data;
		pixman_image_t *boximg;
		pixman_transform_t adj = *transform;

		ptr += boxes[i].y1 * src_stride;
		ptr += boxes[i].x1 * bitspp / 8;
		boximg = pixman_image_create_bits_no_clear(src_format,
					boxes[i].x2 - boxes[i].x1,
					boxes[i].y2 - boxes[i].y1,
					(uint32_t *)ptr, src_stride);

		pixman_transform_translate(&adj, NULL,
					   pixman_int_to_fixed(-boxes[i].x1),
					   pixman_int_to_fixed(-boxes[i].y1));
		pixman_image_set_transform(boximg, &adj);

		pixman_image_set_filter(boximg, filter, NULL, 0);
		pixman_image_composite32(PIXMAN_OP_OVER, boximg, mask, dest,
					 0, 0, /* src_x, src_y */
					 0, 0, /* mask_x, mask_y */
					 0, 0, /* dest_x, dest_y */
					 dest_width, dest_height);

		pixman_image_unref(boximg);
	}

	if (n_box > 1) {
		static bool warned = false;

		if (!warned)
			weston_log("Pixman-renderer warning: %dx overdraw\n",
				   n_box);
		warned = true;
	}
}
예제 #23
0
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    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 mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    prng_srand (testnum);

    op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];

    if (prng_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    srcbuf = pixman_image_get_data (src_img);

    src_x = prng_rand_n (src_width);
    src_y = prng_rand_n (src_height);
    dst_x = prng_rand_n (dst_width);
    dst_y = prng_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(prng_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (prng_rand_n (2))
    {
	if (prng_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (prng_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = prng_rand_n (pixman_image_get_width (mask_img));
	mask_y = prng_rand_n (pixman_image_get_height (mask_img));
    }


    w = prng_rand_n (dst_width - dst_x + 1);
    h = prng_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
        printf ("op=%s\n", operator_name (op));
	printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n",
	    format_name (src_fmt), format_name (dst_fmt),
	    format_name (mask_fmt));
	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 ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
	print_image (dst_img);

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}