[comp.windows.x] xloadimage and 4-bit displays

steve@lia (Stephen Williams) (05/11/91)

Because this is a contrib application, I'm submitting this
fix to netnew rather then xbugs.

This patch allows xloadimage to work on 4 or 2-bit deep
displays.


			  X Window System Bug Report
			    xbugs@expo.lcs.mit.edu


VERSION:
    R4

CLIENT MACHINE and OPERATING SYSTEM:
	any

DISPLAY TYPE:
	XP23 (or any display with depth other then1 or 8)

WINDOW MANAGER:
	any

AREA:
	contrib/xloadimage

SYNOPSIS:
	xloadimage makes an 8 bit image, without reguard to
	the depth of the actual display.

DESCRIPTION:
	Internally, xloadimage builds an 8-bit deep image
	that it does its manipulations on.  When the result
	is to be displayed of a 4 (or 2) bit deep display,
	it creates a PixMap with the correct depth, but tries
	to XPutImage an 8 bit image into the PixMap.  The
	result is a BadMatch error.

REPEAT BY:
	display a color or grey image on a 4-bit deep display.

SAMPLE FIX:

*** send.c	Fri May 10 13:07:02 1991
--- send.c.NEW	Fri May 10 11:40:20 1991
***************
*** 11,16 ****
--- 11,18 ----
  #include "copyright.h"
  #include "xloadimage.h"
  
+ static XImage* makeImage();
+ 
  unsigned int sendImageToX(disp, scrn, visual, image, pixmap, cmap, verbose)
       Display      *disp;
       int           scrn;
***************
*** 127,137 ****
        printf("  Modifying image to conform to X colormap...");
        fflush(stdout);
      }
      pixptr= image->data;
      for (y= 0; y < image->height; y++)
        for (x= 0; x < image->width; x++) {
! 	valToMem(*(index + memToVal(pixptr, image->pixlen)),
! 		 pixptr, image->pixlen);
  	pixptr += image->pixlen;
        }
      if (verbose)
--- 129,141 ----
        printf("  Modifying image to conform to X colormap...");
        fflush(stdout);
      }
+     ximage = makeImage(disp, scrn, visual, image->width, image->height);
+     /*ximage->byte_order= MSBFirst; /* trust me, i know what i'm talking about */
+ 
      pixptr= image->data;
      for (y= 0; y < image->height; y++)
        for (x= 0; x < image->width; x++) {
! 	XPutPixel( ximage, x, y, (*(index + memToVal(pixptr, image->pixlen))) );
  	pixptr += image->pixlen;
        }
      if (verbose)
***************
*** 139,151 ****
  
      gcv.function= GXcopy;
      gc= XCreateGC(disp, *pixmap, GCFunction, &gcv);
-     ximage= XCreateImage(disp, visual, image->depth, ZPixmap, 0, image->data,
- 			 image->width, image->height, 8, 0);
-     ximage->byte_order= MSBFirst; /* trust me, i know what i'm talking about */
  
      XPutImage(disp, *pixmap, gc, ximage, 0, 0,
  	      0, 0, image->width, image->height);
-     ximage->data= NULL;
      XDestroyImage(ximage); /* waste not want not */
      XFreeGC(disp, gc);
      break;
--- 143,156 ----
  
      gcv.function= GXcopy;
      gc= XCreateGC(disp, *pixmap, GCFunction, &gcv);
  
+ 
+ 	printf("  Image depth=%d: Screen depth=%d\n",
+ 		image->depth,
+ 		DefaultScreenOfDisplay(disp)->root_depth );
+ 
      XPutImage(disp, *pixmap, gc, ximage, 0, 0,
  	      0, 0, image->width, image->height);
      XDestroyImage(ximage); /* waste not want not */
      XFreeGC(disp, gc);
      break;
***************
*** 156,159 ****
--- 161,190 ----
    }
    lfree(index);
    return(1);
+ }
+ 
+ 
+ static XImage* makeImage(disp, scrn, visual, width, height)
+     Display* disp;
+     int scrn;
+     Visual* visual;
+     unsigned width;
+     unsigned height;
+ {
+ 	extern char*malloc();
+ 	XImage* result;
+ 	char* data;
+ 
+ 	data = malloc( (width * DefaultDepth(disp, scrn) + 7) / 8 * height );
+ 
+ 	result = XCreateImage( disp, visual, DefaultDepth(disp, scrn),
+ 			ZPixmap,
+ 			0,
+ 			data,
+ 			width,
+ 			height,
+ 			8,
+ 			0);
+ 
+ 	return result;
  }