[comp.windows.x] Definite problem with Xlib image code

dpb@viking.UUCP (09/29/88)

> I believe there's a bug in the Xlib PutImage code for ...
>
>	    for (h = height; --h >= 0; src += srcinc, dest += destinc) {
>    --->	if ((h == 0) && (srclen != length)) {
>    --->	    length -= 2;
>    --->	    *(dest + length + 1) = rev[*(src + length)];
>		}

Todd, I think I tracked down the same bug you are seeing about a 
week ago.  The approach I took was to define two additional functions,
SwapBitsAndTwoBytes_a & SwapBitsAndTwoBytes_b, put these in the
swap dispatch table, and have each of them pass an additional 
parameter to the original SwapBitsAndTwoBytes routine telling it
which byte to grab in the three questionable lines you have marked.

I'd sure like to see a response from the original author of
the XPutImage code...


   Don Bennett           (408)433-3311
   dpb%frame@sun.com      or, sun!frame!dpb
   Frame Technology


VERSION:
	X11 release 2  (Probably R3 Beta also)

CLIENT MACHINE:
	All

SYNOPSIS:
	XPutImage swaps incorrectly in half of the configurations
	in which the SwapBitsAndTwoBytes function is invoked.
	One byte of random garbage sometimes appears in the 
	last byte of an image.

DESCRIPTION:
	(The version of XPutImage.c I started with was dated
	around Sept.6, 1988);

	The SwapBitsAndTwoBytes function makes an attempt to
	grab only one of the last two bytes in the last line
	of the source image when it knows there is only one
	byte worth of data left. However, it only stands a 
	50-50 chance of actually getting the correct byte.
	
	If we consider an image with a bitmap_unit of 16 and
	a width of 40, we know that:
	  a) The data will fit in 5 bytes;
	  b) We will need to swap the first 2 pairs of bytes,
	     taking care of the first 4 bytes of data.
	
	We do NOT know the address of the last byte of data!!!
	To know that, we need to know the bit order and the
	byte order of the image.
	
	The approach I take in the bug fix is to install two
	different flavors of the SwapBitsAndTwoBytes in the
	swap table and have them pass an additional parameter
	to SwapBitsAndTwoBytes to tell it how to handle the
	last byte.

FIX:

*** XPutImage.c.old Wed Sep 21 13:07:38 1988
--- XPutImage.c	Wed Sep 21 12:37:12 1988
***************
*** 227,236 ****
  }
  
  static int
! SwapBitsAndTwoBytes (src, dest, srclen, srcinc, destinc, height)
      register unsigned char *src, *dest;
      long srclen, srcinc, destinc;
      unsigned int height;
  {
      long length = ROUNDUP(srclen, 2);
      register long h, n;
--- 227,238 ----
  }
  
  static int
! SwapBitsAndTwoBytes (src, dest, srclen, srcinc, destinc, height,
! 		     useFirstHalf)
      register unsigned char *src, *dest;
      long srclen, srcinc, destinc;
      unsigned int height;
+     int useFirstHalf;
  {
      long length = ROUNDUP(srclen, 2);
      register long h, n;
***************
*** 241,247 ****
      for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  	if ((h == 0) && (srclen != length)) {
  	    length -= 2;
! 	    *(dest + length + 1) = rev[*(src + length)];
  	}
  	for (n = length; n > 0; n -= 2, src += 2) {
  	    *dest++ = rev[*(src + 1)];
--- 243,252 ----
      for (h = height; --h >= 0; src += srcinc, dest += destinc) {
  	if ((h == 0) && (srclen != length)) {
  	    length -= 2;
! 	    if (useFirstHalf)
! 		*(dest + length + 1) = rev[*(src + length)];
! 	    else
! 		*(dest + length) = rev[*(src + length + 1)];
  	}
  	for (n = length; n > 0; n -= 2, src += 2) {
  	    *dest++ = rev[*(src + 1)];
***************
*** 251,256 ****
--- 256,279 ----
  }
  
  static int
+ SwapBitsAndTwoBytes_a (src, dest, srclen, srcinc, destinc, height)
+     register unsigned char *src, *dest;
+     long srclen, srcinc, destinc;
+     unsigned int height;
+ {
+     SwapBitsAndTwoBytes(src, dest, srclen, srcinc, destinc, height, 1);
+ }
+ 
+ static int
+ SwapBitsAndTwoBytes_b (src, dest, srclen, srcinc, destinc, height)
+     register unsigned char *src, *dest;
+     long srclen, srcinc, destinc;
+     unsigned int height;
+ {
+     SwapBitsAndTwoBytes(src, dest, srclen, srcinc, destinc, height, 0);
+ }
+ 
+ static int
  SwapBitsAndFourBytes (src, dest, srclen, srcinc, destinc, height)
      register unsigned char *src, *dest;
      long srclen, srcinc, destinc;
***************
*** 366,388 ****
  #define l SwapFourBytes,
  #define w SwapWords,
  #define R SwapBits,
! #define S SwapBitsAndTwoBytes,
  #define L SwapBitsAndFourBytes,
  #define W SwapBitsAndWords,
  
  /*         1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll   */
! /* 1Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
! /* 2Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
! /* 4Mm */ { n   n   n   R   S   L   n   s   l   R   R   R },
! /* 1Ml */ { R   R   R   n   s   l   R   S   L   n   n   n },
! /* 2Ml */ { S   S   S   s   n   w   S   R   W   s   s   s },
  /* 4Ml */ { L   L   L   l   w   n   L   W   R   l   l   l },
! /* 1Lm */ { n   n   n   R   S   L   n   s   l   R   R   R },
! /* 2Lm */ { s   s   s   S   R   W   s   n   w   S   S   S },
  /* 4Lm */ { l   l   l   L   W   R   l   w   n   L   L   L },
! /* 1Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
! /* 2Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
! /* 4Ll */ { R   R   R   n   s   l   R   S   L   n   n   n },
  
  #undef n
  #undef s
--- 389,412 ----
  #define l SwapFourBytes,
  #define w SwapWords,
  #define R SwapBits,
! #define Sa SwapBitsAndTwoBytes_a,
! #define Sb SwapBitsAndTwoBytes_b,
  #define L SwapBitsAndFourBytes,
  #define W SwapBitsAndWords,
  
  /*         1Mm 2Mm 4Mm 1Ml 2Ml 4Ml 1Lm 2Lm 4Lm 1Ll 2Ll 4Ll   */
! /* 1Mm */ { n   n   n   R   Sa  L   n   s   l   R   R   R },
! /* 2Mm */ { n   n   n   R   Sa  L   n   s   l   R   R   R },
! /* 4Mm */ { n   n   n   R   Sa  L   n   s   l   R   R   R },
! /* 1Ml */ { R   R   R   n   s   l   R   Sa  L   n   n   n },
! /* 2Ml */ { Sb  Sb  Sb  s   n   w   Sb  R   W   s   s   s },
  /* 4Ml */ { L   L   L   l   w   n   L   W   R   l   l   l },
! /* 1Lm */ { n   n   n   R   Sa  L   n   s   l   R   R   R },
! /* 2Lm */ { s   s   s   Sb  R   W   s   n   w   Sb  Sb  Sb},
  /* 4Lm */ { l   l   l   L   W   R   l   w   n   L   L   L },
! /* 1Ll */ { R   R   R   n   s   l   R   Sa  L   n   n   n },
! /* 2Ll */ { R   R   R   n   s   l   R   Sa  L   n   n   n },
! /* 4Ll */ { R   R   R   n   s   l   R   Sa  L   n   n   n },
  
  #undef n
  #undef s