[Xcb-commit] 7 commits - aux image
Bart Massey
bart at kemper.freedesktop.org
Sat Dec 8 18:55:21 PST 2007
aux/xcb_aux.c | 10 ++++++++
aux/xcb_aux.h | 3 ++
aux/xcb_bitops.h | 48 ++++++++++++++++++++++++++++++++++++++-----
image/test_bitmap.c | 51 +++++++++++++++++++++++++++++++++++----------
image/xcb_image.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--------
image/xcb_image.h | 52 +++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 197 insertions(+), 25 deletions(-)
New commits:
commit a0e3638d0cb552b038f8932862bbe0267a6c67c4
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 18:12:27 2007 -0800
added INSET argument to test_bitmap and cleaned up subimage stuff
diff --git a/image/test_bitmap.c b/image/test_bitmap.c
index 06dbfd3..fe1b3bb 100644
--- a/image/test_bitmap.c
+++ b/image/test_bitmap.c
@@ -76,11 +76,12 @@ void process_events(xcb_connection_t *c,
}
}
-#define INSET 18
+#define INSET_X 31
+#define INSET_Y 32
int main(int argc, char **argv) {
- uint32_t width = test_width - 2 * INSET;
- uint32_t height = test_height - 2 * INSET;
+ uint32_t width = test_width - 2 * INSET_X;
+ uint32_t height = test_height - 2 * INSET_Y;
int snum;
xcb_void_cookie_t check_cookie;
xcb_window_t w;
@@ -100,7 +101,6 @@ int main(int argc, char **argv) {
xcb_alloc_named_color_reply(c, fg_cookie, 0);
uint32_t fg, bg;
xcb_image_t *image, *native_image, *subimage;
- uint32_t left_pad = 0;
uint32_t mask = 0;
xcb_params_gc_t gcv;
@@ -119,9 +119,9 @@ int main(int argc, char **argv) {
assert(native_image);
if (native_image != image)
xcb_image_destroy(image);
- subimage = xcb_image_subimage(native_image, INSET, INSET,
+ subimage = xcb_image_subimage(native_image, INSET_X, INSET_Y,
width, height,
- 0, 0, 0, &left_pad);
+ 0, 0, 0);
assert(subimage);
xcb_image_destroy(native_image);
subimage->format = XCB_IMAGE_FORMAT_XY_BITMAP;
@@ -132,7 +132,7 @@ int main(int argc, char **argv) {
XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg);
XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg);
xcb_aux_create_gc(c, gc, pix, mask, &gcv);
- xcb_image_put(c, pix, gc, subimage, 0, 0, left_pad);
+ xcb_image_put(c, pix, gc, subimage, 0, 0, 0);
process_events(c, gc, w, pix, width, height);
xcb_disconnect(c);
return 1;
commit cd52fa5ad65c2becc9ac6b09bde455eb7ac46a33
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 18:11:43 2007 -0800
took out clever code for subimage copying and left_shift for now, as it was too broken
diff --git a/image/xcb_image.c b/image/xcb_image.c
index f8e1bde..4c646bc 100644
--- a/image/xcb_image.c
+++ b/image/xcb_image.c
@@ -1008,40 +1008,15 @@ xcb_image_subimage(xcb_image_t * image,
uint32_t height,
void * base,
uint32_t bytes,
- uint8_t * data,
- uint32_t * left_pad)
+ uint8_t * data)
{
- 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;
+ int i, j;
+ xcb_image_t * result;
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,
@@ -1049,23 +1024,11 @@ xcb_image_subimage(xcb_image_t * image,
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;
+ /* 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;
diff --git a/image/xcb_image.h b/image/xcb_image.h
index 16ac154..3b54da3 100644
--- a/image/xcb_image.h
+++ b/image/xcb_image.h
@@ -453,7 +453,6 @@ xcb_image_convert (xcb_image_t * src,
* @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
@@ -463,13 +462,6 @@ xcb_image_convert (xcb_image_t * src,
* 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 *
@@ -480,8 +472,7 @@ xcb_image_subimage(xcb_image_t * image,
uint32_t height,
void * base,
uint32_t bytes,
- uint8_t * data,
- uint32_t * left_pad);
+ uint8_t * data);
/*
commit 1b2d5d6cdbed398ecb4547edd74a49d1910789a5
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 17:13:55 2007 -0800
extended test_bitmap to handle subimage test
diff --git a/image/test_bitmap.c b/image/test_bitmap.c
index 5328516..06dbfd3 100644
--- a/image/test_bitmap.c
+++ b/image/test_bitmap.c
@@ -11,7 +11,9 @@
static xcb_window_t make_window(xcb_connection_t *c,
xcb_screen_t *s,
uint32_t bg,
- uint32_t fg) {
+ uint32_t fg,
+ uint32_t width,
+ uint32_t height) {
uint32_t mask = 0;
xcb_params_cw_t cwa;
xcb_window_t w;
@@ -27,7 +29,7 @@ static xcb_window_t make_window(xcb_connection_t *c,
XCB_EVENT_MASK_EXPOSURE);
w = xcb_generate_id(c);
check_cookie = xcb_aux_create_window_checked(c,
- s->root_depth, w, s->root, 0, 0, test_width, test_height, 1,
+ s->root_depth, w, s->root, 0, 0, width, height, 1,
XCB_WINDOW_CLASS_INPUT_OUTPUT, v->visual_id, mask, &cwa);
error = xcb_request_check(c, check_cookie);
assert(!error);
@@ -40,7 +42,9 @@ static xcb_window_t make_window(xcb_connection_t *c,
void process_events(xcb_connection_t *c,
xcb_gcontext_t g,
xcb_window_t w,
- xcb_pixmap_t p) {
+ xcb_pixmap_t p,
+ uint32_t width,
+ uint32_t height) {
xcb_generic_event_t *e;
xcb_void_cookie_t cookie;
@@ -54,7 +58,7 @@ void process_events(xcb_connection_t *c,
case XCB_MAP_NOTIFY:
cookie = xcb_copy_area_checked(c, p, w, g,
0, 0, 0, 0,
- test_width, test_height);
+ width, height);
assert(!xcb_request_check(c, cookie));
break;
case XCB_BUTTON_PRESS:
@@ -72,12 +76,16 @@ void process_events(xcb_connection_t *c,
}
}
+#define INSET 18
+
int main(int argc, char **argv) {
+ uint32_t width = test_width - 2 * INSET;
+ uint32_t height = test_height - 2 * INSET;
int snum;
xcb_void_cookie_t check_cookie;
xcb_window_t w;
xcb_gcontext_t gc;
- xcb_pixmap_t p;
+ xcb_pixmap_t pix;
xcb_connection_t *c = xcb_connect(0, &snum);
xcb_screen_t *s = xcb_aux_get_screen(c, snum);
xcb_alloc_named_color_cookie_t bg_cookie =
@@ -91,20 +99,41 @@ int main(int argc, char **argv) {
xcb_alloc_named_color_reply_t *fg_reply =
xcb_alloc_named_color_reply(c, fg_cookie, 0);
uint32_t fg, bg;
+ xcb_image_t *image, *native_image, *subimage;
+ uint32_t left_pad = 0;
+ uint32_t mask = 0;
+ xcb_params_gc_t gcv;
+
assert(bg_reply && fg_reply);
bg = bg_reply->pixel;
fg = fg_reply->pixel;
free(bg_reply);
free(fg_reply);
- w = make_window(c, s, bg, fg);
+ w = make_window(c, s, bg, fg, width, height);
gc = xcb_generate_id(c);
check_cookie = xcb_create_gc_checked(c, gc, w, 0, 0);
assert(!xcb_request_check(c, check_cookie));
- p = xcb_create_pixmap_from_bitmap_data(c, w,
- (uint8_t *)test_bits, test_width, test_height,
- s->root_depth, fg, bg, 0);
- assert(p);
- process_events(c, gc, w, p);
+ image = xcb_image_create_from_bitmap_data((uint8_t *)test_bits,
+ test_width, test_height);
+ native_image = xcb_image_native(c, image, 1);
+ assert(native_image);
+ if (native_image != image)
+ xcb_image_destroy(image);
+ subimage = xcb_image_subimage(native_image, INSET, INSET,
+ width, height,
+ 0, 0, 0, &left_pad);
+ assert(subimage);
+ xcb_image_destroy(native_image);
+ subimage->format = XCB_IMAGE_FORMAT_XY_BITMAP;
+ pix = xcb_generate_id(c);
+ xcb_create_pixmap(c, s->root_depth, pix, w,
+ subimage->width, subimage->height);
+ gc = xcb_generate_id(c);
+ XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg);
+ XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg);
+ xcb_aux_create_gc(c, gc, pix, mask, &gcv);
+ xcb_image_put(c, pix, gc, subimage, 0, 0, left_pad);
+ process_events(c, gc, w, pix, width, height);
xcb_disconnect(c);
return 1;
}
commit a506e5145ac76329b576c6670740210822e1c908
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 16:45:26 2007 -0800
added create_image_from_bitmap_data(), adapted create_pixmap_from_bitmap_data() to use
diff --git a/image/xcb_image.c b/image/xcb_image.c
index 6f532a2..f8e1bde 100644
--- a/image/xcb_image.c
+++ b/image/xcb_image.c
@@ -745,6 +745,19 @@ xcb_image_get_pixel (xcb_image_t *image,
}
+xcb_image_t *
+xcb_image_create_from_bitmap_data (uint8_t * data,
+ uint32_t width,
+ uint32_t height)
+{
+ return xcb_image_create(width, height, XCB_IMAGE_FORMAT_XY_PIXMAP,
+ 8, 1, 1, 8,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ 0, 0, data);
+}
+
+
/*
* (Adapted from libX11.)
*
@@ -775,20 +788,15 @@ xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display,
xcb_pixmap_t pix;
xcb_image_t * image;
xcb_image_t * final_image;
- xcb_image_format_t format = XCB_IMAGE_FORMAT_XY_PIXMAP;
xcb_gcontext_t gc;
uint32_t mask = 0;
xcb_params_gc_t gcv;
- if (depth > 1)
- format = XCB_IMAGE_FORMAT_XY_BITMAP;
- image = xcb_image_create(width, height, format,
- 8, 1, 1, 8,
- XCB_IMAGE_ORDER_LSB_FIRST,
- XCB_IMAGE_ORDER_LSB_FIRST,
- 0, 0, data);
+ image = xcb_image_create_from_bitmap_data(data, width, height);
if (!image)
return 0;
+ if (depth > 1)
+ image->format = XCB_IMAGE_FORMAT_XY_BITMAP;
final_image = xcb_image_native(display, image, 1);
if (!final_image) {
xcb_image_destroy(image);
diff --git a/image/xcb_image.h b/image/xcb_image.h
index 595cd8e..16ac154 100644
--- a/image/xcb_image.h
+++ b/image/xcb_image.h
@@ -574,6 +574,23 @@ int xcb_image_shm_get (xcb_connection_t * conn,
/**
+ * Create an image from user-supplied bitmap data.
+ * @param data Image data in packed bitmap format.
+ * @param width Width in bits of image data.
+ * @param height Height in bits of image data.
+ * @return The image constructed from the image data, or 0 on error.
+ *
+ * This function creates an image from the user-supplied
+ * bitmap @p data. The bitmap data is assumed to be in
+ * xbm format (i.e., 8-bit scanline unit, LSB-first, 8-bit pad).
+ * @ingroup xcb__image_t
+ */
+xcb_image_t *
+xcb_image_create_from_bitmap_data (uint8_t * data,
+ uint32_t width,
+ uint32_t height);
+
+/**
* Create a pixmap from user-supplied bitmap data.
* @param display The connection to the X server.
* @param d The parent drawable for the pixmap.
commit 0456acf238009d7764eed23a97891cc0e7a13170
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 16:36:39 2007 -0800
added xcb_image_subimage()
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
*/
commit 161deeb0a8cbb86b42d72afa760b12e80f1758d2
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 15:27:04 2007 -0800
fixed existing roundups, added rounddowns
diff --git a/aux/xcb_bitops.h b/aux/xcb_bitops.h
index 6462af4..48c3401 100644
--- a/aux/xcb_bitops.h
+++ b/aux/xcb_bitops.h
@@ -91,14 +91,30 @@ xcb_popcount(uint32_t x)
*
* Rounds @p base up to a multiple of @p pad, where @p pad
* is a power of two. The more general case is handled by
- * xcb_roundup_2().
+ * xcb_roundup().
* @ingroup xcb__bitops
*/
_X_INLINE static uint32_t
xcb_roundup_2 (uint32_t base, uint32_t pad)
{
- uint32_t b = base + pad - 1;
- return b & ~(pad - 1);
+ return (base + pad - 1) & -pad;
+}
+
+/**
+ * Round down to the next power-of-two unit size.
+ * @param base Number to be rounded down.
+ * @param pad Multiple to be rounded to; must be a power of two.
+ * @return Rounded-down number.
+ *
+ * Rounds @p base down to a multiple of @p pad, where @p pad
+ * is a power of two. The more general case is handled by
+ * xcb_rounddown().
+ * @ingroup xcb__bitops
+ */
+_X_INLINE static uint32_t
+xcb_rounddown_2 (uint32_t base, uint32_t pad)
+{
+ return base & -pad;
}
/**
@@ -119,8 +135,30 @@ xcb_roundup (uint32_t base, uint32_t pad)
uint32_t b = base + pad - 1;
/* faster if pad is a power of two */
if (((pad - 1) & pad) == 0)
- return b & ~(pad - 1);
- return b % pad;
+ return b & -pad;
+ return b - b % pad;
+}
+
+
+/**
+ * Round down to the next unit size.
+ * @param base Number to be rounded down.
+ * @param pad Multiple to be rounded to.
+ * @return Rounded-down number.
+ *
+ * This is a general routine for rounding @p base down
+ * to a multiple of @p pad. If you know that @p pad
+ * is a power of two, you should probably call xcb_rounddown_2()
+ * instead.
+ * @ingroup xcb__bitops
+ */
+_X_INLINE static uint32_t
+xcb_rounddown (uint32_t base, uint32_t pad)
+{
+ /* faster if pad is a power of two */
+ if (((pad - 1) & pad) == 0)
+ return base & -pad;
+ return base - base % pad;
}
commit 61c711cc0a54df8840837b40447e4719be8d670d
Author: Bart Massey <bart at cs.pdx.edu>
Date: Sat Dec 8 13:29:19 2007 -0800
added aux_clear_window() for xlib compatibility, in spite of misgivings
diff --git a/aux/xcb_aux.c b/aux/xcb_aux.c
index f152669..3602afa 100644
--- a/aux/xcb_aux.c
+++ b/aux/xcb_aux.c
@@ -323,3 +323,13 @@ xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy,
XCB_AUX_ADD_PARAM(&mask, &gv, join_style, joinstyle);
return xcb_aux_change_gc_checked(dpy, gc, mask, &gv);
}
+
+/* Adapted from Xlib */
+/* XXX It would be wiser for apps just to call
+ clear_area() directly. */
+xcb_void_cookie_t
+xcb_aux_clear_window(xcb_connection_t * dpy,
+ xcb_window_t w)
+{
+ return xcb_clear_area(dpy, 0, w, 0, 0, 0, 0);
+}
diff --git a/aux/xcb_aux.h b/aux/xcb_aux.h
index fce1f9e..952b0c3 100644
--- a/aux/xcb_aux.h
+++ b/aux/xcb_aux.h
@@ -188,6 +188,9 @@ xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy,
int32_t capstyle,
int32_t joinstyle);
+xcb_void_cookie_t
+xcb_aux_clear_window(xcb_connection_t * dpy,
+ xcb_window_t w);
#ifdef __cplusplus
}
More information about the xcb-commit
mailing list