[comp.windows.x] XImage problems

rbd@lamont.ldgo.columbia.edu (roger davis) (08/22/89)

I am writing an image processing application under X11 Release 3
and am having difficulty converting raw raster data into an XImage.

My current method is:

1) XCreateImage( ... ); (using ZPixmap format)
2) loop over entire raster, converting raw raster data
   into pixel values and then doing XPutPixel();
3) XPutImage( ... );

This works, but is **painfully** slow. On a Sun 4/280 w/32 Mb of
memory running SunOS 4.0.1, MIT X11/R3, a 512x512 image requires
between 5 and 10 minutes to load.

Is there any faster way to get raster data into a Pixmap? I thought
of keeping an array of 256 GC's (one for each pixel value) and then
doing XDrawPoint()s with the appropriate GC, but this seems kind
of ugly.

I've also thought of bypassing XPutPixel() by directly writing pixel
data into the XImage->data memory, but, besides this being incredibly
unportable, I've been able to ascertain just about zilch from the
XLib manual regarding the layout of pixels within the data array.
Could someone explain the difference between XYPixmap and ZPixmap
format, and how I can address individual pixels or bits thereof in
an 8-bit image?

I'd also like to know just how much data space I need to allocate for
a width*height 8-bit XImage. The documentation seems to indicate that I
need (width*height*sizeof(char)) bytes, but this causes core dumps in
XPutPixel() with large images. I jacked it up to
(width*height*sizeof(unsigned long)) which works OK, but this is a lot
of memory for an image which may be as large as 1024x1024, and I'd
rather not waste it if I don't need to.

-- 
Roger Davis
Lamont-Doherty Geological Observatory
rbd@lamont.ldgo.columbia.edu

rws@EXPO.LCS.MIT.EDU (08/22/89)

    On a Sun 4/280 w/32 Mb of
    memory running SunOS 4.0.1, MIT X11/R3, a 512x512 image requires
    between 5 and 10 minutes to load.

Yup.  We've sped up the common cases of XGetPixel and XPutPixel considerably for
R4.  I don't have real numbers handy, but xwud can remap an 1152x900x8-bit image
in about 34 seconds on a Sun 3/60, doing an XGetPixel and an XPutPixel and
a little bit of computation for each element.  Not blindingly fast, but better.
(Compare that with your time, which is for an image roughly 4 times smaller,
on a machine roughly three times faster.)

    I thought
    of keeping an array of 256 GC's (one for each pixel value) and then
    doing XDrawPoint()s with the appropriate GC, but this seems kind
    of ugly.

I hope you're joking.

    I've also thought of bypassing XPutPixel() by directly writing pixel
    data into the XImage->data memory,

You can certainly do this.

    but, besides this being incredibly unportable,

It isn't really, not if you know what the image format is.  The data
representation is really set by the protocol, not by Xlib.

    Could someone explain the difference between XYPixmap and ZPixmap
    format, and how I can address individual pixels or bits thereof in
    an 8-bit image?

(My guess is you don't really want to deal with XYPixmap.)  Try reading
Section 8 of the protocol document (page 357 in the Digital Press book).
ZPixmap is really pretty straightforward for 8-bit images.

    I'd also like to know just how much data space I need to allocate for
    a width*height 8-bit XImage.

It depends on what the scanline pad is (8, 16, or 32).  The total size is
(ROUNDUP(width * bits_per_pixel, scanline_pad) >> 3) * height.