How do I access an XImage directly? - Xwindows

This is a discussion on How do I access an XImage directly? - Xwindows ; I am trying to access the pixels of an XImage without using XGetPixel and XSetPixel. I created an XImage with the following code: XImage* img = XGetImage(display, window, 0, 0, 256, 256, AllPlanes, XYPixmap); I can't figure out how to ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: How do I access an XImage directly?

  1. How do I access an XImage directly?

    I am trying to access the pixels of an XImage without using XGetPixel
    and XSetPixel. I created an XImage with the following code:

    XImage* img = XGetImage(display, window, 0, 0, 256, 256, AllPlanes,
    XYPixmap);

    I can't figure out how to access the pixels directly. This is what I
    have so far (it doesn't work):

    int get_pixel(XImage* img, int x, int y) {
    int pos = y * img->bytes_per_line + x;
    int color = rgb(img->data[pos], img->data[pos+1], img->data[pos+2]);
    return color;
    }

  2. Re: How do I access an XImage directly?

    nate@nate879.org wrote:
    > I am trying to access the pixels of an XImage without using XGetPixel
    > and XSetPixel. I created an XImage with the following code:
    >
    > XImage* img = XGetImage(display, window, 0, 0, 256, 256, AllPlanes,
    > XYPixmap);
    >
    > I can't figure out how to access the pixels directly. This is what I
    > have so far (it doesn't work):
    >
    > int get_pixel(XImage* img, int x, int y) {
    > int pos = y * img->bytes_per_line + x;
    > int color = rgb(img->data[pos], img->data[pos+1], img->data[pos+2]);
    > return color;
    > }


    A few things to note:
    XGetImage returns the image format in the client's byte order.

    XCreateImage by default creates an XImage with the Display's byte order,
    which may not match the client.

    XPutImage will translate with ReformatImage internally if say the byte
    order of the XImage is LSBFirst and you want to display remotely on an
    MSBFirst display.

    So with the endian constraints, you then have the different display
    depths to handle.

    For sanity sake let's start with a 24/32-bit per-pixel image/drawable
    that you're using with XGetImage.

    bytes = octets.

    As I understand it, the bytes of the image may be in BGR or RGB, and
    that's dependent on:

    Visual *visual = DefaultVisual(display, DefaultScreen(display));

    Visual is layed out like this:
    unsigned long red_mask;
    unsigned long green_mask;
    unsigned long blue_mask;


    So for my display with a LSBFirst (least significant byte first)
    x86/IA-32 the Visual masks are:
    red, green, blue masks: 0xff0000, 0xff00, 0xff

    unsigned char *ptr = img->data + (y * img->bytes_per_line + 4 * x);
    unsigned char r, g, b;

    b = ptr[0];
    g = ptr[1];
    r = ptr[2];


    This unportable code may give you the idea:
    assert(sizeof(int) == 4);
    unsigned char bytes[4] = { 0xff, 0xee, 0xee, 0xdd};
    int i;
    memcpy (&i, bytes, 4);
    printf("i:%x i & 0xff: %x\n", i, i & 0xff);

    Which displays on my system:
    i:ddeeeeff i & 0xff: ff


    For a 16 bit image you generally have 6 bits for green, 5 bits for red,
    and 5 for blue. Green is more visually significant to the human eye, so
    they have devoted an extra bit to it.

    A 15 bit image is stored in 2 bytes, but has only 5 bits for each
    individual color channel.

    The Visual masks can tell you which colors are which by ANDing with the
    appropriate value, after you construct a single value from the 2 bytes
    by ORing and shifting.

    If I were you, I'd ignore the 8 bit displays/drawables/images. They
    tend to look awful these days when you use XGetImage/XPutImage with
    them. The color management (dithering) for such displays is also
    horrendously complicated. Be glad we live in more modern times.

    If you get stuck, I suggest looking at the libX11 sources.


    George

+ Reply to Thread