diff options
author | Bart Massey <bart@cs.pdx.edu> | 2007-12-08 16:36:39 -0800 |
---|---|---|
committer | Arnaud Fontaine <arnau@debian.org> | 2010-11-14 20:03:27 +0900 |
commit | c699affc7de4946c1f9cb8856b83936e53d72bb6 (patch) | |
tree | 77eddc2f67201703832ca7ecb97e3f2f81321060 | |
parent | 43c752df3d1f7b0c329307f748269a2eb32af976 (diff) |
added xcb_image_subimage()
-rw-r--r-- | image/xcb_image.c | 71 | ||||
-rw-r--r-- | image/xcb_image.h | 44 |
2 files changed, 114 insertions, 1 deletions
diff --git a/image/xcb_image.c b/image/xcb_image.c index b5e78a7..6f532a2 100644 --- a/image/xcb_image.c +++ b/image/xcb_image.c @@ -991,3 +991,74 @@ xcb_image_convert (xcb_image_t * src, } return dst; } + +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data, + uint32_t * left_pad) +{ + int i, j; + xcb_image_t * result; + uint8_t * imagep; + uint8_t * resultp; + uint32_t left_x; + uint8_t planes = 1; + uint32_t realign = 0; + + if (x + width > image->width) + return 0; + if (y + height > image->height) + return 0; + switch (image->format) { + case XCB_IMAGE_FORMAT_Z_PIXMAP: + if (image->bpp == 4) { + realign = (x & 1) << 2; + break; + } + if (image->bpp != 1) + break; + /* fall through */ + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + planes = image->bpp; + left_x = xcb_rounddown_2(x, image->unit); + width += x - left_x; + if (left_pad) + *left_pad = x - left_x; + else + realign = x - left_x; + } + result = xcb_image_create(width, height, image->format, + image->scanline_pad, image->depth, + image->bpp, image->unit, image->byte_order, + image->bit_order, + base, bytes, data); + if (!result) + return 0; + resultp = result->data; + imagep = image->data; + if (realign > 0) { + /* XXX FIXME For now, lose on performance. Sorry. */ + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + uint32_t pixel = xcb_image_get_pixel(image, x + i, y + j); + xcb_image_put_pixel(result, i, j, pixel); + } + } + return result; + } + for (j = 0; j < planes; j++) { + for (i = 0; i < height; i++) { + memcpy(resultp, imagep, result->stride); + resultp += result->stride; + imagep += image->stride; + } + } + return result; +} diff --git a/image/xcb_image.h b/image/xcb_image.h index e9e427e..595cd8e 100644 --- a/image/xcb_image.h +++ b/image/xcb_image.h @@ -434,7 +434,8 @@ xcb_image_get_pixel (xcb_image_t *image, * when the destination has the same bits-per-pixel/scanline-unit * as the source, an optimized copy routine (thanks to Keith Packard) * is used for the conversion. Otherwise, the copy is done the - * slow, slow way with xcb_get_pixel() and xcb_put_pixel() calls. + * slow, slow way with @ref xcb_image_get_pixel() and + * @ref xcb_image_put_pixel() calls. * @ingroup xcb__image_t */ xcb_image_t * @@ -442,6 +443,47 @@ xcb_image_convert (xcb_image_t * src, xcb_image_t * dst); +/** + * Extract a subimage of an image. + * @param image Source image. + * @param x X coordinate of subimage. + * @param y Y coordinate of subimage. + * @param width Width of subimage. + * @param height Height of subimage. + * @param base Base of memory allocation. + * @param bytes Size of base allocation. + * @param data Memory allocation. + * @param left_pad If non-null, any left-shift will be put here---otherwise, the resulting image will be properly justified. + * @return The subimage, or null on error. + * + * Given an image, this function extracts the subimage at the + * given coordinates. The requested subimage must be entirely + * contained in the source @p image. The resulting image will have the same + * general image parameters as the source image. The @p base, @p bytes, + * and @p data arguments are passed to @ref xcb_create_image() unaltered + * to create the destination image---see its documentation for details. + * + * Normally, extracting a subimage of a bitmap when the @p x coordinate + * of the subimage is not aligned to an @p image scanline unit boundary + * will require rotation of each scanline unit during the copy. To + * avoid this, pass an integer pointer as the @p left_pad argument, and + * this routine will create a slightly-larger image to retain alignment, + * and report the left pad through the supplied pointer. For images + * stored in Z format, any left_pad parameter is ignored. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data, + uint32_t * left_pad); + + /* * Shm stuff */ |