[comp.windows.x] XPutPixel bug in X11

rbd@lamont.Columbia.edu (roger davis) (02/11/88)

> I am running X V11 R1 on a Sun workstation, and have run into a problem with 
> XPutPixel and bitmaps.  It looks to me as though _XPutPixel cannot work on
> 68000 (or other big-endian) architectures due to an assumption in the code that
> the address of a long int refers to its low order byte...
> 
> =Spencer (spencer@crim.eecs.umich.edu)

Glad to see I'm not the only one bashing my head against the wall. I am
working with XV11R1 on Sun 3/50 and 3/160C workstations running SunOS 3.4, and
have had little success with XPutPixel *or* XGetPixel. I spent hours tinkering
with the following code fragment in an attempt to read an area from an unobscured
window into an XImage, look at it pixel by pixel, change the pixels, and
write the transformed image back to the window:


	XImage *xi;
	unsigned long black, white;
	long all_planes;
	int x, y, count;
	int file1, file2;

	... open display and window, create gc, etc. ...

	white= WhitePixel(dpy, DefaultScreen(dpy));
	black= BlackPixel(dpy, DefaultScreen(dpy));
	all_planes= 0x3fffff;

	... select for mouse button clicks, map window, etc. ...


	for (;;) {
		XNextEvent(dpy, &event);

		/* here after a mouse click */
		XClearWindow(dpy, win);

		/* draw a short diagonal line and read it
		   off the window into an XImage       */
		XDrawLine(dpy, win, gc, 10, 10, 25, 25);
		xi= XGetImage(dpy, win, 10, 10, 16, 16, all_planes, XYPixmap);

		/* write the image data to a file for later examination */
		write(file1, xi->data, xi->height*xi->bytes_per_line);

		/* test XGetPixel by counting all of the black pixels */
		count= 0;
		for (y= 0; y < 16; y++)
			for (x= 0; x < 16; x++)
				if (XGetPixel(xi, x, y) == black)
					count++;

		/* test XPutPixel by setting all pixels to black */
		for (y= 0; y < 16; y++)
			for (x= 0; x < 16; x++)
				XPutPixel(xi, x, y, black);

		/* write the transformed image data to another file */
		write(file2, xi->data, xi->height*xi->bytes_per_line);

		/* display the transformed image beneath the original */
		XPutImage(dpy, win, gc, xi, 0, 0, 10, 40, 16, 16);
		XDestroyImage(xi);
	}

On both the monochrome 3/50 and the color 3/160C,
if the image is read with XYPixmap format, XGetPixel seems to work, but
XPutPixel has absolutely no effect. If the image is read with ZPixmap format,
XGetPixel does not work, and XPutPixel sets the pixel to 0 no matter
what argument it is supplied with. (I tried swapping the bytes of the argument
to XPutPixel to no avail.) In all cases, the original image data
(dumped to file1) was correct, so XGetImage is not at fault.

On the color 3/160C, XPutImage does not work when the image is in XYPixmap
format -- it draws garbage on the screen (actually, different garbage every
time you try). As I understand it, XYPixmap and ZPixmap are just two different
ways of storing multi-plane image data, and either one should work. Am I
misunderstanding something here? (More documentation on this would be nice.
I paged through the entire Xlib manual trying to find the difference between
XYPixmap and ZPixmap before I dug up an old X10 document and found
an explanation there!)

I don't think this has anything to do with the MSBFirst/LSBFirst problem --
I assume that the server and Xlib get it right between them when they pass
me the XImage read from the display, and that the Put/Get functions know
how to deal with all possible bit/byte orderings. Any ideas?

BTW, does anybody have any code to (a) convert a depth-1 monochrome image
to a depth-8 (or n) monochrome image suitable for display in a depth-8
drawable, or (2) dump a drawable's contents into a PostScript file or a Sun
rasterfile? (Not being smart enough to read or write a single pixel at a
time, I'm not about to tackle jobs like these :-) ).