summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Massey <bart@cs.pdx.edu>2007-12-08 16:36:39 -0800
committerBart Massey <bart@cs.pdx.edu>2007-12-08 16:36:39 -0800
commit88591ae9f1ce6945177d0f1e9b8dfd86f9a669c5 (patch)
tree3aabb948cb11e6d41bc288a6a80ccb370b23d71b
parentf7c46b7a03a37c087310a6596122705ea77157b7 (diff)
added xcb_image_subimage()
-rw-r--r--image/xcb_image.c71
-rw-r--r--image/xcb_image.h44
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
*/