[comp.windows.x] XPM - patch 2.1 to 2.3

lehors@ploum.inria.fr (Arnaud Le Hors) (08/31/90)

Follows a patch to apply to XPM version 2.1.

Modifications:

	monochrom visuals are now correctly handled,
	comments can be of a null length.
--
   Arnaud LE HORS
   BULL Research FRANCE -- Koala Project   |    Email : lehors@mirsa.inria.fr
         Inria - Sophia Antipolis          |    Phone : (33) 93 65 77 71
         2004, Route des Lucioles          |    Telex :      97 00 50 F
         06565 Valbonne CEDEX  France      |    Fax   : (33) 93 65 77 66

-- cut here -------
Go into the XPM v2.1 source directory, and pipe this file into "patch -p"
You may want to clean the directory afterwards by a:
find . \( -name \*.orig -o -size 0 \) -exec rm {} \;

diff -c1 -r -N ./Makefile /tmp/xpm-new/Makefile
*** ./Makefile	Thu Aug 30 16:47:39 1990
--- /tmp/xpm-new/Makefile	Thu Aug 30 16:47:37 1990
***************
*** 3,5 ****
  # XPM Makefile - Arnaud LE HORS
! # $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
  #
--- 3,5 ----
  # XPM Makefile - Arnaud LE HORS
! # $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
  #
diff -c1 -r -N ./README /tmp/xpm-new/README
*** ./README	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/README	Thu Aug 30 16:47:37 1990
***************
*** 1,2 ****
! $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
  
--- 1,2 ----
! $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
  
diff -c1 -r -N ./XCrPFData.c /tmp/xpm-new/XCrPFData.c
*** ./XCrPFData.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/XCrPFData.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./XRdPixF.c /tmp/xpm-new/XRdPixF.c
*** ./XRdPixF.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/XRdPixF.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./XWrPixF.c /tmp/xpm-new/XWrPixF.c
*** ./XWrPixF.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/XWrPixF.c	Thu Aug 30 16:47:37 1990
***************
*** 5,7 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 5,7 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
***************
*** 38,40 ****
    unsigned int pixgap;		/* length of pixels gap */
!   byte *dptr;
    Pixel *index = NULL;		/* index of different pixels */
--- 38,40 ----
    unsigned int pixgap;		/* length of pixels gap */
!   byte *dptr, *bptr, *destline, *destptr, *bitplane, destmask;
    Pixel *index = NULL;		/* index of different pixels */
***************
*** 45,46 ****
--- 45,48 ----
    unsigned int cpp;             /* chars per pixel */
+   unsigned int depth, linelen;
+   unsigned long plane;
    char *name;
***************
*** 77,79 ****
    pixlen = (ximage->bits_per_pixel / 8) + (ximage->bits_per_pixel % 8 ? 1 :
0);
!   pixgap = ximage->bytes_per_line - width;
  
--- 79,81 ----
    pixlen = (ximage->bits_per_pixel / 8) + (ximage->bits_per_pixel % 8 ? 1 :
0);
!   depth = ximage->depth;
  
***************
*** 83,105 ****
        return(XpmErrorStatus = PixmapNoMemory);
!   dptr = (byte *)ximage->data;
!   for (y = 0; y < height; y++) {
!       for (x = 0; x < width; x++) {
! 	  pixel = memToVal(dptr, pixlen);
! 	  for (a = 0; a < ncolors; a++)
! 	      if (*(index + a) == pixel) break;
! 	  if (a == ncolors) {
! 	      if (ncolors > indexsize) {
! 		  indexsize *= 2;
! 		  if (! (index = (Pixel *)malloc(sizeof(Pixel) * indexsize)))
! 		      RETURN(PixmapNoMemory);
  	      }
! 	      *(index + ncolors) = pixel;
! 	      ncolors++;
  	  }
- 	  valToMem((unsigned long)a, dptr, pixlen);
- 	  dptr += pixlen;
        }
!       for (b = 0; b < pixgap; b++) dptr += pixlen; /* skip extra pixels */
!   }
  
    /* get rgb values and a string of char for each color
--- 85,160 ----
        return(XpmErrorStatus = PixmapNoMemory);
!   if (depth % 8) {
!       linelen = (width / 8) + (width % 8 ? 1 : 0);
!       if (! (bitplane = (byte *)malloc(height * linelen)))
! 	  RETURN(PixmapNoMemory);
!       if (! (bptr = (byte *)malloc(width * height * pixlen))) {
! 	  free(bitplane);
! 	  RETURN(PixmapNoMemory);
!       }
!       dptr = bptr;
!       for (plane = 1 << (depth - 1); plane; plane >>= 1) {
! 	  ximage = XGetImage(display, pixmap, 0, 0, width, height, 
! 			     plane, XYPixmap);
! 	  destline = bitplane = (byte *)ximage->data;
! 	  for (y = 0; y < height; y++) {
! 	      destmask = 0x80;
! 	      destptr = destline;
! 	      for (x = 0; x < width; x++) {
! 		  if (*destptr & destmask)
! 		      *dptr |= plane;
! 		  else
! 		      *dptr &= ~plane;
! 		  if (!(destmask >>= 1)) {
! 		      destmask = 0x80;
! 		      destptr++;
! 		  }
! 		  pixel = memToVal(dptr, pixlen);
! 		  for (a = 0; a < ncolors; a++)
! 		      if (*(index + a) == pixel) break;
! 		  if (a == ncolors) {
! 		      if (ncolors > indexsize) {
! 			  indexsize *= 2;
! 			  if (! (index = (Pixel *)
! 				 malloc(sizeof(Pixel) * indexsize))) {
! 			      free(bitplane);
! 			      free(bptr);
! 			      RETURN(PixmapNoMemory);
! 			  }
! 		      }
! 		      *(index + ncolors) = pixel;
! 		      ncolors++;
! 		  }
! 		  valToMem((unsigned long)a, dptr, pixlen);
! 		  dptr += pixlen;
  	      }
! 	      destline += linelen;
  	  }
        }
!       free(bitplane);
!       bitplane = NULL;
!   } else {
!       pixgap = ximage->bytes_per_line - width;
  
+       dptr = bptr = (byte *)ximage->data;
+       for (y = 0; y < height; y++) {
+ 	  for (x = 0; x < width; x++) {
+ 	      pixel = memToVal(dptr, pixlen);
+ 	      for (a = 0; a < ncolors; a++)
+ 		  if (*(index + a) == pixel) break;
+ 	      if (a == ncolors) {
+ 		  if (ncolors > indexsize) {
+ 		      indexsize *= 2;
+ 		      if (! (index = (Pixel *)
+ 			     malloc(sizeof(Pixel) * indexsize)))
+ 			  RETURN(PixmapNoMemory);
+ 		  }
+ 		  *(index + ncolors) = pixel;
+ 		  ncolors++;
+ 	      }
+ 	      valToMem((unsigned long)a, dptr, pixlen);
+ 	      dptr += pixlen;
+ 	  }
+ 	  for (b = 0; b < pixgap; b++) dptr += pixlen; /* skip extra pixels */
+       }
+   }
    /* get rgb values and a string of char for each color
***************
*** 186,188 ****
  
!   dptr = (byte *)ximage->data;
    for (y = 0; y < height; y++) {
--- 241,243 ----
  
!   dptr = bptr;
    for (y = 0; y < height; y++) {
***************
*** 205,206 ****
--- 260,263 ----
    free(index);
+   if (depth % 8)
+       free(bptr);
    for (a = 0; a < ncolors; a++)
diff -c1 -r -N ./create.c /tmp/xpm-new/create.c
*** ./create.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/create.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
***************
*** 39,43 ****
    Pixel        *pixels;		/* pixels colors */
!   unsigned int width, height;
    char         *chars, buf[BUFSIZ], *colorname;
!   byte         *dptr, *bptr;
    XColor       xcolor;
--- 39,44 ----
    Pixel        *pixels;		/* pixels colors */
!   unsigned int width, height, linelen;
    char         *chars, buf[BUFSIZ], *colorname;
!   byte         *dptr, *bptr, *destline, *destptr, *bitplane, destmask;
!   unsigned long plane;
    XColor       xcolor;
***************
*** 214,226 ****
  
!   pixmap = XCreatePixmap(display, d, width, 
! 			 height, depth);
!   gcv.function= GXcopy;
!   gc = XCreateGC(display, pixmap, GCFunction, &gcv);
!   ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)bptr, 
! 			width, height, 8, 0);
!   ximage->byte_order= MSBFirst; /* trust him, Jim Frost knows what he's */
! 				/* talking about */
!   XPutImage(display, pixmap, gc, ximage, 0, 0, 0, 0, 
! 	    width, height);
  
    ximage->data = NULL;
--- 215,274 ----
  
!   pixmap = XCreatePixmap(display, d, width, height, depth);
  
+   /* Jim Frost algorithm */
+     /* if the destination depth is not a multiple of 8, then we send each
+      * plane as a bitmap because otherwise we would have to pack the pixel
+      * data and the XImage format is pretty vague about how that should
+      * be done.  this is not as fast as it would be if it were packed but
+      * it should be a lot more portable and only slightly slower.
+      */
+ 
+   if (depth % 8) {
+       gcv.function = GXcopy;
+       gcv.background= 0;
+       gc = XCreateGC(display, pixmap, GCFunction | GCBackground, &gcv);
+       linelen = (width / 8) + (width % 8 ? 1 : 0);
+       if (! (bitplane = (byte *)malloc(height * linelen)))
+ 	  RETURN(PixmapNoMemory);
+       ximage = XCreateImage(display, visual, 1, XYBitmap, 0, bitplane, 
+ 			    width, height, 8, 0);
+       ximage->bitmap_bit_order = MSBFirst;
+       ximage->byte_order = MSBFirst;
+ 
+       for (plane = 1 << (depth - 1); plane; plane >>= 1) {
+ 	dptr = bptr;
+ 	destline = bitplane;
+ 	for (y = 0; y < height; y++) {
+ 	  destmask = 0x80;
+ 	  destptr = destline;
+ 	  for (x = 0; x < width; x++) {
+ 	    if (*dptr & plane)
+ 	      *destptr |= destmask;
+ 	    else
+ 	      *destptr &= ~destmask;
+ 	    if (!(destmask >>= 1)) {
+ 	      destmask = 0x80;
+ 	      destptr++;
+ 	    }
+ 	    dptr += pixlen;
+ 	  }
+ 	  destline += linelen;
+ 	}
+ 	XSetForeground(display, gc, plane);
+ 	XSetPlaneMask(display, gc, plane);
+ 	XPutImage(display, pixmap, gc, ximage, 0, 0, 0, 0, width, height);
+       }
+       free(bitplane);
+   } else {
+ 
+     /* send image across in one whack
+      */
+       gcv.function = GXcopy;
+       gc = XCreateGC(display, pixmap, GCFunction, &gcv);
+       ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)bptr,
+ 			    width, height, 8, 0);
+       ximage->byte_order = MSBFirst; /* trust him, Jim Frost knows what he's
*/
+       /* talking about */
+       XPutImage(display, pixmap, gc, ximage, 0, 0, 0, 0, width, height);
+   }
    ximage->data = NULL;
***************
*** 228,230 ****
    XFreeGC(display, gc);
!   free(dptr);
    free(chars);
--- 276,278 ----
    XFreeGC(display, gc);
!   free(bptr);
    free(chars);
diff -c1 -r -N ./demo.c /tmp/xpm-new/demo.c
*** ./demo.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/demo.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./free.c /tmp/xpm-new/free.c
*** ./free.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/free.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./mio.c /tmp/xpm-new/mio.c
*** ./mio.c	Thu Aug 30 16:47:40 1990
--- /tmp/xpm-new/mio.c	Thu Aug 30 16:47:37 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
***************
*** 74,79 ****
  	    Comment[0] = Comment[n];
! 	    n = notend = 1;
  	    while (notend) {
! 		while ((Comment[n] = getc((FILE *)mdata->stream)) != ECMT[0] 
! 		       && Comment[n] != EOF) n++;
  		CommentLength = n++;
--- 74,80 ----
  	    Comment[0] = Comment[n];
! 	    notend = 1;
! 	    n = 0;
  	    while (notend) {
! 		while (Comment[n] != ECMT[0] && Comment[n] != EOF)
! 		    Comment[++n] = getc((FILE *)mdata->stream);
  		CommentLength = n++;
***************
*** 85,88 ****
  		    mungetc(Comment[n], mdata);
- 		} else {
- 		    n++;
  		}
--- 86,87 ----
***************
*** 155,160 ****
      case MFILE:
! 	*cmt = (char *) malloc(CommentLength + 1);
! 	strncpy(*cmt, Comment, CommentLength);
! 	(*cmt)[CommentLength] = '\0';
! 	CommentLength = 0;
  	break;
--- 154,162 ----
      case MFILE:
! 	if (CommentLength) {
! 	    *cmt = (char *) malloc(CommentLength + 1);
! 	    strncpy(*cmt, Comment, CommentLength);
! 	    (*cmt)[CommentLength] = '\0';
! 	    CommentLength = 0;
! 	} else
! 	    *cmt = NULL;
  	break;
diff -c1 -r -N ./value.c /tmp/xpm-new/value.c
*** ./value.c	Thu Aug 30 16:47:41 1990
--- /tmp/xpm-new/value.c	Thu Aug 30 16:47:38 1990
***************
*** 26,28 ****
   *
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 26,28 ----
   *
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./visual.c /tmp/xpm-new/visual.c
*** ./visual.c	Thu Aug 30 16:47:41 1990
--- /tmp/xpm-new/visual.c	Thu Aug 30 16:47:38 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
***************
*** 14,16 ****
  {
!   if (visual->class == GrayScale)
        switch(visual->map_entries) {
--- 14,18 ----
  {
!   switch (visual->class) {
!   case StaticGray:
!   case GrayScale:
        switch(visual->map_entries) {
***************
*** 18,20 ****
  	  return(MONO);
- 	  break;
        case 4:
--- 20,21 ----
***************
*** 21,23 ****
  	  return(GRAY4);
- 	  break;
        default:
--- 22,23 ----
***************
*** 25,28 ****
        }
!   else
        return(COLOR);
  }
--- 25,29 ----
        }
!   default:
        return(COLOR);
+   }
  }
diff -c1 -r -N ./xpm.h /tmp/xpm-new/xpm.h
*** ./xpm.h	Thu Aug 30 16:47:41 1990
--- /tmp/xpm-new/xpm.h	Thu Aug 30 16:47:38 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */
diff -c1 -r -N ./xpm.tex /tmp/xpm-new/xpm.tex
*** ./xpm.tex	Thu Aug 30 16:47:41 1990
--- /tmp/xpm-new/xpm.tex	Thu Aug 30 16:47:38 1990
***************
*** 4,6 ****
  
! % $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
  %
--- 4,6 ----
  
! % $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
  %
diff -c1 -r -N ./xpmP.h /tmp/xpm-new/xpmP.h
*** ./xpmP.h	Thu Aug 30 16:47:41 1990
--- /tmp/xpm-new/xpmP.h	Thu Aug 30 16:47:38 1990
***************
*** 6,8 ****
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
   */
--- 6,8 ----
   *  Developped by Arnaud Le Hors
!  *  $Id: xpm.shar,v 2.3 90/08/30 16:31:37 lehors Exp $
   */