  20070621
    fixed improper ClearCode termination condition in GIF decoder (JZ); fixed
    some minor inconsistencies in Makefile (GRR)
        - xv-joe-zbiciak-20070621-gif-decoder-bugfix.dif

  20080121
    removed duplicate "XDestroyWindow(theDisp, pngW);" in xvmisc.c (IMC); fixed
    empty-filename click-and-crash bug in xvdir.c (IMC, DB)
        - xv-ian-collier-20080118-crash-fixes.msg
        - xv-david-bath-20080901-empty-filename-save-crash-fix.dif

  20081205
    reverted xvxwd.c to SJT's version 



diff -ru ../test3.20070520.stock/xv-3.10a/xv.h ./xv.h
--- ../test3.20070520.stock/xv-3.10a/xv.h	2007-05-20 22:23:33.000000000 -0700
+++ ./xv.h	2007-06-21 10:10:34.000000000 -0700
@@ -16,8 +16,9 @@
 /* GRR 2nd public jumbo F+E patches:	20050410 */
 /* GRR 3rd public jumbo F+E patches:	20050501 */
 /* GRR 4th public jumbo F+E patch:  	20070520 */
-#define REVDATE   "version 3.10a-jumboFix+Enh of 20070520"
-#define VERSTR    "3.10a-20070520"
+/* GRR 5th public jumbo F+E patch:  	200xxxxx (probably mid-2009) */
+#define REVDATE   "version 3.10a-jumboFix+Enh of 20081205 (interim!)"
+#define VERSTR    "3.10a-20081205"
 
 /*
  * uncomment the following, and modify for your site, but only if you've



diff -ru ../test3.20070520.stock/xv-3.10a/xvdir.c ./xvdir.c
--- ../test3.20070520.stock/xv-3.10a/xvdir.c	2007-05-20 22:23:33.000000000 -0700
+++ ./xvdir.c	2008-01-21 13:02:38.000000000 -0800
@@ -539,8 +539,9 @@
     return -1;
   }
 
-  /* handle clicks inside the filename box */
-  if (x > 80 &&
+  /* handle clicks inside the filename box, but only when box is not empty */
+  if (enPos > stPos &&
+      x > 80 &&
       y > dList.y + (int) dList.h + 30 &&
       x < 80 + DNAMWIDE+6 &&
       y < dList.y + (int) dList.h + 30 + LINEHIGH+5) {



diff -ru ../test3.20070520.stock/xv-3.10a/xvgif.c ./xvgif.c
--- ../test3.20070520.stock/xv-3.10a/xvgif.c	2007-05-20 22:23:33.000000000 -0700
+++ ./xvgif.c	2007-06-21 09:36:40.000000000 -0700
@@ -700,7 +700,7 @@
        * associated output code on the output queue.
        */
 
-      while (CurCode > BitMask) {
+      while (CurCode >= ClearCode) {  /* Joe Zbiciak fix, 20070621 */
 	if (OutCount > 4096) break;   /* corrupt file */
 	OutCode[OutCount++] = Suffix[CurCode];
 	CurCode = Prefix[CurCode];



diff -ru ../test3.20070520.stock/xv-3.10a/xvmisc.c ./xvmisc.c
--- ../test3.20070520.stock/xv-3.10a/xvmisc.c	2007-05-20 22:23:33.000000000 -0700
+++ ./xvmisc.c	2008-01-21 12:57:29.000000000 -0800
@@ -561,10 +561,6 @@
     if (mgcsfxW) XDestroyWindow(theDisp, mgcsfxW);
 #endif
 
-#ifdef HAVE_PNG
-    if (pngW)  XDestroyWindow(theDisp, pngW);
-#endif
-
     /* if NOT using stdcmap for images, free stdcmap */
     if (colorMapMode != CM_STDCMAP) {
       int j;



[This one reverts xvxwd.c to the pre-2007 SJT version, which actually worked...]

diff -ru ../test3.20070520.stock/xv-3.10a/xvxwd.c ./xvxwd.c
--- ../test3.20070520.stock/xv-3.10a/xvxwd.c	2007-05-20 22:23:33.000000000 -0700
+++ ./xvxwd.c	2008-12-06 00:30:44.000000000 -0800
@@ -19,6 +19,12 @@
  */
 
 #include "xv.h"
+#include <limits.h>             /* for CHAR_BIT */
+
+/* SJT: just in case ... */
+#ifndef CHAR_BIT
+#  define CHAR_BIT 8
+#endif
 
 
 /***************************** x11wd.h *****************************/
@@ -83,9 +89,14 @@
 static int    writebiglong    PARM((FILE *, CARD32));
 #endif
 
+static void   getcolorshift   PARM((CARD32, int *, int *)); /* SJT */
+
+/* SJT: for 16bpp and 24bpp shifts */
+static int    red_shift_right, red_justify_left,
+              grn_shift_right, grn_justify_left,
+              blu_shift_right, blu_justify_left;
 static byte  *pic8, *pic24;
-static CARD32 red_mask, green_mask, blue_mask;
-static int    red_shift, green_shift, blue_shift;
+static CARD32 red_mask, grn_mask, blu_mask;
 static int    bits_per_item, bits_used, bit_shift,
               bits_per_pixel, bits_per_rgb;
 static char   buf[4];
@@ -189,38 +200,34 @@
       return 0;
     }
 
-    switch (bits_per_pixel) {
-    case 16:
-    case 24:
-    case 32:
-      ;
-    default:
-      xwdError("True/Direct supports only 16, 24, and 32 bits");
-      return 0;
-    }
+    for (row=0; row<rows; row++) {
+      for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
+	CARD32 ul;
 
-    if (byte_order == MSBFirst) {
-      for (row=0; row<rows; row++) {
-        for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
-          register CARD32 ul = getpixnum(ifp);
-
-          *xP++ = ul >> red_shift   & red_mask  ;
-          *xP++ = ul >> green_shift & green_mask;
-          *xP++ = ul >> blue_shift  & blue_mask ;
-        };
-        for (col=0; col<padright; col++) getpixnum(ifp);
-      }
-    } else {
-      for (row=0; row<rows; row++) {
-        for (col=0, xP=pic24+(row*cols*3); col<cols; col++) {
-          register CARD32 ul = getpixnum(ifp);
-
-          *xP++ = ul >> blue_shift  & blue_mask ;
-          *xP++ = ul >> green_shift & green_mask;
-          *xP++ = ul >> red_shift   & red_mask  ;
-        };
-        for (col=0; col<padright; col++) getpixnum(ifp);
+	ul = getpixnum(ifp);
+	switch (bits_per_pixel) {
+        case 16:
+        case 24:
+        case 32:
+          /* SJT: shift all the way to the right and then shift left. The
+             pairs of shifts could be combined. There will be two right and
+             one left shift, but it's unknown which will be which. It seems
+             easier to do the shifts (which might be 0) separately than to
+             have a complex set of tests. I believe this is independent of
+             byte order but I have no way to test.
+           */
+          *xP++ = ((ul & red_mask) >> red_shift_right) << red_justify_left;
+          *xP++ = ((ul & grn_mask) >> grn_shift_right) << grn_justify_left;
+          *xP++ = ((ul & blu_mask) >> blu_shift_right) << blu_justify_left;
+          break;
+
+	default:
+	  xwdError("True/Direct supports only 16, 24, and 32 bits");
+	  return 0;
+	}
       }
+
+      for (col=0; col<padright; col++) getpixnum(ifp);
     }
 
     pinfo->type = PIC24;
@@ -445,28 +452,18 @@
      (i.e., 3 bytes, no alpha/padding) */
 
 
-  bits_used      = bits_per_item;
+  bits_used  = bits_per_item;
 
   if (bits_per_pixel == sizeof(pixel_mask) * 8)  pixel_mask = (CARD32) -1;
   else pixel_mask = (1 << bits_per_pixel) - 1;
 
-  red_mask   = h11P->red_mask;
-  green_mask = h11P->grn_mask;
-  blue_mask  = h11P->blu_mask;
-
-  red_shift = blue_shift = green_shift = 0;
-  while (!(red_mask & 1)) {
-    red_mask >>= 1;
-    ++red_shift;
-  }
-  while (!(blue_mask & 1)) {
-    blue_mask >>= 1;
-    ++blue_shift;
-  }
-  while (!(green_mask & 1)) {
-    green_mask >>= 1;
-    ++green_shift;
-  }
+  red_mask = h11P->red_mask;
+  grn_mask = h11P->grn_mask;
+  blu_mask = h11P->blu_mask;
+
+  getcolorshift(red_mask, &red_shift_right, &red_justify_left);
+  getcolorshift(grn_mask, &grn_shift_right, &grn_justify_left);
+  getcolorshift(blu_mask, &blu_shift_right, &blu_justify_left);
 
   byteP  = (char   *) buf;
   shortP = (CARD16 *) buf;
@@ -476,6 +473,45 @@
 }
 
 
+/* SJT: figure out the proper shifts */
+static void getcolorshift (CARD32 mask, int *rightshift, int *leftshift)
+{
+  int lshift, rshift;
+  unsigned int uu;
+
+  if (mask == 0)
+  {
+    *rightshift = *leftshift = 0;
+    return;
+  }
+
+  uu = mask;
+  lshift = rshift = 0;
+  while ((uu & 0xf) == 0)
+  {
+      rshift += 4;
+      uu >>= 4;
+  }
+  while ((uu & 1) == 0)
+  {
+      rshift++;
+      uu >>= 1;
+  }
+
+  while (uu != 0)
+  {
+      if (uu & 1)
+      {
+          lshift++;
+          uu >>= 1;
+      }
+  }
+  *rightshift = rshift;
+  *leftshift = CHAR_BIT * sizeof(pixel) - lshift;
+  return;
+}
+
+
 /******************************/
 static CARD32 getpixnum(file)
      FILE* file;
