image: Add a convenience function for creating an image from another's data

The GL backend would like to extract a rectangle from another surface
and convert it to a different pixel format. The
_cairo_image_surface_create_from_image() does that by returning a new
image that has the contents of the specified rectangle in the source

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-02-01 16:31:49 +00:00
parent 15830fdb10
commit c391093f40
2 changed files with 62 additions and 0 deletions

View file

@ -226,6 +226,13 @@ cairo_private cairo_image_surface_t *
_cairo_image_surface_clone_subimage (cairo_surface_t *surface,
const cairo_rectangle_int_t *extents);
/* Similar to clone; but allow format conversion */
cairo_private cairo_image_surface_t *
_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
pixman_format_code_t format,
int x, int y, int width, int height,
int stride);
CAIRO_END_DECLS
#endif /* CAIRO_IMAGE_SURFACE_PRIVATE_H */

View file

@ -1088,6 +1088,61 @@ _cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
return clone;
}
cairo_image_surface_t *
_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
pixman_format_code_t format,
int x, int y,
int width, int height, int stride)
{
cairo_image_surface_t *surface;
cairo_status_t status;
pixman_image_t *image;
void *mem = NULL;
status = other->base.status;
if (unlikely (status))
goto cleanup;
if (stride) {
mem = _cairo_malloc_ab (height, stride);
if (unlikely (mem == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto cleanup;
}
}
image = pixman_image_create_bits (format, width, height, mem, stride);
if (unlikely (image == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto cleanup_mem;
}
surface = (cairo_image_surface_t *)
_cairo_image_surface_create_for_pixman_image (image, format);
if (unlikely (surface->base.status)) {
status = surface->base.status;
goto cleanup_image;
}
pixman_image_composite32 (PIXMAN_OP_SRC,
other->pixman_image, NULL, image,
x, y,
0, 0,
0, 0,
width, height);
surface->base.is_clear = FALSE;
surface->owns_data = mem != NULL;
return surface;
cleanup_image:
pixman_image_unref (image);
cleanup_mem:
free (mem);
cleanup:
return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
}
cairo_image_transparency_t
_cairo_image_analyze_transparency (cairo_image_surface_t *image)
{