[Xcb] Bug in image handling on PPC

Barton C Massey bart at cs.pdx.edu
Mon Aug 11 23:40:13 PDT 2008


Uli,

I'm not ignoring you---I'm just buried.  Sorry we haven't
put this one to rest by now.  Thanks much for the huge
investigation and test cases!

	Bart

In message <200808120756.04305.doomster at knuut.de> you wrote:
> On Thursday 24 July 2008 07:53:02 Ulrich Eckhardt wrote:
> > IOW, xcb_image_convert() fails while manually converting the pixels works,
> > at least for the case at hand.
> 
> Okay, here is a test that tries to put an image created from 
> xcb_image_create_from_bitmap_data into various different formats.
> 
> For me, it fails on a big-endian machine to yield the expected results 
> whenever the target byte_order field is MSB_FIRST and the unit size is 2 or 4 
> bytes. I haven't tested on a little-endian machine yet.
> 
> Uli
> 
> 
> 
> --Boundary-00=_0XSoIfnf5IGB/UO
> Content-Type: text/x-csrc;
>   charset="iso 8859-15";
>   name="image-test.c"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: attachment;
> 	filename="image-test.c"
> 
> #include <stdio.h>
> #include <xcb/xcb_image.h>
> #include <xcb/shape.h>
> #include <stdlib.h>
> #include <string.h>
> #include <assert.h>
> 
> // write a pixmap to stdout
> void
> dump_image(xcb_image_t const* img)
> {
>     int x, y;
>     for( y=0; y!=img->height; ++y)
>     {
>         for( x=0; x!=img->width; ++x)
>         {
>             switch(xcb_image_get_pixel( img, x, y))
>             {
>             case 0:
>                 putc( '_', stdout);
>                 break;
>             case 1:
>                 putc( '*', stdout);
>                 break;
>             default:
>                 putc( '?', stdout);
>             }
>         }
>         putc( '\n', stdout);
>     }
> }
> 
> // convert byte order to string
> char const*
> byte_order_string(xcb_image_order_t t)
> {
>     switch(t)
>     {
>     case XCB_IMAGE_ORDER_LSB_FIRST:
>         return "XCB_IMAGE_ORDER_LSB_FIRST";
>     case XCB_IMAGE_ORDER_MSB_FIRST:
>         return "XCB_IMAGE_ORDER_MSB_FIRST";
>     }
>     return "<unknown>";
> }
> 
> // convert format to string
> char const*
> image_format_string(xcb_image_format_t t)
> {
>     switch(t)
>     {
>     case XCB_IMAGE_FORMAT_XY_BITMAP:
>         return "XCB_IMAGE_FORMAT_XY_BITMAP";
>     case XCB_IMAGE_FORMAT_XY_PIXMAP:
>         return "XCB_IMAGE_FORMAT_XY_PIXMAP";
>     case XCB_IMAGE_FORMAT_Z_PIXMAP:
>         return "XCB_IMAGE_FORMAT_Z_PIXMAP";
>     }
>     return "<unknown>";
> }
> 
> typedef enum {
>     dump_only = 0,
>     dump_with_data = 1,
>     dump_with_pixels = 2,
> } dump_flags;
> 
> // write fields of an xcb_image_t structure
> // The flag 'with_data' says whether the contained bytes should be written, too.
> void
> dump_data(xcb_image_t const* img, dump_flags flags)
> {
>     printf("{");
>     printf("width=%u, ", img->width);
>     printf("height=%u, ", img->height);
>     printf("format=%s, ", image_format_string(img->format));
>     printf("scanline_pad=%u, ", img->scanline_pad);
>     printf("depth=%u, ", img->depth);
>     printf("bpp=%u, ", img->bpp);
>     printf("unit=%u, ", img->unit);
>     printf("plane_mask=%x, ", img->plane_mask);
>     printf("byte_order=%s, ", byte_order_string(img->byte_order));
>     printf("bit_order=%s, ", byte_order_string(img->bit_order));
>     printf("stride=%u, ", img->stride);
>     printf("size=%u, ", img->size);
>     printf("base=%p, ", img->base);
>     // dump just the pointer or the whole content
>     if(flags&dump_with_data)
>     {
>         uint32_t i;
>         printf("data={");
>         for( i=0; i!=img->size; ++i)
>             printf("%02x ", img->data[i]);
>         printf("}");
>     }
>     else
>     {
>         printf("data=%p", img->data);
>     }
>     puts("}");
>     // dump the whole image in pixels
>     if(flags&dump_with_pixels)
>         dump_image(img);
> }
> 
> // print error message and exit
> void
> error( char const* msg)
> {
>     puts(msg);
>     exit(EXIT_FAILURE);
> }
> 
> /* a simple bitmap
> The size of the picture is 16x16 pixels and the content is roughly
> like this:
>   O X
>   Y 1
> It is intended for use with xcb_image_create_from_bitmap_data(). */
> unsigned const bitmap_width = 16;
> unsigned const bitmap_height = 16;
> static uint8_t const bitmap_data[] =
> {
>     0x0e,0x88,
>     0x11,0x50,
>     0x11,0x20,
>     0x11,0x50,
>     0x0e,0x88,
>     0x00,0x00,
>     0x00,0x00,
>     0x00,0x00,
>     0x00,0x00,
>     0x00,0x00,
>     0x00,0x00,
>     0x11,0x20,
>     0x0a,0x30,
>     0x04,0x20,
>     0x02,0x20,
>     0x01,0x20,
> };
> 
> struct test_setup
> {
>     uint8_t unit; // 8, 16, 32
>     xcb_image_format_t format; // XYBitmap, XYPixmap
>     xcb_image_order_t byte_order; // LSB first, MSB first
>     xcb_image_order_t bit_order; // LSB first, MSB first
> };
> 
> /* test setups
> This table defines the settings for the target image. The bitmap above is
> converted into each image type in turn. */
> struct test_setup const setups[] =
> {
>     { 8, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 8, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
> 
>     { 16, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 16, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
> 
>     { 32, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_BITMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_LSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_LSB_FIRST},
>     { 32, XCB_IMAGE_FORMAT_XY_PIXMAP, XCB_IMAGE_ORDER_MSB_FIRST, XCB_IMAGE_ORDER_MSB_FIRST},
>     {0}
> };
> 
> /* report a failed test
> The pointers to the setup and the message are mandatory, the image is optional.
> */
> void test_failed( struct test_setup const* setup, char const* msg, xcb_image_t* image)
> {
>     printf("test failed: %s\n", msg);
>     printf("target setup: unit=%u, format=%s, byte_order=%s, bit_order=%s\n",
>         (unsigned)setup->unit,
>         image_format_string(setup->format),
>         byte_order_string(setup->byte_order),
>         byte_order_string(setup->bit_order));
>     if(image) {
>         printf("resulting image:");
>         dump_data( image, dump_with_data|dump_with_pixels);
>     }
> }
> 
> void test( xcb_image_t const* original, struct test_setup const* setup)
> {
>     xcb_image_t* img;
>     int bits_different = 0;
>     uint32_t p;
> 
>     img = xcb_image_create( bitmap_width, bitmap_height,
>         setup->format,
>         setup->unit, // xpad
>         1, // depth
>         1, // BPP
>         setup->unit,
>         setup->byte_order,
>         setup->bit_order,
>         0, 0, 0); // data
>     if(!img) {
>         test_failed( setup, "failed to create target image", img);
>         return;
>     }
> 
>     img = xcb_image_convert( original, img);
>     if(!img) {
>         test_failed( setup, "failed to convert image", img);
>         return;
>     }
> 
>     for( p=0; p!=bitmap_width*bitmap_height; ++p) {
>         uint32_t p1, p2;
>         uint16_t x, y;
> 
>         x = p%bitmap_width;
>         y = p/bitmap_height;
>         p1 = xcb_image_get_pixel( original, x, y);
>         p2 = xcb_image_get_pixel( img, x, y);
>         if(p1 != p2)
>             bits_different = 1;
>     }
> 
>     if(bits_different) {
>         test_failed( setup, "target image differs", img);
>         return;
>     }
> 
>     printf("success\n");
> }
> 
> int
> main()
> {
>     struct test_setup const* setup;
>     xcb_image_t* original = xcb_image_create_from_bitmap_data(
>         bitmap_data, bitmap_width, bitmap_height);
>     if(!original)
>         error("xcb_image_create_from_bitmap_data(): failed to load initial bitmap");
>     printf("original image:\n");
>     dump_data( original, dump_with_data|dump_with_pixels);
>     printf("\n");
> 
>     for( setup = setups; setup->unit; ++setup) {
>         test( original, setup);
>         printf("\n");
>     }
> 
>     return EXIT_SUCCESS;
> }
> 
> 
> 
> --Boundary-00=_0XSoIfnf5IGB/UO
> Content-Type: text/plain; charset="us-ascii"
> MIME-Version: 1.0
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline
> 
> _______________________________________________
> Xcb mailing list
> Xcb at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xcb
> --Boundary-00=_0XSoIfnf5IGB/UO--


More information about the Xcb mailing list