XV 3.10a super-patch by Dave Coffin  3/8/2003

Changes made by me:
*  Fix for Postscript save crashes
*  Changed "Delete" button to non-destructive "Reject"
*  Fixed Smooth24() routine
*  Support for all raw digital camera formats
*  Compatibility with Red Hat header files
*  Simulates Protan and Deutan colorblindness
*  Use fprintf(stderr) instead of OpenAlert() (3/28/2009)
*  Reduced maxWIDE and maxHIGH by 8 and 26 pixels respectively,
   to avoid resizing by KDE window manager (9/1/2011).

Changes made by others:
*  Support for PNG image format (plus patches by Greg Roelofs)
*  Compatibility with latest versions of libjpeg and libtiff

--- xv-3.10a/Makefile	1995-01-23 15:20:54.000000000 -0500
+++ xv-3.10a/Makefile	2009-03-28 11:12:07.000000000 -0400
@@ -15,5 +15,5 @@
 
 
-CCOPTS = -O 
+CCOPTS = -O4 -march=native
 
 
@@ -46,13 +46,22 @@
 ### on your machine, *COMMENT OUT* the following lines
 ###
 JPEG    = -DDOJPEG
-JPEGDIR = jpeg
-JPEGINC = -I$(JPEGDIR)
-JPEGLIB = $(JPEGDIR)/libjpeg.a
-$(JPEGDIR)/jconfig.h:
-	cd $(JPEGDIR) ; ./configure CC='$(CC)'
-$(JPEGLIB):  $(JPEGDIR)/jconfig.h
-	cd $(JPEGDIR) ; make
+
+
+###
+### if, for whatever reason, you're unable to get the PNG library to compile
+### on your machine, *COMMENT OUT* the following lines
+###
+PNG    = -DDOPNG
+PNGLIB = -lpng
+
+
+###
+### if, for whatever reason, you're unable to get the PNG library to compile
+### on your machine, *COMMENT OUT* the following lines
+###
+ZLIBDIR = /usr/local/src/zlib
+ZLIBLIB = -lz
 
 
 ###
@@ -60,11 +69,6 @@
 ### on your machine, *COMMENT OUT* the following lines
 ###
 TIFF    = -DDOTIFF
-TIFFDIR = tiff
-TIFFINC = -I$(TIFFDIR)
-TIFFLIB = $(TIFFDIR)/libtiff.a
-$(TIFFLIB):
-	( cd $(TIFFDIR) ; make CC='$(CC)' )
 
 
 ###
@@ -102,7 +106,7 @@
 
 
 ### for LINUX, uncomment the following line
-#MCHN = -DLINUX
+MCHN = -DLINUX
 
 
 # For SCO 1.1 (UNIX 3.2v2) machines, uncomment the following:
@@ -184,11 +188,11 @@
 
 
 
-CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
+CFLAGS = $(CCOPTS) $(JPEG) $(TIFF) $(PDS) \
 	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
-	$(DXWM) $(MCHN)
+	$(DXWM) $(MCHN) $(PNG)
 
-LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm
+LIBS = -L/usr/X11R6/lib -lX11 -ljpeg -ltiff -lpng -lz -lm
 
 OBJS = 	xv.o xvevent.o xvroot.o xvmisc.o xvimage.o xvcolor.o xvsmooth.o \
 	xv24to8.o xvgif.o xvpm.o xvinfo.o xvctrl.o xvscrl.o xvalg.o \
@@ -196,7 +200,7 @@
 	xvdial.o xvgraf.o xvsunras.o xvjpeg.o xvps.o xvpopup.o xvdflt.o \
 	xvtiff.o xvtiffwr.o xvpds.o xvrle.o xviris.o xvgrab.o vprintf.o \
 	xvbrowse.o xvtext.o xvpcx.o xviff.o xvtarga.o xvxpm.o xvcut.o \
-	xvxwd.o xvfits.o
+	xvxwd.o xvfits.o xvpng.o xvraw.o
 
 MISC = README INSTALL CHANGELOG IDEAS
 
@@ -267,7 +271,7 @@
 xvbrowse.o:	bits/br_pcx bits/br_jfif bits/br_tiff bits/br_pds 
 xvbrowse.o:	bits/br_ps bits/br_iff bits/br_targa bits/br_xpm
 xvbrowse.o:	bits/br_trash bits/fcurs bits/fccurs bits/fdcurs bits/fcursm
-xvbrowse.o:     bits/br_xwd
+xvbrowse.o:     bits/br_xwd bits/br_png
 
 xvbutt.o:	bits/cboard50 bits/rb_frame bits/rb_frame1 bits/rb_top
 xvbutt.o:	bits/rb_bot bits/rb_dtop bits/rb_dbot bits/rb_body
--- xv-3.10a/bits/br_png	1969-12-31 19:00:00.000000000 -0500
+++ xv-3.10a/bits/br_png	2009-03-28 11:12:07.000000000 -0400
@@ -0,0 +1,28 @@
+#define br_png_width 48
+#define br_png_height 48
+static unsigned char br_png_bits[] = {
+  0xe0, 0xff, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x41, 0x00, 0x20, 0x00, 0x00, 0x00, 0x81, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x01, 0x01, 0x20, 0x00, 0x00, 0x00, 0xff, 0x03,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x3f, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x3f, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0xf8, 0x19, 0xc3, 0x07, 0x02, 0x20, 0x18, 0x3b, 0x63, 0x0c, 0x02,
+  0x20, 0x18, 0x3b, 0x33, 0x00, 0x02, 0x20, 0x18, 0x5b, 0x33, 0x00, 0x02,
+  0x20, 0xf8, 0x59, 0x33, 0x0f, 0x02, 0x20, 0x18, 0x98, 0x33, 0x0c, 0x02,
+  0x20, 0x18, 0x98, 0x33, 0x0c, 0x02, 0x20, 0x18, 0x18, 0x63, 0x0c, 0x02,
+  0x20, 0x18, 0x18, 0xc3, 0x0b, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x3f, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x3f, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03,
+  };
--- xv-3.10a/jpeg/jconfig.cfg	1994-12-22 17:35:00.000000000 -0500
+++ xv-3.10a/jpeg/jconfig.cfg	2009-03-28 11:12:07.000000000 -0400
@@ -42,3 +42,5 @@
 #undef PROGRESS_REPORT
 
 #endif /* JPEG_CJPEG_DJPEG */
+
+#define JDCT_DEFAULT JDCT_FLOAT
--- xv-3.10a/xv.c	1995-01-19 13:08:43.000000000 -0500
+++ xv-3.10a/xv.c	2009-03-28 11:12:07.000000000 -0400
@@ -277,6 +277,10 @@
   tiffW = (Window) NULL;  tiffUp = 0;
 #endif
 
+#ifdef HAVE_PNG
+  pngW = (Window) NULL;  pngUp = 0;
+#endif
+
   imap = ctrlmap = gmap = browmap = cmtmap = 0;
 
   ch_offx = ch_offy = p_offx = p_offy = 0;
@@ -314,8 +318,8 @@
   theVisual = DefaultVisual(theDisp,theScreen);
   ncells    = DisplayCells(theDisp, theScreen);
   dispDEEP  = DisplayPlanes(theDisp,theScreen);
-  maxWIDE   = vrWIDE  = dispWIDE  = DisplayWidth(theDisp,theScreen);
-  maxHIGH   = vrHIGH  = dispHIGH  = DisplayHeight(theDisp,theScreen);
+  maxWIDE   = (vrWIDE = dispWIDE = DisplayWidth(theDisp,theScreen)) - 8;
+  maxHIGH   = (vrHIGH = dispHIGH = DisplayHeight(theDisp,theScreen)) - 26;
 
 
   rootDEEP = dispDEEP;
@@ -782,6 +786,10 @@
   XSetTransientForHint(theDisp, tiffW, dirW);
 #endif
   
+#ifdef HAVE_PNG
+  CreatePNGW();
+  XSetTransientForHint(theDisp, pngW, dirW);
+#endif
   
   LoadFishCursors();
   SetCursors(-1);
@@ -984,7 +992,7 @@
   
   vrWIDE = dispWIDE  = DisplayWidth(theDisp,theScreen);
   vrHIGH = dispHIGH  = DisplayHeight(theDisp,theScreen);
-  maxWIDE = dispWIDE;  maxHIGH = dispHIGH;
+  maxWIDE = dispWIDE-8;  maxHIGH = dispHIGH-26;
 }
 
 
@@ -2367,7 +2375,7 @@
 
 
     if (automax) {   /* -max and -maxpect */
-      eWIDE = dispWIDE;  eHIGH = dispHIGH;
+      eWIDE = maxWIDE;  eHIGH = maxHIGH;
       if (fixedaspect) FixAspect(0,&eWIDE,&eHIGH);
     }
 
@@ -2539,10 +2547,14 @@
 
   FILE *fp;
   byte  magicno[30];    /* first 30 bytes of file */
+  char  com[256];
   int   rv, n;
 
   if (!fname) return RFT_ERROR;   /* shouldn't happen */
 
+  snprintf (com, 256, "dcraw -i '%s' 2>/dev/null", fname);
+  if (system(com) == 0) return RFT_RAW;
+
   fp = xv_fopen(fname, "r");
   if (!fp) return RFT_ERROR;
 
@@ -2611,6 +2623,11 @@
 	   (magicno[0]=='I' && magicno[1]=='I'))        rv = RFT_TIFF;
 #endif
 
+#ifdef HAVE_PNG
+  else if (magicno[0]==0x89 && magicno[1]=='P' &&
+           magicno[2]=='N'  && magicno[3]=='G')         rv = RFT_PNG;
+#endif
+
 #ifdef HAVE_PDS
   else if (strncmp((char *) magicno,  "NJPL1I00", (size_t) 8)==0 ||
 	   strncmp((char *) magicno+2,"NJPL1I",   (size_t) 6)==0 ||
@@ -2651,6 +2668,7 @@
   case RFT_GIF:     rv = LoadGIF   (fname, pinfo);         break;
   case RFT_PM:      rv = LoadPM    (fname, pinfo);         break;
   case RFT_PBM:     rv = LoadPBM   (fname, pinfo);         break;
+  case RFT_RAW:     rv = LoadRAW   (fname, pinfo);         break;
   case RFT_XBM:     rv = LoadXBM   (fname, pinfo);         break;
   case RFT_SUNRAS:  rv = LoadSunRas(fname, pinfo);         break;
   case RFT_BMP:     rv = LoadBMP   (fname, pinfo);         break;
@@ -2671,6 +2689,10 @@
   case RFT_TIFF:    rv = LoadTIFF  (fname, pinfo);           break;
 #endif
 
+#ifdef HAVE_PNG
+  case RFT_PNG:     rv = LoadPNG   (fname, pinfo);         break;
+#endif
+
 #ifdef HAVE_PDS
   case RFT_PDSVICAR: rv = LoadPDS  (fname, pinfo);           break;
 #endif
@@ -2913,18 +2935,16 @@
 
   /* execute the command */
   sprintf(str, "Doing command: '%s'", fullcmd);
-  OpenAlert(str);
+  fprintf (stderr, "%s\n", str);
   i = system(fullcmd);
   if (i) {
     sprintf(str, "Unable to complete command:\n  %s\n\n  exit status: %d",
 	    fullcmd, i);
-    CloseAlert();
     ErrPopUp(str, "\nThat Sucks!");
     unlink(tmpname);      /* just in case it was created */
     return 1;
   }
 
-  CloseAlert();
   strcpy(fname, tmpname);
   return 0;
 }
@@ -3596,50 +3616,41 @@
 /***********************************/
 int DeleteCmd()
 {
-  /* 'delete' button was pressed.  Pop up a dialog box to determine
-     what should be deleted, then do it.
+  /* 'Reject' button was pressed.  Move the file to ./rejected
+     without question.
      returns '1' if THE CURRENTLY VIEWED entry was deleted from the list, 
      in which case the 'selected' filename on the ctrl list is now 
      different, and should be auto-loaded, or something */
 
-  static char *bnames[] = { "\004Disk File", "\nList Entry", "\033Cancel" };
-  char str[512];
-  int  del, i, delnum, rv;
+  char str[512], *name, *basename;
+  int  i, delnum, rv;
 
   /* failsafe */
   delnum = nList.selected;
   if (delnum < 0 || delnum >= numnames) return 0;
 
-  sprintf(str,"Delete '%s'?\n\n%s%s",
-	  namelist[delnum],
-	  "'List Entry' deletes selection from list.\n",
-	  "'Disk File' deletes file associated with selection.");
-
-  del = PopUp(str, bnames, 3);
-  
-  if (del == 2) return 0;   /* cancel */
-  
-  if (del == 0) {           /* 'Disk File' */
-    char *name;
-    if (namelist[delnum][0] != '/') {    /* prepend 'initdir' */
-      name = (char *) malloc(strlen(namelist[delnum]) + strlen(initdir) + 2);
-      if (!name) FatalError("malloc in DeleteCmd failed\n");
-      sprintf(name,"%s/%s", initdir, namelist[delnum]);
-    }
-    else name = namelist[delnum];
-
-    i = unlink(name);
-    if (i) {
-      sprintf(str,"Can't delete file '%s'\n\n  %s.", name, ERRSTR(errno));
-      ErrPopUp(str, "\nPity");
-      if (name != namelist[delnum]) free(name);
-      return 0;
-    }
-
-    XVDeletedFile(name);
+  if (namelist[delnum][0] != '/') {    /* prepend 'initdir' */
+    name = (char *) malloc(strlen(namelist[delnum]) + strlen(initdir) + 2);
+    if (!name) FatalError("malloc in DeleteCmd failed\n");
+    sprintf(name,"%s/%s", initdir, namelist[delnum]);
+  }
+  else name = namelist[delnum];
+
+  mkdir("rejected",0777);
+  if ( (basename=strrchr(name,'/')+1) == (char *)1 )
+    basename=name;
+  sprintf(str,"rejected/%s",basename);
+  i = rename(name,str);
+  if (i) {
+    sprintf(str,"Can't reject file '%s'\n\n  %s.", name, ERRSTR(errno));
+    ErrPopUp(str, "\nPity");
     if (name != namelist[delnum]) free(name);
+    return 0;
   }
 
+  XVDeletedFile(name);
+  if (name != namelist[delnum]) free(name);
+
   deleteFromList(delnum);
 
   rv = 0;
--- xv-3.10a/xv.h	1995-01-23 15:22:23.000000000 -0500
+++ xv-3.10a/xv.h	2009-03-28 11:12:07.000000000 -0400
@@ -8,8 +8,8 @@
 #include "config.h"
 
 
-#define REVDATE   "Version 3.10a  Rev: 12/29/94"
-#define VERSTR    "3.10a"
+#define REVDATE   "Version 3.10a  Rev: 12/29/94 (PNG patch 1.2)"
+#define VERSTR    "3.10a(PNG+raw)"
 
 /*
  * uncomment the following, and modify for your site, but only if you've
@@ -115,9 +115,6 @@
 #ifndef VMS
 #  include <errno.h>
    extern int   errno;             /* SHOULD be in errno.h, but often isn't */
-#  ifndef __NetBSD__
-     extern char *sys_errlist[];     /* this too... */
-#  endif
 #endif
 
 
@@ -327,6 +324,10 @@
 #define HAVE_TIFF
 #endif
 
+#ifdef DOPNG
+#define HAVE_PNG
+#endif
+
 #ifdef DOPDS
 #define HAVE_PDS
 #endif
@@ -458,24 +459,31 @@
 #define F_TIFINC  0
 #endif
 
+#ifdef HAVE_PNG
+#define F_PNGINC  1
+#else
+#define F_PNGINC  0
+#endif
+
 
 #define F_GIF         0
 #define F_JPEG      ( 0 + F_JPGINC)
 #define F_TIFF      ( 0 + F_JPGINC + F_TIFINC)
-#define F_PS        ( 1 + F_JPGINC + F_TIFINC)
-#define F_PBMRAW    ( 2 + F_JPGINC + F_TIFINC)
-#define F_PBMASCII  ( 3 + F_JPGINC + F_TIFINC)
-#define F_XBM       ( 4 + F_JPGINC + F_TIFINC)
-#define F_XPM       ( 5 + F_JPGINC + F_TIFINC)
-#define F_BMP       ( 6 + F_JPGINC + F_TIFINC)
-#define F_SUNRAS    ( 7 + F_JPGINC + F_TIFINC)
-#define F_IRIS      ( 8 + F_JPGINC + F_TIFINC)
-#define F_TARGA     ( 9 + F_JPGINC + F_TIFINC)
-#define F_FITS      (10 + F_JPGINC + F_TIFINC)
-#define F_PM        (11 + F_JPGINC + F_TIFINC)
-#define F_DELIM1    (12 + F_JPGINC + F_TIFINC)     /* ----- */
-#define F_FILELIST  (13 + F_JPGINC + F_TIFINC)
-#define F_MAXFMTS   (14 + F_JPGINC + F_TIFINC)     /* 15, normally */
+#define F_PNG       ( 0 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_PS        ( 1 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_PBMRAW    ( 2 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_PBMASCII  ( 3 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_XBM       ( 4 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_XPM       ( 5 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_BMP       ( 6 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_SUNRAS    ( 7 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_IRIS      ( 8 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_TARGA     ( 9 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_FITS      (10 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_PM        (11 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_DELIM1    (12 + F_JPGINC + F_TIFINC + F_PNGINC)   /* ----- */
+#define F_FILELIST  (13 + F_JPGINC + F_TIFINC + F_PNGINC)
+#define F_MAXFMTS   (14 + F_JPGINC + F_TIFINC + F_PNGINC)   /* 17, normally */
 
 
 
@@ -505,6 +513,8 @@
 #define RFT_XPM      17
 #define RFT_XWD      18
 #define RFT_FITS     19
+#define RFT_PNG      20
+#define RFT_RAW      21
 
 /* definitions for page up/down, arrow up/down list control */
 #define LS_PAGEUP   0
@@ -645,7 +655,9 @@
 #define ALG_PIXEL     10
 #define ALG_SPREAD    11
 #define ALG_MEDIAN    12
-#define ALG_MAX       13
+#define ALG_PROTAN    13
+#define ALG_DEUTAN    14
+#define ALG_MAX       15
 
 
 /* indicies into sizeMB */
@@ -765,9 +777,10 @@
 typedef struct { Window win;            /* window ID */
 		 int x,y,w,h;           /* window coords in parent */
 		 int active;            /* true if can do anything*/
-		 int min,max;           /* min/max values 'pos' can take */
-		 int val;               /* 'value' of dial */
-		 int page;              /* amt val change on pageup/pagedown */
+		 double min,max;        /* min/max values 'pos' can take */
+		 double val;            /* 'value' of dial */
+		 double inc;            /* amt val change on up/down */
+		 double page;           /* amt val change on pageup/pagedown */
 		 char *title;           /* title for this guage */
 		 char *units;           /* string appended to value */
 		 u_long fg,bg,hi,lo;    /* colors */
@@ -1154,6 +1167,13 @@
 #endif
 
 
+#ifdef HAVE_PNG
+/* stuff used for 'png' box */
+WHERE Window        pngW;
+WHERE int           pngUp;        /* is pngW mapped, or what? */
+#endif
+
+
 #undef WHERE
 
 
@@ -1465,12 +1485,12 @@
 
 
 /*************************** XVDIAL.C ***************************/
-void DCreate               PARM((DIAL *, Window, int, int, int, int, int, 
-				 int, int, int, u_long, u_long, u_long, 
-				 u_long, char *, char *));
+void DCreate               PARM((DIAL *, Window, int, int, int, int, double,
+                                 double, double, double, double, u_long,
+                                 u_long, u_long, u_long, char *, char *));
 
-void DSetRange             PARM((DIAL *, int, int, int, int));
-void DSetVal               PARM((DIAL *, int));
+void DSetRange             PARM((DIAL *, double,double,double,double,double));
+void DSetVal               PARM((DIAL *, double));
 void DSetActive            PARM((DIAL *, int));
 void DRedraw               PARM((DIAL *));
 int  DTrack                PARM((DIAL *, int, int));
@@ -1552,6 +1572,9 @@
 int WritePBM               PARM((FILE *, byte *, int, int, int, byte *, 
 				 byte *, byte *, int, int, int, char *));
 
+/**************************** XVRAW.C ***************************/
+int LoadRAW                PARM((char *, PICINFO *));
+
 /**************************** XVXBM.C ***************************/
 int LoadXBM                PARM((char *, PICINFO *));
 int WriteXBM               PARM((FILE *, byte *, int, int, byte *, byte *, 
@@ -1613,6 +1636,13 @@
 int   TIFFCheckEvent       PARM((XEvent *));
 void  TIFFSaveParams       PARM((char *, int));
 
+/**************************** XVPNG.C ***************************/
+int  LoadPNG               PARM((char *, PICINFO *));
+void CreatePNGW            PARM((void));
+void PNGDialog             PARM((int));
+int  PNGCheckEvent         PARM((XEvent *));
+void PNGSaveParams         PARM((char *, int));
+
 /**************************** XVPDS.C ***************************/
 int LoadPDS                PARM((char *, PICINFO *));
 
--- xv-3.10a/xvalg.c	1994-12-22 17:34:47.000000000 -0500
+++ xv-3.10a/xvalg.c	2009-03-28 11:12:07.000000000 -0400
@@ -26,6 +26,8 @@
 static void Pixelize       PARM((void));
 static void Spread         PARM((void));
 static void MedianFilter   PARM((void));
+static void ProtanFilter   PARM((void));
+static void DeutanFilter   PARM((void));
 static void saveOrigPic    PARM((void));
 
 static void doBlurConvolv  PARM((byte *,int,int,byte *, int,int,int,int, int));
@@ -119,6 +121,8 @@
   case ALG_PIXEL:     Pixelize();     break;
   case ALG_SPREAD:    Spread();       break;
   case ALG_MEDIAN:    MedianFilter(); break;
+  case ALG_PROTAN:    ProtanFilter(); break;
+  case ALG_DEUTAN:    DeutanFilter(); break;
   }
 
   algMB.dim[ALG_NONE] = (origPic == (byte *) NULL);
@@ -554,6 +558,64 @@
 
 
 
+
+/************************/
+static void ProtanFilter()
+{
+  byte *pic24, *p24, *tmpPic;
+  int  i, j, sx,sy,sw,sh;
+
+  WaitCursor();
+
+  if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
+  else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
+  CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
+
+  SetISTR(ISTR_INFO, "Copying green channel to red...");
+
+  if (start24bitAlg(&pic24, &tmpPic)) return;
+  xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
+  
+  for (i=sy; i<sy+sh; i++) {
+    p24 = tmpPic + (i*pWIDE + sx) * 3;
+    for (j=sx; j<sx+sw; j++, p24+=3) {
+      p24[0]=p24[1];
+    }
+  }
+
+  end24bitAlg(pic24, tmpPic);
+}
+
+
+/************************/
+static void DeutanFilter()
+{
+  byte *pic24, *p24, *tmpPic;
+  int  i, j, sx,sy,sw,sh;
+
+  WaitCursor();
+
+  if (HaveSelection()) GetSelRCoords(&sx,&sy,&sw,&sh);
+  else { sx = 0;  sy = 0;  sw = pWIDE;  sh = pHIGH; }
+  CropRect2Rect(&sx,&sy,&sw,&sh, 0,0,pWIDE,pHIGH);
+
+  SetISTR(ISTR_INFO, "Copying red channel to green...");
+
+  if (start24bitAlg(&pic24, &tmpPic)) return;
+  xvbcopy((char *) pic24, (char *) tmpPic, (size_t) (pWIDE*pHIGH*3));
+  
+  for (i=sy; i<sy+sh; i++) {
+    p24 = tmpPic + (i*pWIDE + sx) * 3;
+    for (j=sx; j<sx+sw; j++, p24+=3) {
+      p24[1]=p24[0];
+    }
+  }
+
+  end24bitAlg(pic24, tmpPic);
+}
+
+
+
 /************************/
 static void doBlurConvolv(pic24, w, h, results, selx,sely,selw,selh, n)
      byte *pic24, *results;
--- xv-3.10a/xvbrowse.c	1995-01-19 12:49:17.000000000 -0500
+++ xv-3.10a/xvbrowse.c	2009-03-28 11:12:07.000000000 -0400
@@ -55,6 +55,7 @@
 #include "bits/br_xpm"
 #include "bits/br_xwd"
 #include "bits/br_fits"
+#include "bits/br_png"
 
 #include "bits/br_trash"
 #include "bits/fcurs"
@@ -94,7 +95,8 @@
 #define BF_XPM      25
 #define BF_XWD      26
 #define BF_FITS     27
-#define BF_MAX      28    /* # of built-in icons */
+#define BF_PNG      28
+#define BF_MAX      29    /* # of built-in icons */
 
 #define ISLOADABLE(ftyp) (ftyp!=BF_DIR  && ftyp!=BF_CHR && ftyp!=BF_BLK && \
 			  ftyp!=BF_SOCK && ftyp!=BF_FIFO) 
@@ -524,6 +526,7 @@
   bfIcons[BF_XPM] =MakePix1(br->win,br_xpm_bits, br_xpm_width, br_xpm_height);
   bfIcons[BF_XWD] =MakePix1(br->win,br_xwd_bits, br_xwd_width, br_xwd_height);
   bfIcons[BF_FITS]=MakePix1(br->win,br_fits_bits,br_fits_width,br_fits_height);
+  bfIcons[BF_PNG]=MakePix1(br->win,br_png_bits,br_png_width,br_png_height);
 
 
   /* check that they all got built */
@@ -3020,6 +3023,7 @@
     case RFT_XPM:      bf->ftype = BF_XPM;      break;
     case RFT_XWD:      bf->ftype = BF_XWD;      break;
     case RFT_FITS:     bf->ftype = BF_FITS;     break;
+    case RFT_PNG:      bf->ftype = BF_PNG;      break;
     }
   }
 }
@@ -3567,6 +3571,7 @@
   case RFT_XPM:      strcat(str,"XPM file");              break;
   case RFT_XWD:      strcat(str,"XWD file");              break;
   case RFT_FITS:     strcat(str,"FITS file");             break;
+  case RFT_PNG:      strcat(str,"PNG file");              break;
   default:           strcat(str,"file of unknown type");  break;
   }
   
--- xv-3.10a/xvraw.c	1969-12-31 19:00:00.000000000 -0500
+++ xv-3.10a/xvraw.c	2009-03-28 11:12:07.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * xvraw.c - load routine for raw digital camera files
+ *
+ * by Dave Coffin (dcoffin@shore.net)  3/6/2003
+ * "dcraw" 4.51 or later must be installed for this to work.
+ *
+ * LoadRAW(fname, pinfo)  -  loads the file
+ */
+
+#include "copyright.h"
+
+#include "xv.h"
+
+int LoadRAW (char *fname, PICINFO *pinfo)
+{
+  char com[256];
+  FILE *pfp;
+
+  snprintf (com, 256, "dcraw -c '%s'", fname);
+  pfp = popen (com, "r");
+  if (!pfp) {
+    SetISTR(ISTR_WARNING,"%s:  %s", fname, strerror(errno));
+    return 0;
+  }
+  if (fscanf (pfp, "P6 %d %d 255%*c", &pinfo->w, &pinfo->h) != 2) {
+    SetISTR(ISTR_WARNING,"%s:  %s", fname, "Cannot decode!!");
+    return 0;
+  }
+  pinfo->pic = (byte *) malloc (pinfo->w * pinfo->h * 3);
+  if (!pinfo->pic) FatalError("couldn't malloc 'pic'");
+  fread (pinfo->pic, pinfo->w * 3, pinfo->h, pfp);
+  pclose (pfp);
+
+  pinfo->type = PIC24;
+  pinfo->colType = F_FULLCOLOR;
+  pinfo->comment = (char *) NULL;
+  sprintf(pinfo->fullInfo, "Raw digital photo");
+  sprintf(pinfo->shrtInfo, "Raw digital photo");
+  return 1;
+}
--- xv-3.10a/xvctrl.c	1994-12-22 17:34:41.000000000 -0500
+++ xv-3.10a/xvctrl.c	2009-03-28 11:12:07.000000000 -0400
@@ -124,7 +124,9 @@
 			       "Clear Rotate...\t\244T",
 			       "Pixelize...\t\244p",
 			       "Spread...\t\244S",
-			       "DeSpeckle...\t\244k"};
+			       "DeSpeckle...\t\244k",
+			       "Protan",
+			       "Deutan" };
 
 static char *sizeMList[]   = { "Normal\tn",
 			       "Max Size\tm",
@@ -264,7 +266,7 @@
   BTCreate(&but[BLOAD],    ctrlW, R_BX0, R_BY2, R_BW1, SBUTTH, "Load",   BCLS);
   BTCreate(&but[BSAVE],    ctrlW, R_BX0, R_BY3, R_BW1, SBUTTH, "Save",   BCLS);
   BTCreate(&but[BPRINT],   ctrlW, R_BX0, R_BY4, R_BW1, SBUTTH, "Print",  BCLS);
-  BTCreate(&but[BDELETE],  ctrlW, R_BX0, R_BY5, R_BW1, SBUTTH, "Delete", BCLS);
+  BTCreate(&but[BDELETE],  ctrlW, R_BX0, R_BY5, R_BW1, SBUTTH, "Reject", BCLS);
 
 
   /* expressions for positioning bottom buttons (6x2 array) */
--- xv-3.10a/xvdial.c	1995-01-03 16:20:31.000000000 -0500
+++ xv-3.10a/xvdial.c	2009-03-28 11:12:07.000000000 -0400
@@ -41,20 +41,21 @@
 
 
 /* local functions */
-static int  whereInDial     PARM((DIAL *, int, int));
-static void drawArrow       PARM((DIAL *));
-static void drawValStr      PARM((DIAL *));
-static void drawButt        PARM((DIAL *, int, int));
-static int  computeDialVal  PARM((DIAL *, int, int));
-static void dimDial         PARM((DIAL *));
+static int    whereInDial     PARM((DIAL *, int, int));
+static void   drawArrow       PARM((DIAL *));
+static void   drawValStr      PARM((DIAL *));
+static void   drawButt        PARM((DIAL *, int, int));
+static double computeDialVal  PARM((DIAL *, int, int));
+static void   dimDial         PARM((DIAL *));
 
 
 /***************************************************/
-void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, page, 
+void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, inc, page, 
 	          fg, bg, hi, lo, title, units)
 DIAL         *dp;
 Window        parent;
-int           x,y,w,h,minv,maxv,curv,page;
+int           x,y,w,h;
+double        minv,maxv,curv,inc,page;
 unsigned long fg,bg,hi,lo;
 char         *title, *units;
 {
@@ -98,18 +99,18 @@
 				1,fg,bg);
   if (!dp->win) FatalError("can't create dial window");
 
-  DSetRange(dp, minv, maxv, curv, page);
+  DSetRange(dp, minv, maxv, curv, inc, page);
   XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
 }
 
 
 /***************************************************/
-void DSetRange(dp, minv, maxv, curv, page)
-DIAL *dp;
-int   minv, maxv, curv, page;
+void DSetRange(dp, minv, maxv, curv, inc, page)
+DIAL   *dp;
+double  minv, maxv, curv, inc, page;
 {
   if (maxv<minv) maxv=minv;
-  dp->min = minv;    dp->max = maxv;    dp->page = page;
+  dp->min = minv; dp->max = maxv; dp->inc = inc; dp->page = page;
   dp->active =  (minv < maxv);
 
   DSetVal(dp, curv);
@@ -118,8 +119,8 @@
 
 /***************************************************/
 void DSetVal(dp, curv)
-DIAL *dp;
-int   curv;
+DIAL  *dp;
+double curv;
 {
   RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
 
@@ -129,7 +130,7 @@
   XSetForeground(theDisp, theGC, dp->bg); 
   drawArrow(dp);
 
-  dp->val = curv;
+  dp->val = (double)((int)(curv / dp->inc + (curv > 0 ? 0.5 : -0.5))) * dp->inc;
 
   /* draw new arrow and string */
   XSetForeground(theDisp, theGC, dp->fg);
@@ -202,7 +203,8 @@
 int mx,my;
 {
   Window       rW,cW;
-  int          rx,ry, x,y, ipos, pos, lit, i, origval;
+  int          rx, ry, x, y, ipos, pos, lit;
+  double       origval;
   unsigned int mask;
 
   lit = 0;
@@ -224,9 +226,9 @@
   if (ipos != INDIAL) {
     drawButt(dp, ipos, 1);
     switch (ipos) {
-    case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); break;
+    case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc);  break;
     case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page); break;
-    case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1); break;
+    case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);  break;
     case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
     }
     if (dp->drawobj != NULL) (dp->drawobj)();  
@@ -235,8 +237,9 @@
   }
 
   else { 
-    i = computeDialVal(dp, mx, my);
-    DSetVal(dp, i);
+    double v;
+    v = computeDialVal(dp, mx, my);
+    DSetVal(dp, v);
     if (dp->drawobj != NULL) (dp->drawobj)();  
   }
 
@@ -246,11 +249,11 @@
     if (!(mask & Button1Mask)) break;    /* button released */
 
     if (ipos == INDIAL) {
-      int j;
-      i = computeDialVal(dp, x, y);
-      j = dp->val;
-      DSetVal(dp, i);
-      if (j != dp->val) {
+      double v, w;
+      v = computeDialVal(dp, x, y);
+      w = dp->val;
+      DSetVal(dp, v);
+      if (w != dp->val) {
 	/* track whatever dial controls */
 	if (dp->drawobj != NULL) (dp->drawobj)();  
       }
@@ -266,11 +269,11 @@
 
       if (lit) {
 	switch (ipos) {
-	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); 
+	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->inc); 
 	             break;
 	case INCW2:  if (dp->val < dp->max) DSetVal(dp, dp->val+dp->page);
                      break;
-	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-1);
+	case INCCW1: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->inc);
                      break;
 	case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                      break;
@@ -320,19 +323,20 @@
 static void drawArrow(dp)
 DIAL *dp;
 {
-  int i, rad, cx, cy;
+  int rad, cx, cy;
+  double v;
   XPoint arrow[4];
 
   rad = dp->rad;  cx = dp->cx;  cy = dp->cy;
 
   /* map pos (range minv..maxv) into degrees (range 240..-60) */
-  i = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
-  arrow[0].x = cx + (int) ((double) rad * .80 * cos(i * DEG2RAD));
-  arrow[0].y = cy - (int) ((double) rad * .80 * sin(i * DEG2RAD));
-  arrow[1].x = cx + (int) ((double) rad * .33 * cos((i+160) * DEG2RAD));
-  arrow[1].y = cy - (int) ((double) rad * .33 * sin((i+160) * DEG2RAD));
-  arrow[2].x = cx + (int) ((double) rad * .33 * cos((i-160) * DEG2RAD));
-  arrow[2].y = cy - (int) ((double) rad * .33 * sin((i-160) * DEG2RAD));
+  v = 240 + (-300 * (dp->val - dp->min)) / (dp->max - dp->min);
+  arrow[0].x = cx + (int) ((double) rad * .80 * cos(v * DEG2RAD));
+  arrow[0].y = cy - (int) ((double) rad * .80 * sin(v * DEG2RAD));
+  arrow[1].x = cx + (int) ((double) rad * .33 * cos((v+160) * DEG2RAD));
+  arrow[1].y = cy - (int) ((double) rad * .33 * sin((v+160) * DEG2RAD));
+  arrow[2].x = cx + (int) ((double) rad * .33 * cos((v-160) * DEG2RAD));
+  arrow[2].y = cy - (int) ((double) rad * .33 * sin((v-160) * DEG2RAD));
   arrow[3].x = arrow[0].x;
   arrow[3].y = arrow[0].y;
   XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin);
@@ -343,23 +347,37 @@
 static void drawValStr(dp)
 DIAL *dp;
 {
-  int  i, x1, x2;
+  int  tot, i, x1, x2;
   char foo[60], foo1[60];
 
   /* compute longest string necessary so we can right-align this thing */
-  sprintf(foo,"%d",dp->min);    x1 = strlen(foo);
-  sprintf(foo,"%d",dp->max);    x2 = strlen(foo);
+  sprintf(foo,"%d",(int)dp->min);    x1 = strlen(foo);
+  sprintf(foo,"%d",(int)dp->max);    x2 = strlen(foo);
   if (dp->min < 0 && dp->max > 0) x2++;   /* put '+' at beginning */
   i = x1;  if (x2>x1) i = x2;
   if (dp->units) i += strlen(dp->units);
 
-  if (dp->min < 0 && dp->max > 0) sprintf(foo,"%+d", dp->val);
-  else sprintf(foo,"%d", dp->val);
+  sprintf(foo,"%g",dp->inc);   /* space for decimal values */
+  tot = i + strlen(foo) - 1;   /* Take away the 0 from the beginning */
+
+  if (dp->min < 0.0 && dp->max > 0.0) sprintf(foo,"%+g", dp->val);
+  else sprintf(foo,"%g", dp->val);
+
+  if (dp->inc < 1.0)
+  {
+    int j;
+
+    if (dp->val == (double)((int)dp->val))
+      strcat(foo,".");
+
+    for (j = strlen(foo); j < tot; j++)
+      strcat(foo,"0");
+  }
 
   if (dp->units) strcat(foo,dp->units);
   foo1[0] = '\0';
   if (strlen(foo) < (size_t) i) {
-    for (i = i - strlen(foo); i>0; i--) strcat(foo1," ");
+    for (i-=strlen(foo);i>0;i--) strcat(foo1," ");
   }
   strcat(foo1, foo);
 
@@ -411,12 +429,13 @@
 
 
 /***************************************************/
-static int computeDialVal(dp, x, y)
+static double computeDialVal(dp, x, y)
 DIAL *dp;
 int x, y;
 {
-  int dx, dy, val;
-  double angle;
+  int dx, dy;
+ 
+  double angle, val;
 
   /* compute dx, dy (distance from cx, cy).  Note: +dy is *up* */
   dx = x - dp->cx;  dy = dp->cy - y;
@@ -436,8 +455,10 @@
   if (angle > 270.0) angle -= 360.0;
   if (angle < -90.0) angle += 360.0;
 
-  val = (int) ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
+  val = ((dp->max - dp->min) * (240.0 - angle) / 300.0) + dp->min;
 
+  /* round value to be an even multiple of dp->inc */
+  val = (double)((int)(val / dp->inc + 0.5)) * dp->inc;
   return val;
 }
 
--- xv-3.10a/xvdir.c	1995-01-03 16:21:39.000000000 -0500
+++ xv-3.10a/xvdir.c	2009-03-28 11:12:07.000000000 -0400
@@ -62,6 +62,9 @@
 #ifdef HAVE_TIFF
 			       "TIFF",
 #endif
+#ifdef HAVE_PNG
+			       "PNG",
+#endif
 			       "PostScript",
 			       "PBM/PGM/PPM (raw)",
 			       "PBM/PGM/PPM (ascii)",
@@ -1115,6 +1118,15 @@
   }
 #endif
 
+#ifdef HAVE_PNG
+  else if (fmt == F_PNG) {   /* PNG */
+    PNGSaveParams(fullname, col);
+    PNGDialog(1);                   /* open PNG Dialog box */
+    dbut[S_BOK].lit = 0;  BTRedraw(&dbut[S_BOK]);
+    return 0;                      /* always 'succeeds' */
+  }
+#endif
+
 
 
 
@@ -1168,7 +1180,8 @@
     
   case F_XPM:
     rv = WriteXPM   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
-		     fullname, picComments);    
+		     fullname, picComments);
+    break;
   case F_FITS:
     rv = WriteFITS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
 		     picComments);    
@@ -1380,14 +1393,21 @@
       (strcmp(lowsuf,"eps" )==0) ||
       (strcmp(lowsuf,"rgb" )==0) ||
       (strcmp(lowsuf,"tga" )==0) ||
-      (strcmp(lowsuf,"xpm" )==0) ||
       (strcmp(lowsuf,"fits")==0) ||
       (strcmp(lowsuf,"fts" )==0) ||
+#ifdef HAVE_JPEG
       (strcmp(lowsuf,"jpg" )==0) ||
       (strcmp(lowsuf,"jpeg")==0) ||
       (strcmp(lowsuf,"jfif")==0) ||
+#endif
+#ifdef HAVE_TIFF
       (strcmp(lowsuf,"tif" )==0) ||
-      (strcmp(lowsuf,"tiff")==0)) {
+      (strcmp(lowsuf,"tiff")==0) ||
+#endif
+#ifdef HAVE_PNG
+      (strcmp(lowsuf,"png" )==0) ||
+#endif
+      (strcmp(lowsuf,"xpm" )==0)) {
 
     /* found one.  set lowsuf = to the new suffix, and tack on to filename */
 
@@ -1423,6 +1443,10 @@
 #ifdef HAVE_TIFF
     case F_TIFF:     strcpy(lowsuf,"tif");  break;
 #endif
+
+#ifdef HAVE_PNG
+    case F_PNG:      strcpy(lowsuf,"png");  break;
+#endif
     }
 
     if (allcaps) {  /* upper-caseify lowsuf */
@@ -1677,7 +1701,7 @@
     sprintf(cmd, "Print /Queue = XV_Queue /Delete %s", outFName);
 #endif
     sprintf(str,"Doing command: '%s'", cmd);
-    OpenAlert(str);
+    fprintf (stderr, "%s\n", str);
     i = system(cmd);
 
 #ifdef VMS
@@ -1686,13 +1710,11 @@
 
     if (i) {
       sprintf(str, "Unable to complete command:\n  %s", cmd);
-      CloseAlert();
       ErrPopUp(str, "\nThat Sucks!");
       unlink(outFName);
       return 1;
     }
     else {
-      CloseAlert();
       SetISTR(ISTR_INFO,"Successfully completed command.");
 #ifndef VMS
       unlink(outFName);
--- xv-3.10a/xvevent.c	1995-01-23 18:20:24.000000000 -0500
+++ xv-3.10a/xvevent.c	2009-03-28 11:12:07.000000000 -0400
@@ -154,7 +154,7 @@
      int    *donep;
 {
   static int wasInfoUp=0, wasCtrlUp=0, wasDirUp=0, wasGamUp=0, wasPsUp=0;
-  static int wasJpegUp=0, wasTiffUp=0;
+  static int wasJpegUp=0, wasTiffUp=0, wasPngUp=0;
 
   static int mainWKludge=0;  /* force first mainW expose after a mainW config
 				to redraw all of mainW */
@@ -233,6 +233,10 @@
     if (TIFFCheckEvent(event)) break;   /* event has been processed */
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;   /* event has been processed */
+#endif
+
     if (GamCheckEvent (event)) break;   /* event has been processed */
     if (BrowseCheckEvent (event, &retval, &done)) break;   /* event eaten */
     if (TextCheckEvent   (event, &retval, &done)) break;   /* event eaten */
@@ -359,6 +363,10 @@
       else if (client_event->window == tiffW) TIFFDialog(0);
 #endif
 
+#ifdef HAVE_PNG
+      else if (client_event->window == pngW)  PNGDialog(0);
+#endif
+
       else if (client_event->window == mainW) Quit(0);
     }
   }
@@ -538,6 +546,10 @@
 #ifdef HAVE_TIFF
 	if (wasTiffUp) { TIFFDialog(wasTiffUp);  wasTiffUp=0; }
 #endif
+
+#ifdef HAVE_PNG
+	if (wasPngUp)  { PNGDialog(wasJpegUp);   wasPngUp=0; }
+#endif
       }
     }
   }
@@ -576,6 +588,10 @@
 #ifdef HAVE_TIFF
 	  if (tiffUp) { wasTiffUp = tiffUp;  TIFFDialog(0); }
 #endif
+
+#ifdef HAVE_PNG
+	  if (pngUp)  { wasPngUp  = pngUp;   PNGDialog(0); }
+#endif
 	}
       }
     }
@@ -908,7 +924,7 @@
     {
       int w1,h1;
       w1 = eWIDE;  h1 = eHIGH;
-      eWIDE = dispWIDE;  eHIGH = dispHIGH;
+      eWIDE = maxWIDE;  eHIGH = maxHIGH;
       FixAspect(0,&w,&h);
       eWIDE = w1;  eHIGH = h1;  /* play it safe */
       WResize(w,h);
@@ -1147,6 +1163,10 @@
     if (TIFFCheckEvent(event)) break;
 #endif
     
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+    
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
@@ -1366,6 +1386,10 @@
     if (TIFFCheckEvent(event)) break;
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
@@ -2372,6 +2396,10 @@
   if (tiffUp) TIFFDialog(0);  /* close tiff window */
 #endif
 
+#ifdef HAVE_PNG
+  if (pngUp) PNGDialog(0);    /* close png window */
+#endif
+
   ClosePopUp();
 
   /* make the interrupt signal look like a '\n' keypress in ctrlW */
--- xv-3.10a/xvgam.c	1995-01-13 14:51:14.000000000 -0500
+++ xv-3.10a/xvgam.c	2009-03-28 11:12:07.000000000 -0400
@@ -265,11 +265,11 @@
   BTCreate(&gbut[G_BRNDCOL], cmapF,  5 + 66 + 67 + 2, 189, 66, BUTTH, 
 	   "Random", infofg, infobg, hicol, locol);
 
-  DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0,360,180, 5, 
+  DCreate(&rhDial, cmapF, 5, 215, 66, 100,   0.0, 360.0, 180.0, 1.0, 5.0, 
 	  infofg, infobg, hicol, locol, "Hue", NULL);
-  DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0,360,180, 5, 
+  DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0.0, 360.0, 180.0, 1.0, 5.0, 
 	  infofg, infobg, hicol, locol, "Sat.", NULL);
-  DCreate(&bvDial, cmapF, 139, 215, 66, 100,   0,360,180, 5, 
+  DCreate(&bvDial, cmapF, 139, 215, 66, 100, 0.0, 360.0, 180.0, 1.0, 5.0, 
 	  infofg, infobg, hicol, locol, "Value", NULL);
 
   rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
@@ -359,7 +359,7 @@
 
   srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
 
-  DCreate(&satDial, hsvF, 100, 199, 100, 121, -100, 100, 0, 5, 
+  DCreate(&satDial, hsvF, 100, 199, 100, 121, -100.0, 100.0, 0.0, 1.0, 5.0, 
 	   infofg, infobg,hicol,locol, "Saturation", "%");
 
   hueRB = RBCreate(NULL, hsvF,  7, 153, "1", 
@@ -722,7 +722,7 @@
 
   if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
 
-  if (satDial.val != 0) hsvnonlinear++;
+  if (satDial.val != 0.0) hsvnonlinear++;
 
   /* check intensity graf */
   for (i=0; i<256 && intGraf.func[i]==i; i++);
@@ -1291,14 +1291,14 @@
     rgb2hsv(rcmap[editColor], gcmap[editColor], bcmap[editColor], &h, &s, &v);
     if (h<0) h = 0;
 
-    DSetVal(&rhDial, (int) h);
-    DSetVal(&gsDial, (int) (s*100));
-    DSetVal(&bvDial, (int) (v*100));
+    DSetVal(&rhDial, h);
+    DSetVal(&gsDial, s*100);
+    DSetVal(&bvDial, v*100);
   }
   else {
-    DSetVal(&rhDial, rcmap[editColor]);
-    DSetVal(&gsDial, gcmap[editColor]);
-    DSetVal(&bvDial, bcmap[editColor]);
+    DSetVal(&rhDial, (double)rcmap[editColor]);
+    DSetVal(&gsDial, (double)gcmap[editColor]);
+    DSetVal(&bvDial, (double)bcmap[editColor]);
   }
 }
   
@@ -1310,16 +1310,15 @@
 
   if (hsvmode) {
     int rv, gv, bv;
-    hsv2rgb((double) rhDial.val, ((double) gsDial.val) / 100.0, 
-	    ((double) bvDial.val) / 100.0, &rv, &gv, &bv);
+    hsv2rgb(rhDial.val, gsDial.val / 100.0, bvDial.val / 100.0, &rv, &gv, &bv);
     rcmap[editColor] = rv;
     gcmap[editColor] = gv;
     bcmap[editColor] = bv;
   }
   else {
-    rcmap[editColor] = rhDial.val;
-    gcmap[editColor] = gsDial.val;
-    bcmap[editColor] = bvDial.val;
+    rcmap[editColor] = (int)rhDial.val;
+    gcmap[editColor] = (int)gsDial.val;
+    bcmap[editColor] = (int)bvDial.val;
   }
 }
 
@@ -1561,9 +1560,9 @@
     gsDial.title = "Green";
     bvDial.title = "Blue";
 		   
-    DSetRange(&rhDial, 0, 255, rcmap[editColor], 16);
-    DSetRange(&gsDial, 0, 255, gcmap[editColor], 16);
-    DSetRange(&bvDial, 0, 255, bcmap[editColor], 16);
+    DSetRange(&rhDial, 0.0, 255.0, (double)rcmap[editColor], 1.0, 16.0);
+    DSetRange(&gsDial, 0.0, 255.0, (double)gcmap[editColor], 1.0, 16.0);
+    DSetRange(&bvDial, 0.0, 255.0, (double)bcmap[editColor], 1.0, 16.0);
 
     XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
     XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
@@ -1581,9 +1580,9 @@
 	    &h, &s, &v);
 
     if (h<0.0) h = 0.0;
-    DSetRange(&rhDial, 0, 360, (int) h, 5);
-    DSetRange(&gsDial, 0, 100, (int) (s*100), 5);
-    DSetRange(&bvDial, 0, 100, (int) (v*100), 5);
+    DSetRange(&rhDial, 0.0, 360.0,     h, 1.0, 5.0);
+    DSetRange(&gsDial, 0.0, 100.0, s*100, 1.0, 5.0);
+    DSetRange(&bvDial, 0.0, 100.0, v*100, 1.0, 5.0);
 
     XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
     XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
@@ -1891,7 +1890,7 @@
     }
 
     /* apply satDial value to s */
-    s = s + ((double) satDial.val) / 100.0;
+    s = s + satDial.val / 100.0;
     if (s<0.0) s = 0.0;
     if (s>1.0) s = 1.0;
 
@@ -2007,7 +2006,7 @@
 
   gs->hueRBnum = RBWhich(hueRB);
 
-  gs->satval = satDial.val;
+  gs->satval = (int)satDial.val;
   GetGrafState(&intGraf,&gs->istate);
   GetGrafState(&rGraf,  &gs->rstate);
   GetGrafState(&gGraf,  &gs->gstate);
@@ -2064,8 +2063,8 @@
     changed++;
   }
     
-  if (gs->satval != satDial.val) {
-    DSetVal(&satDial,gs->satval);
+  if (gs->satval != (int)satDial.val) {
+    DSetVal(&satDial,(double)gs->satval);
     changed++;
   }
 
@@ -3200,7 +3199,7 @@
 
   if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
 
-  if (satDial.val != 0) hsvmod++;
+  if (satDial.val != 0.0) hsvmod++;
 
   /* check intensity graf */
   for (i=0; i<256; i++) {
@@ -3284,7 +3283,7 @@
       }
 
       /* apply satDial value to s */
-      s = s + satDial.val;
+      s = s + (int)satDial.val;
       if (s<  0) s =   0;
       if (s>100) s = 100;
 
--- xv-3.10a/xvinfo.c	1994-12-22 17:34:41.000000000 -0500
+++ xv-3.10a/xvinfo.c	2009-03-28 11:12:07.000000000 -0400
@@ -264,9 +264,7 @@
 
   if (stnum == ISTR_WARNING && !ctrlUp && !infoUp && !anyBrowUp && 
       strlen(istrs[stnum])) {
-    OpenAlert(istrs[stnum]);
-    sleep(3);
-    CloseAlert();
+    fprintf (stderr, "%s\n", istrs[stnum]);
   }
 }
 
--- xv-3.10a/xvjpeg.c	1995-01-05 03:17:13.000000000 -0500
+++ xv-3.10a/xvjpeg.c	2009-03-28 11:12:07.000000000 -0400
@@ -51,11 +51,11 @@
 static    void         clickJD            PARM((int, int));
 static    void         doCmd              PARM((int));
 static    void         writeJPEG          PARM((void));
-METHODDEF void         xv_error_exit      PARM((j_common_ptr));
-METHODDEF void         xv_error_output    PARM((j_common_ptr));
-METHODDEF void         xv_prog_meter      PARM((j_common_ptr));
+METHODDEF(void)        xv_error_exit      PARM((j_common_ptr));
+METHODDEF(void)        xv_error_output    PARM((j_common_ptr));
+METHODDEF(void)        xv_prog_meter      PARM((j_common_ptr));
 static    unsigned int j_getc             PARM((j_decompress_ptr));
-METHODDEF boolean      xv_process_comment PARM((j_decompress_ptr));
+METHODDEF(boolean)     xv_process_comment PARM((j_decompress_ptr));
 static    int          writeJFIF          PARM((FILE *, byte *, int,int,int));
 
 
@@ -87,10 +87,10 @@
   
   XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
   
-  DCreate(&qDial, jpegW, 10, 10, 80, 100, 1, 100, 75, 5, 
+  DCreate(&qDial, jpegW, 10, 10, 80, 100, 1.0, 100.0, 75.0, 1.0, 5.0, 
 	  infofg, infobg, hicol, locol, "Quality", "%");
   
-  DCreate(&smDial, jpegW, 120, 10, 80, 100, 0, 100, 0, 5, 
+  DCreate(&smDial, jpegW, 120, 10, 80, 100, 0.0, 100.0, 0.0, 1.0, 5.0, 
 	  infofg, infobg, hicol, locol, "Smoothing", "%");
   
   BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
@@ -400,7 +400,7 @@
 
 
 /**************************************************/
-METHODDEF void xv_error_exit(cinfo) 
+METHODDEF (void) xv_error_exit(cinfo) 
      j_common_ptr cinfo;
 {
   my_error_ptr myerr;
@@ -412,7 +412,7 @@
 
 
 /**************************************************/
-METHODDEF void xv_error_output(cinfo) 
+METHODDEF (void) xv_error_output(cinfo) 
      j_common_ptr cinfo;
 {
   my_error_ptr myerr;
@@ -426,7 +426,7 @@
 
 
 /**************************************************/
-METHODDEF void xv_prog_meter(cinfo)
+METHODDEF (void) xv_prog_meter(cinfo)
      j_common_ptr cinfo;
 {
   struct jpeg_progress_mgr *prog;
@@ -671,7 +671,7 @@
 
 
 /**************************************************/
-METHODDEF boolean xv_process_comment(cinfo)
+METHODDEF (boolean) xv_process_comment(cinfo)
      j_decompress_ptr cinfo;
 {
   int          length, hasnull;
@@ -759,8 +759,9 @@
 
 
   jpeg_set_defaults(&cinfo);
-  jpeg_set_quality(&cinfo, qDial.val, TRUE);
-  cinfo.smoothing_factor = smDial.val;
+  jpeg_set_quality(&cinfo, (int)qDial.val, TRUE);
+  cinfo.smoothing_factor = (int)smDial.val;
+  cinfo.optimize_coding = TRUE;
 
 
   jpeg_start_compress(&cinfo, TRUE);
@@ -769,7 +770,7 @@
   /*** COMMENT HANDLING ***/
 
   sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
-	  CREATOR_STR, REVDATE, qDial.val, smDial.val);
+	  CREATOR_STR, REVDATE, (int)qDial.val, (int)smDial.val);
   
   if (picComments) {   /* append XV comment */
     char *sp, *sp1;  int done;
--- xv-3.10a/xvmisc.c	1995-01-13 18:41:34.000000000 -0500
+++ xv-3.10a/xvmisc.c	2009-03-28 11:12:07.000000000 -0400
@@ -469,12 +469,10 @@
   char *st;
 
   /* give 'em time to read message */
-  if (infoUp || ctrlUp || anyBrowUp) sleep(3); 
+  if (infoUp || ctrlUp || anyBrowUp) ; 
   else {
     st = GetISTR(ISTR_INFO);
-    OpenAlert(st);
-    sleep(3);
-    CloseAlert();
+    fprintf (stderr, "%s\n", st);
   }
 }
     
@@ -520,6 +518,10 @@
     if (tiffW) XDestroyWindow(theDisp, tiffW);
 #endif
 
+#ifdef HAVE_PNG
+    if (pngW)  XDestroyWindow(theDisp, pngW);
+#endif
+
     /* if NOT using stdcmap for images, free stdcmap */
     if (colorMapMode != CM_STDCMAP) { 
       int j;
@@ -716,6 +718,10 @@
 #ifdef HAVE_TIFF
   if (tiffW) XDefineCursor(theDisp, tiffW, otherc);
 #endif
+
+#ifdef HAVE_PNG
+  if (pngW)  XDefineCursor(theDisp, pngW, otherc);
+#endif
 }
 
 
--- xv-3.10a/xvpng.c	1969-12-31 19:00:00.000000000 -0500
+++ xv-3.10a/xvpng.c	2009-03-28 11:12:07.000000000 -0400
@@ -0,0 +1,991 @@
+/*
+ * xvpng.c - load and write routines for 'PNG' format pictures
+ *
+ * callable functions
+ *
+ *    CreatePNGW()
+ *    PNGDialog(vis)
+ *    PNGCheckEvent(xev)
+ *    PNGSaveParams(fname, col)
+ *    LoadPNG(fname, pinfo)
+ */
+
+/*#include "copyright.h"*/
+/* (c) 1995 by Alexander Lehmann <lehmann@mathematik.th-darmstadt.de>
+ *   this file is a suplement to xv and is supplied under the same copying
+ *   conditions (except the shareware part)
+ * Modified by Andreas Dilger <adilger@enel.ucalgary.ca> to fix
+ *   error handling for bad PNGs, add dialogs for interlacing and
+ *   compression selection, and upgrade to libpng-0.89
+ * The copyright will be passed on to JB at some future point if he
+ * so desires.
+ */
+
+#include "xv.h"
+
+#ifdef HAVE_PNG
+
+#include "png.h"
+
+/*** Stuff for PNG Dialog box ***/
+#define PWIDE 318
+#define PHIGH 215
+
+#define DISPLAY_GAMMA 2.20  /* Default display gamma */
+/* Default zlib compression level
+#define COMPRESSION   Z_BEST_COMPRESSION
+*/
+#define COMPRESSION   6
+
+#define DWIDE     86
+#define DHIGH    104
+#define PFX PWIDE-93
+#define PFY       44
+#define PFH       20
+
+#define P_BOK    0
+#define P_BCANC  1
+#define P_NBUTTS 2
+
+#define BUTTH    24
+
+#define LF       10   /* a.k.a. '\n' on ASCII machines */
+#define CR       13   /* a.k.a. '\r' on ASCII machines */
+
+/*** local functions ***/
+static    void drawPD         PARM((int, int, int, int));
+static    void clickPD        PARM((int, int));
+static    void doCmd          PARM((int));
+static    void writePNG       PARM((void));
+static    int  WritePNG       PARM((FILE *, byte *, int, int, int,
+                                    byte *, byte *, byte *, int));
+
+static    void png_xv_error   PARM((png_structp png_ptr,
+                                    png_const_charp message));
+static    void png_xv_warning PARM((png_structp png_ptr,
+                                    png_const_charp message));
+
+/*** local variables ***/
+static char *filename;
+static char *fbasename;
+static int   colorType;
+static int   read_anything;
+static double Display_Gamma = DISPLAY_GAMMA;
+
+static DIAL  cDial, gDial;
+static BUTT  pbut[P_NBUTTS];
+static CBUTT interCB;
+static CBUTT FdefCB, FnoneCB, FsubCB, FupCB, FavgCB, FPaethCB;
+
+/**************************************************************************/
+/* PNG SAVE DIALOG ROUTINES ***********************************************/
+/**************************************************************************/
+
+
+/*******************************************/
+void CreatePNGW()
+{
+  pngW = CreateWindow("xv png", "XVPNG", NULL,
+                      PWIDE, PHIGH, infofg, infobg, 0);
+  if (!pngW) FatalError("can't create PNG window!");
+
+  XSelectInput(theDisp, pngW, ExposureMask | ButtonPressMask | KeyPressMask);
+
+  DCreate(&cDial, pngW,  12, 25, DWIDE, DHIGH, (double)Z_NO_COMPRESSION,
+          (double)Z_BEST_COMPRESSION, COMPRESSION, 1.0, 3.0,
+          infofg, infobg, hicol, locol, "Compression", NULL);
+
+  DCreate(&gDial, pngW, DWIDE+27, 25, DWIDE, DHIGH, 1.0, 3.5,DISPLAY_GAMMA,0.01,0.2,
+          infofg, infobg, hicol, locol, "Disp. Gamma", NULL);
+
+  CBCreate(&interCB, pngW,  DWIDE+30, DHIGH+3*LINEHIGH+2, "interlace",
+           infofg, infobg, hicol, locol);
+
+  CBCreate(&FdefCB,   pngW, PFX, PFY, "Default",
+           infofg, infobg, hicol, locol);
+  FdefCB.val = 1;
+
+  CBCreate(&FnoneCB,  pngW, PFX, FdefCB.y + PFH + 4, "none",
+           infofg, infobg, hicol, locol);
+  CBCreate(&FsubCB,   pngW, PFX, FnoneCB.y + PFH, "sub",
+           infofg, infobg, hicol, locol);
+  CBCreate(&FupCB,    pngW, PFX, FsubCB.y  + PFH, "up",
+           infofg, infobg, hicol, locol);
+  CBCreate(&FavgCB,   pngW, PFX, FupCB.y   + PFH, "average",
+           infofg, infobg, hicol, locol);
+  CBCreate(&FPaethCB, pngW, PFX, FavgCB.y  + PFH, "Paeth",
+           infofg, infobg, hicol, locol);
+
+  FnoneCB.val = FsubCB.val = FupCB.val = FavgCB.val = FPaethCB.val = 1;
+  CBSetActive(&FnoneCB, !FdefCB.val);
+  CBSetActive(&FsubCB, !FdefCB.val);
+  CBSetActive(&FupCB, !FdefCB.val);
+  CBSetActive(&FavgCB, !FdefCB.val);
+  CBSetActive(&FPaethCB, !FdefCB.val);
+
+  BTCreate(&pbut[P_BOK], pngW, PWIDE-180-1, PHIGH-10-BUTTH-1, 80, BUTTH,
+          "Ok", infofg, infobg, hicol, locol);
+  BTCreate(&pbut[P_BCANC], pngW, PWIDE-90-1, PHIGH-10-BUTTH-1, 80, BUTTH,
+          "Cancel", infofg, infobg, hicol, locol);
+
+  XMapSubwindows(theDisp, pngW);          
+}
+
+
+/*******************************************/
+void PNGDialog(vis)
+     int vis;
+{
+  if (vis) {
+    CenterMapWindow(pngW, pbut[P_BOK].x + (int) pbut[P_BOK].w/2,
+                          pbut[P_BOK].y + (int) pbut[P_BOK].h/2,
+                    PWIDE, PHIGH);
+  }
+  else XUnmapWindow(theDisp, pngW);
+  pngUp = vis;
+}
+
+
+/*******************************************/
+int PNGCheckEvent(xev)
+     XEvent *xev;
+{
+  /* check event to see if it's for one of our subwindows.  If it is,
+     deal accordingly, and return '1'.  Otherwise, return '0' */
+
+  int rv;
+  rv = 1;
+
+  if (!pngUp) return 0;
+
+  if (xev->type == Expose) {
+    int x,y,w,h;
+    XExposeEvent *e = (XExposeEvent *) xev;
+    x = e->x; y = e->y; w = e->width; h = e->height;
+
+    /* throw away excess expose events for 'dumb' windows */
+    if (e->count > 0 && (e->window == cDial.win)) {}
+
+    else if (e->window == pngW)        drawPD(x, y, w, h);
+    else if (e->window == cDial.win)   DRedraw(&cDial);
+    else if (e->window == gDial.win)   DRedraw(&gDial);
+    else rv = 0;
+  }
+
+  else if (xev->type == ButtonPress) {
+    XButtonEvent *e = (XButtonEvent *) xev;
+    int x,y;
+    x = e->x;  y = e->y;
+    
+    if (e->button == Button1) {
+      if      (e->window == pngW)       clickPD(x,y);
+      else if (e->window == cDial.win)  DTrack(&cDial,x,y);
+      else if (e->window == gDial.win)  DTrack(&gDial,x,y);
+      else rv = 0;
+    }  /* button1 */
+    else rv = 0;
+  }  /* button press */
+
+  else if (xev->type == KeyPress) {
+    XKeyEvent *e = (XKeyEvent *) xev;
+    char buf[128];  KeySym ks;
+    int stlen;
+    
+    stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
+    buf[stlen] = '\0';
+    
+    RemapKeyCheck(ks, buf, &stlen);
+    
+    if (e->window == pngW) {
+      if (stlen) {
+        if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
+          FakeButtonPress(&pbut[P_BOK]);
+        }
+        else if (buf[0] == '\033') {            /* ESC */
+          FakeButtonPress(&pbut[P_BCANC]);
+        }
+      }
+    }
+    else rv = 0;
+  }
+  else rv = 0;
+
+  if (rv==0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
+    XBell(theDisp, 50);
+    rv = 1;   /* eat it */
+  }
+
+  return rv;
+}
+
+
+/*******************************************/
+void PNGSaveParams(fname, col)
+     char *fname;
+     int col;
+{
+  filename = fname;
+  colorType = col;
+}
+
+
+/*******************************************/
+static void drawPD(x, y, w, h)
+     int x, y, w, h;
+{
+  char *title   = "Save PNG file...";
+
+  char ctitle1[20];
+  char *ctitle2 = "Useful range";
+  char *ctitle3 = "is 2 - 7.";
+  char *ctitle4 = "Uncompressed = 0";
+
+  char *ftitle  = "Row Filters:";
+
+  char gtitle[20];
+
+  int i;
+  XRectangle xr;
+  
+  xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
+  XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
+
+  XSetForeground(theDisp, theGC, infofg);
+  XSetBackground(theDisp, theGC, infobg);
+
+  for (i=0; i<P_NBUTTS; i++) BTRedraw(&pbut[i]);
+
+  DrawString(pngW,       15,  6+ASCENT,                          title);
+
+  sprintf(ctitle1, "Default = %d", COMPRESSION);
+  DrawString(pngW,       18,  6+DHIGH+cDial.y+ASCENT,            ctitle1);
+  DrawString(pngW,       17,  6+DHIGH+cDial.y+ASCENT+LINEHIGH,   ctitle2);
+  DrawString(pngW,       17,  6+DHIGH+cDial.y+ASCENT+2*LINEHIGH, ctitle3);
+  DrawString(pngW,       17,  6+DHIGH+cDial.y+ASCENT+3*LINEHIGH, ctitle4);
+
+  sprintf(gtitle, "Default = %g", DISPLAY_GAMMA);
+  DrawString(pngW, DWIDE+30,  6+DHIGH+gDial.y+ASCENT,            gtitle);
+
+  ULineString(pngW, FdefCB.x, FdefCB.y-3-DESCENT, ftitle);
+  XDrawRectangle(theDisp, pngW, theGC, FdefCB.x-11, FdefCB.y-LINEHIGH-3,
+                                       93, 8*LINEHIGH+15);
+  CBRedraw(&FdefCB);
+  XDrawLine(theDisp, pngW, theGC, FdefCB.x-11, FdefCB.y+LINEHIGH+4,
+                                  FdefCB.x+82, FdefCB.y+LINEHIGH+4);
+
+  CBRedraw(&FnoneCB);
+  CBRedraw(&FupCB);
+  CBRedraw(&FsubCB);
+  CBRedraw(&FavgCB);
+  CBRedraw(&FPaethCB);
+
+  CBRedraw(&interCB);
+
+  XSetClipMask(theDisp, theGC, None);
+}
+
+
+/*******************************************/
+static void clickPD(x,y)
+     int x,y;
+{
+  int i;
+  BUTT *bp;
+
+  /* check BUTTs */
+  
+  for (i=0; i<P_NBUTTS; i++) {
+    bp = &pbut[i];
+    if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
+  }
+  
+  if (i<P_NBUTTS) {  /* found one */
+    if (BTTrack(bp)) doCmd(i);
+  }
+
+  /* check CBUTTs */
+
+  else if (CBClick(&FdefCB,x,y)) {
+    int oldval = FdefCB.val;
+
+    CBTrack(&FdefCB);
+
+    if (oldval != FdefCB.val)
+    {
+      CBSetActive(&FnoneCB, !FdefCB.val);
+      CBSetActive(&FsubCB, !FdefCB.val);
+      CBSetActive(&FupCB, !FdefCB.val);
+      CBSetActive(&FavgCB, !FdefCB.val);
+      CBSetActive(&FPaethCB, !FdefCB.val);
+
+      CBRedraw(&FnoneCB);
+      CBRedraw(&FupCB);
+      CBRedraw(&FsubCB);
+      CBRedraw(&FavgCB);
+      CBRedraw(&FPaethCB);
+    }
+  }
+  else if (CBClick(&FnoneCB,x,y))  CBTrack(&FnoneCB);
+  else if (CBClick(&FsubCB,x,y))   CBTrack(&FsubCB);
+  else if (CBClick(&FupCB,x,y))    CBTrack(&FupCB);
+  else if (CBClick(&FavgCB,x,y))   CBTrack(&FavgCB);
+  else if (CBClick(&FPaethCB,x,y)) CBTrack(&FPaethCB);
+  else if (CBClick(&interCB,x,y))  CBTrack(&interCB);
+}
+
+
+/*******************************************/
+static void doCmd(cmd)
+     int cmd;
+{
+  switch (cmd) {
+  case P_BOK: {
+    char *fullname;
+
+    writePNG();
+    PNGDialog(0);
+    
+    fullname = GetDirFullName();
+    if (!ISPIPE(fullname[0])) {
+      XVCreatedFile(fullname);
+      StickInCtrlList(0);
+    }
+  }
+    break;
+
+  case P_BCANC:  PNGDialog(0);  break;
+
+  default:        break;
+  }
+}
+
+
+/*******************************************/
+static void writePNG()
+{
+  FILE       *fp;
+  int         w, h, nc, rv, ptype, pfree;
+  byte       *inpix, *rmap, *gmap, *bmap;
+
+  fp = OpenOutFile(filename);
+  if (!fp) return;
+
+  fbasename = BaseName(filename);
+
+  WaitCursor();
+  inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
+
+  rv = WritePNG(fp, inpix, ptype, w, h, rmap, gmap, bmap, nc);
+
+  SetCursors(-1);
+
+  if (CloseOutFile(fp, filename, rv) == 0) DirBox(0);
+
+  if (pfree) free(inpix);
+}
+
+
+/*******************************************/
+int WritePNG(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols)
+     FILE *fp;
+     byte *pic;
+     int   ptype, w, h;
+     byte *rmap, *gmap, *bmap;
+     int   numcols;
+{
+  png_struct *png_ptr;
+  png_info   *info_ptr;
+  png_color   palette[256];
+  png_textp   text;
+  byte        remap[256];
+  int         i, filter, linesize = 0, pass;
+  byte       *p, *png_line;
+  char        software[256];
+  char       *savecmnt = NULL;
+
+  if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
+       png_xv_error, png_xv_warning)) == NULL) {
+    FatalError("malloc failure in WritePNG");
+  }
+
+  if ((info_ptr = png_create_info_struct(png_ptr)) == NULL)
+  {
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+    FatalError("malloc failure in WritePNG");
+  }
+
+  if (setjmp(png_ptr->jmpbuf)) {
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+    return -1;
+  }
+
+  png_init_io(png_ptr, fp);
+
+  png_set_compression_level(png_ptr, (int)cDial.val);
+
+  /* Don't bother filtering if we aren't compressing the image */
+  if (FdefCB.val)
+  {
+    if ((int)cDial.val == 0)
+      png_set_filter(png_ptr, 0, PNG_FILTER_NONE);
+  }
+  else
+  {
+    filter  = FnoneCB.val  ? PNG_FILTER_NONE  : 0;
+    filter |= FsubCB.val   ? PNG_FILTER_SUB   : 0;
+    filter |= FupCB.val    ? PNG_FILTER_UP    : 0;
+    filter |= FavgCB.val   ? PNG_FILTER_AVG   : 0;
+    filter |= FPaethCB.val ? PNG_FILTER_PAETH : 0;
+
+    png_set_filter(png_ptr, 0, filter);
+  }
+
+  info_ptr->width = w;
+  info_ptr->height = h;
+
+  info_ptr->interlace_type = interCB.val ? 1 : 0;
+
+  if (colorType == F_FULLCOLOR || colorType == F_REDUCED) {
+    if(ptype == PIC24) {
+      linesize = 3*w;
+      info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+      info_ptr->bit_depth = 8;
+    } else {
+      linesize = w;
+      info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+      if(numcols <= 2)
+        info_ptr->bit_depth = 1;
+      else
+      if(numcols <= 4)
+        info_ptr->bit_depth = 2;
+      else
+      if(numcols <= 16)
+        info_ptr->bit_depth = 4;
+      else
+        info_ptr->bit_depth = 8;
+
+      for(i = 0; i < numcols; i++) {
+        palette[i].red   = rmap[i];
+        palette[i].green = gmap[i];
+        palette[i].blue  = bmap[i];
+      }
+      info_ptr->num_palette = numcols;
+      info_ptr->palette = palette;
+      info_ptr->valid |= PNG_INFO_PLTE;
+    }
+  }
+
+  else if(colorType == F_GREYSCALE || colorType == F_BWDITHER) {
+    info_ptr->color_type = PNG_COLOR_TYPE_GRAY;
+    if(colorType == F_BWDITHER) {
+      /* shouldn't happen */
+      if (ptype == PIC24) FatalError("PIC24 and B/W Stipple in WritePNG()");
+
+      info_ptr->bit_depth = 1;
+      if(MONO(rmap[0], gmap[0], bmap[0]) > MONO(rmap[1], gmap[1], bmap[1])) {
+        remap[0] = 1;
+        remap[1] = 0;
+      }
+      else {
+        remap[0] = 0;
+        remap[1] = 1;
+      }
+      linesize = w;
+    }
+    else {
+      if(ptype == PIC24) {
+        linesize = w*3;
+        info_ptr->bit_depth = 8;
+      }
+      else {
+        int low_presc;
+
+        linesize = w;
+
+        for(i = 0; i < numcols; i++)
+          remap[i] = MONO(rmap[i], gmap[i], bmap[i]);
+
+        for(; i < 256; i++)
+          remap[i]=0;
+
+        info_ptr->bit_depth = 8;
+
+        /* Note that this fails most of the time because of gamma */
+        /* try to adjust to 4 bit prescision grayscale */
+
+        low_presc=1;
+
+        for(i = 0; i < numcols; i++) {
+          if((remap[i] & 0x0f) * 0x11 != remap[i]) {
+            low_presc = 0;
+            break;
+          }
+        }
+
+        if(low_presc) {
+          for(i = 0; i < numcols; i++) {
+            remap[i] &= 0xf;
+          }
+          info_ptr->bit_depth = 4;
+
+          /* try to adjust to 2 bit prescision grayscale */
+
+          for(i = 0; i < numcols; i++) {
+            if((remap[i] & 0x03) * 0x05 != remap[i]) {
+              low_presc = 0;
+              break;
+            }
+          }
+        }
+
+        if(low_presc) {
+          for(i = 0; i < numcols; i++) {
+            remap[i] &= 3;
+          }
+          info_ptr->bit_depth = 2;
+
+          /* try to adjust to 1 bit prescision grayscale */
+
+          for(i = 0; i < numcols; i++) {
+            if((remap[i] & 0x01) * 0x03 != remap[i]) {
+              low_presc = 0;
+              break;
+            }
+          }
+        }
+
+        if(low_presc) {
+          for(i = 0; i < numcols; i++) {
+            remap[i] &= 1;
+          }
+          info_ptr->bit_depth = 1;
+        }
+      }
+    }
+  }
+
+  else
+    png_error(png_ptr, "Unknown colorstyle in WritePNG");
+
+  if ((text = (png_textp)malloc(sizeof(png_text)))) {
+    sprintf(software, "XV %s", REVDATE);
+
+    text->compression = -1;
+    text->key = "Software";
+    text->text = software;
+    text->text_length = strlen(text->text);
+
+    info_ptr->max_text = 1;
+    info_ptr->num_text = 1;
+    info_ptr->text = text;
+  }
+
+  Display_Gamma = gDial.val;  /* Save the current gamma for loading */
+
+  info_ptr->gamma = 1.0/gDial.val;
+  info_ptr->valid |= PNG_INFO_gAMA;
+
+  png_write_info(png_ptr, info_ptr);
+
+  if(info_ptr->bit_depth < 8)
+    png_set_packing(png_ptr);
+
+  pass=png_set_interlace_handling(png_ptr);
+
+  if((png_line = malloc(linesize)) == NULL)
+    png_error(png_ptr, "cannot allocate temp image line");
+
+  for(i = 0; i < pass; i++) {
+    int j;
+    p = pic;
+    for(j = 0; j < h; j++) {
+      if(info_ptr->color_type == PNG_COLOR_TYPE_GRAY) {
+        int k;
+        for(k = 0; k < w; k++)
+          png_line[k] = ptype==PIC24 ? MONO(p[k*3], p[k*3+1], p[k*3+2]) :
+                                       remap[p[k]];
+        png_write_row(png_ptr, png_line);
+      } else  /* RGB or palette */
+        png_write_row(png_ptr, p);
+      if((j & 0x1f) == 0) WaitCursor();
+      p += linesize;
+    }
+  }
+
+  free(png_line);
+
+  if (text)
+  {
+    if (picComments && strlen(picComments) &&
+        (savecmnt = (char *)malloc((strlen(picComments) + 1)*sizeof(char)))) {
+      png_textp tp;
+      char *comment, *key;
+
+      strcpy(savecmnt, picComments);
+      key = savecmnt;
+      tp = text;
+      info_ptr->num_text = 0;
+
+      comment = strchr(key, ':');
+
+      do  {
+        /* Allocate a larger structure for comments if necessary */
+        if (info_ptr->num_text >= info_ptr->max_text)
+        {
+          if ((tp =
+              realloc(text, (info_ptr->num_text + 2)*sizeof(png_text))) == NULL)
+          {
+            break;
+          }
+          else
+          {
+            text = tp;
+            tp = &text[info_ptr->num_text];
+            info_ptr->max_text += 2;
+          }
+        }
+
+        /* See if it looks like a PNG keyword from LoadPNG */
+        /* GRR: should test for strictly < 80, right? (key = 1-79 chars only) */
+        if(comment && comment[1] == ':' && comment - key <= 80) {
+          *(comment++) = '\0';
+          *(comment++) = '\0';
+
+          /* If the comment is the 'Software' chunk XV writes, we remove it,
+             since we have already stored one */
+          if (strcmp(key, "Software") == 0 && strncmp(comment, "XV", 2) == 0) {
+            key = strchr(comment, '\n');
+            if(key)
+              key++; /* skip \n */
+            comment = strchr(key, ':');
+          }
+          /* We have another keyword and/or comment to write out */
+          else {
+            tp->key = key;
+            tp->text = comment;
+
+            /* We have to find the end of this comment, and the next keyword
+               if there is one */
+            for (; NULL != (key = comment = strchr(comment, ':')); comment++)
+              if (key[1] == ':')
+                break;
+
+            /* It looks like another keyword, go backward to the beginning */
+            if (key) {
+              while(key > tp->text && *key != '\n')
+                key--;
+
+              if (key > tp->text && comment - key <= 80) {
+                *key = '\0';
+                key++;
+              }
+            }
+
+            tp->text_length = strlen(tp->text);
+
+            /* We don't have another keyword, so remove the last newline */
+            if (!key && tp->text[tp->text_length - 1] == '\n')
+            {
+              tp->text[tp->text_length] = '\0';
+              tp->text_length--;
+            }
+
+            tp->compression = tp->text_length > 640 ? 0 : -1;
+            info_ptr->num_text++;
+            tp++;
+          }
+        }
+        /* Just a generic comment:  make sure line-endings are valid for PNG */
+        else {
+          char *p=key, *q=key;     /* only deleting chars, not adding any */
+
+          while (*p) {
+            if (*p == CR) {        /* lone CR or CR/LF:  EOL either way */
+              *q++ = LF;           /* LF is the only allowed PNG line-ending */
+              if (p[1] == LF)      /* get rid of any original LF */
+                ++p;
+            } else if (*p == LF)   /* lone LF */
+              *q++ = LF;
+            else
+              *q++ = *p;
+            ++p;
+          }
+          *q = '\0';               /* unnecessary...but what the heck */
+          tp->key = "Comment";
+          tp->text = key;
+          tp->text_length = q - key;
+          tp->compression = tp->text_length > 750 ? 0 : -1;
+          info_ptr->num_text++;
+          key = NULL;
+        }
+      } while (key && *key);
+    }
+    else
+    {
+      info_ptr->num_text = 0;
+    }
+  }
+  info_ptr->text = text;
+
+  png_convert_from_time_t(&(info_ptr->mod_time), time(NULL));
+  info_ptr->valid |= PNG_INFO_tIME;
+
+  png_write_end(png_ptr, info_ptr);
+  fflush(fp);   /* just in case we core-dump before finishing... */
+
+  if (text)
+  {
+    free(text);
+    /* must do this or png_destroy_write_struct() 0.97+ will free text again: */
+    info_ptr->text = (png_textp)NULL;
+    if (savecmnt)
+    {
+      free(savecmnt);
+      savecmnt = (char *)NULL;
+    }
+  }
+
+  png_destroy_write_struct(&png_ptr, &info_ptr);
+
+  return 0;
+}
+
+
+/*******************************************/
+int LoadPNG(fname, pinfo)
+     char    *fname;
+     PICINFO *pinfo;
+/*******************************************/
+{
+  /* returns '1' on success */
+
+  FILE  *fp;
+  png_struct *png_ptr;
+  png_info *info_ptr;
+  png_color_16 my_background;
+  int i,j;
+  int linesize;
+  int filesize;
+  int pass;
+  size_t commentsize;
+
+  fbasename = BaseName(fname);
+
+  pinfo->pic     = (byte *) NULL;
+  pinfo->comment = (char *) NULL;
+
+  read_anything=0;
+
+  /* open the file */
+  fp = xv_fopen(fname,"r");
+  if (!fp)
+  {
+    SetISTR(ISTR_WARNING,"%s:  can't open file", fname);
+    return 0;
+  }
+
+  /* find the size of the file */
+  fseek(fp, 0L, 2);
+  filesize = ftell(fp);
+  fseek(fp, 0L, 0);
+  
+  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
+                                   png_xv_error, png_xv_warning);
+  if(!png_ptr) {
+    fclose(fp);
+    FatalError("malloc failure in LoadPNG");
+  }
+
+  info_ptr = png_create_info_struct(png_ptr);
+
+  if(!info_ptr) {
+    fclose(fp);
+    png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
+    FatalError("malloc failure in LoadPNG");
+  }
+
+  if(setjmp(png_ptr->jmpbuf)) {
+    fclose(fp);
+    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+    if(!read_anything) {
+      if(pinfo->pic) {
+        free(pinfo->pic);
+        pinfo->pic = NULL;
+      }
+      if(pinfo->comment) {
+        free(pinfo->comment);
+        pinfo->comment = NULL;
+      }
+    }
+    return read_anything;
+  }
+
+  png_init_io(png_ptr, fp);
+  png_read_info(png_ptr, info_ptr);
+
+  pinfo->w = pinfo->normw = info_ptr->width;
+  pinfo->h = pinfo->normh = info_ptr->height;
+
+  pinfo->frmType = F_PNG;
+
+  sprintf(pinfo->fullInfo, "PNG, %d bit ",
+          info_ptr->bit_depth * info_ptr->channels);
+
+  switch(info_ptr->color_type) {
+    case PNG_COLOR_TYPE_PALETTE:
+      strcat(pinfo->fullInfo, "palette color");
+      break;
+
+    case PNG_COLOR_TYPE_GRAY:
+      strcat(pinfo->fullInfo, "grayscale");
+      break;
+
+    case PNG_COLOR_TYPE_GRAY_ALPHA:
+      strcat(pinfo->fullInfo, "grayscale+alpha");
+      break;
+
+    case PNG_COLOR_TYPE_RGB:
+      strcat(pinfo->fullInfo, "truecolor");
+      break;
+
+    case PNG_COLOR_TYPE_RGB_ALPHA:
+      strcat(pinfo->fullInfo, "truecolor+alpha");
+      break;
+  }
+
+  sprintf(pinfo->fullInfo + strlen(pinfo->fullInfo),
+	  ", %sinterlaced. (%d bytes)",
+	  info_ptr->interlace_type ? "" : "non-", filesize);
+
+  sprintf(pinfo->shrtInfo, "%dx%d PNG", info_ptr->width, info_ptr->height);
+
+  if (info_ptr->bit_depth < 8)
+      png_set_packing(png_ptr);
+
+  if (info_ptr->valid & PNG_INFO_gAMA)
+    png_set_gamma(png_ptr, Display_Gamma, info_ptr->gamma);
+  else
+    png_set_gamma(png_ptr, Display_Gamma, 0.45);
+
+  if (info_ptr->valid & PNG_INFO_bKGD)
+    png_set_background(png_ptr, &info_ptr->background,
+                       PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+  else {
+    my_background.red = my_background.green = my_background.blue =
+      my_background.gray = 0;
+    png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN,
+                       0, Display_Gamma);
+  }
+
+  if (info_ptr->bit_depth == 16)
+    png_set_strip_16(png_ptr);
+
+  if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
+      info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+  {
+    if (info_ptr->bit_depth == 1)
+      pinfo->colType = F_BWDITHER;
+    else
+      pinfo->colType = F_GREYSCALE;
+    png_set_expand(png_ptr);
+  }
+
+  pass=png_set_interlace_handling(png_ptr);
+
+  png_read_update_info(png_ptr, info_ptr);
+
+  if(info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+     info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+    linesize = pinfo->w * 3;
+    pinfo->colType = F_FULLCOLOR;
+    pinfo->type = PIC24;
+  } else {
+    linesize = pinfo->w;
+    pinfo->type = PIC8;
+    if(info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
+       info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+      for(i = 0; i < 256; i++)
+        pinfo->r[i] = pinfo->g[i] = pinfo->b[i] = i;
+    } else {
+      pinfo->colType = F_FULLCOLOR;
+      for(i = 0; i < info_ptr->num_palette; i++) {
+        pinfo->r[i] = info_ptr->palette[i].red;
+        pinfo->g[i] = info_ptr->palette[i].green;
+        pinfo->b[i] = info_ptr->palette[i].blue;
+      }
+    }
+  }
+  pinfo->pic = calloc((size_t)(linesize*pinfo->h), (size_t)1);
+
+  if(!pinfo->pic) {
+    png_error(png_ptr, "can't allocate space for PNG image");
+  }
+
+  png_start_read_image(png_ptr);
+
+  for(i = 0; i < pass; i++) {
+    byte *p = pinfo->pic;
+    for(j = 0; j < pinfo->h; j++) {
+      png_read_row(png_ptr, p, NULL);
+      read_anything = 1;
+      if((j & 0x1f) == 0) WaitCursor();
+      p += linesize;
+    }
+  }
+
+  png_read_end(png_ptr, info_ptr);
+
+  if(info_ptr->num_text > 0) {
+    commentsize = 1;
+
+    for(i = 0; i < info_ptr->num_text; i++)
+      commentsize += strlen(info_ptr->text[i].key) + 1 +
+                     info_ptr->text[i].text_length + 2;
+
+    if((pinfo->comment = malloc(commentsize)) == NULL) {
+      png_warning(png_ptr,"can't allocate comment string");
+    }
+    else {
+      pinfo->comment[0] = '\0';
+      for(i = 0; i < info_ptr->num_text; i++) {
+        strcat(pinfo->comment, info_ptr->text[i].key);
+        strcat(pinfo->comment, "::");
+        strcat(pinfo->comment, info_ptr->text[i].text);
+        strcat(pinfo->comment, "\n");
+      }
+    }
+  }
+
+  png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
+
+  fclose(fp);
+
+  return 1;
+}
+
+
+/*******************************************/
+static void
+png_xv_error(png_ptr, message)
+     png_structp png_ptr;
+     png_const_charp message;
+{
+  SetISTR(ISTR_WARNING,"%s:  libpng error: %s", fbasename, message);
+
+  longjmp(png_ptr->jmpbuf, 1);
+}
+
+
+/*******************************************/
+static void
+png_xv_warning(png_ptr, message)
+     png_structp png_ptr;
+     png_const_charp message;
+{
+  if (!png_ptr)
+    return;
+
+  SetISTR(ISTR_WARNING,"%s:  libpng warning: %s", fbasename, message);
+}
+
+#endif
--- xv-3.10a/xvpopup.c	1995-01-19 13:09:31.000000000 -0500
+++ xv-3.10a/xvpopup.c	2009-03-28 11:12:07.000000000 -0400
@@ -200,14 +200,14 @@
     
     if (!padHaveDooDads) {
       DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
-	      1, 2048, pWIDE, 10,
+	      1.0, 2048.0, (double)pWIDE, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Width", NULL);
       DCreate(&padHDial, popW, 16+1+75, puhigh-16-100-1,75,100,
-	      1, 2048, pHIGH, 10,
+	      1.0, 2048.0, (double)pHIGH, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Height", NULL);
 
       DCreate(&padODial, popW, 16+1+75+75+9, puhigh-16-100-1,75,100,
-	      0, 100, 100, 10,
+	      0.0, 100.0, 100.0, 1.0, 10.0,
 	      infofg, infobg, hicol, locol, "Opaque", NULL);
 
       MBCreate(&padMthdMB, popW, 100-2+44, 10, 140, 19, NULL,
@@ -258,9 +258,9 @@
   else if (poptyp == ISPAD) {
     BTSetActive(&bts[0], (int) strlen(gsBuf));
     i = pWIDE * 3;  RANGE(i,2048,9999);  
-    DSetRange(&padWDial, 1, i, padWDial.val, 10);
+    DSetRange(&padWDial, 1.0, (double)i, padWDial.val, 1.0, 10.0);
     i = pHIGH * 3;  RANGE(i,2048,9999);  
-    DSetRange(&padHDial, 1, i, padHDial.val, 10);
+    DSetRange(&padHDial, 1.0, (double)i, padHDial.val, 1.0, 10.0);
 
     DSetActive(&padWDial, (padMode!=PAD_LOAD));  /* DSetRange activates dial */
     DSetActive(&padHDial, (padMode!=PAD_LOAD));
@@ -465,9 +465,9 @@
   changedGSBuf();      /* careful!  popW doesn't exist yet! */
 
   if (padHaveDooDads) { 
-    oldW = padWDial.val;  
-    oldH = padHDial.val;
-    oldO = padODial.val;
+    oldW = (int)padWDial.val;  
+    oldH = (int)padHDial.val;
+    oldO = (int)padODial.val;
   }
   else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
 
@@ -486,9 +486,9 @@
   }
 
   if (rv == 1) {   /* cancelled:  restore normal values */
-    DSetVal(&padWDial, oldW);
-    DSetVal(&padHDial, oldH);
-    DSetVal(&padODial, oldO);
+    DSetVal(&padWDial, (double)oldW);
+    DSetVal(&padHDial, (double)oldH);
+    DSetVal(&padODial, (double)oldO);
   }
 
   XUnmapWindow(theDisp, padWDial.win);
@@ -498,9 +498,9 @@
   /* load up return values */
   *pMode   = padMode;  
   *pStr    = padBuf;  
-  *pWide   = padWDial.val;
-  *pHigh   = padHDial.val;
-  *pOpaque = padODial.val;
+  *pWide   = (int)padWDial.val;
+  *pHigh   = (int)padHDial.val;
+  *pOpaque = (int)padODial.val;
   *pOmode  = padOMode;
 
   return rv;
@@ -972,8 +972,8 @@
   else if (popUp == ISPAD) {
     if (PTINRECT(x, y, padDButt.x, padDButt.y, padDButt.w, padDButt.h)) {
       if (BTTrack(&padDButt)) {
-	DSetVal(&padWDial, pWIDE);
-	DSetVal(&padHDial, pHIGH);
+	DSetVal(&padWDial, (double)pWIDE);
+	DSetVal(&padHDial, (double)pHIGH);
       }
     }
 
--- xv-3.10a/xvps.c	1994-12-22 17:34:42.000000000 -0500
+++ xv-3.10a/xvps.c	2009-03-28 11:12:07.000000000 -0400
@@ -139,9 +139,9 @@
   CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg, hicol, locol);
   CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg, hicol, locol);
 
-  DCreate(&xsDial, psW, 240, 30, 80, 100, 10, 800, 100, 5, 
+  DCreate(&xsDial, psW, 240, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0, 
 	  infofg, infobg, hicol, locol, "Width", "%");
-  DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5, 
+  DCreate(&ysDial, psW, 331, 30, 80, 100, 10.0, 800.0, 100.0, 0.5, 5.0, 
 	  infofg, infobg, hicol, locol, "Height", "%");
   xsDial.drawobj = changedScale;
   ysDial.drawobj = changedScale;
@@ -236,10 +236,10 @@
 
   if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
     if (def_int >= 10 && def_int <= 720) {
-      int i = (int) ((PIX2INCH * 100) / def_int);
+      double v = (PIX2INCH * 100) / def_int;
 
-      DSetVal(&xsDial, i);
-      DSetVal(&ysDial, i);
+      DSetVal(&xsDial, v);
+      DSetVal(&ysDial, v);
     }
   }
 
@@ -836,7 +836,7 @@
   if (scx < scy) { sz_iny = h * scx; }
             else { sz_inx = w * scy; }
 
-  DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
+  DSetVal(&xsDial, 100 * (sz_inx * PIX2INCH) / w);
   DSetVal(&ysDial, xsDial.val);
 
   sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
@@ -891,7 +891,7 @@
   int   i, j, q, err, rpix, gpix, bpix, nc, ptype;
   int   iw, ih, ox, oy, slen, lwidth, bits, colorps, w, h, pfree;
   double iwf, ihf;
-  byte *inpix, *rmap, *gmap, *bmap;
+  byte *save_inpix, *inpix, *rmap, *gmap, *bmap;
 
   slen = bits = colorps = 0;
 
@@ -901,7 +901,8 @@
 
   WaitCursor();
   
-  inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
+  save_inpix = inpix =
+	GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
 
     
   /* printed image will have size iw,ih (in picas) */
@@ -1123,7 +1124,7 @@
   fprintf(fp,"origstate restore\n\n");
   fprintf(fp,"%%%%Trailer\n");
 
-  if (pfree) free(inpix);
+  if (pfree) free(save_inpix);
 
   if (CloseOutFile(fp, filename, (err==EOF)) == 0) {
     DirBox(0);
@@ -1621,7 +1622,7 @@
   SetISTR(ISTR_INFO, "Running '%s'...", GS_PATH);
 
   sprintf(tmp1, "Running %s", tmp);
-  if (!quick && !ctrlUp && !infoUp) OpenAlert(tmp1);
+  if (!quick && !ctrlUp && !infoUp) fprintf (stderr, "%s\n", tmp1);
 
 #ifndef VMS
   gsresult = system(tmp);
@@ -1631,8 +1632,6 @@
 
   WaitCursor();
 
-  if (!quick && !ctrlUp && !infoUp) CloseAlert();
-
   /* figure out how many page files were created, by stating files. 
      breaks out on first failure, assuming there won't be any more after
      that, and it would complicate matters too much anyhow... */
--- xv-3.10a/xvsmooth.c	1994-12-22 17:34:42.000000000 -0500
+++ xv-3.10a/xvsmooth.c	2009-03-28 11:12:07.000000000 -0400
@@ -65,10 +65,13 @@
      returns a dwide*dhigh 24bit image, or NULL on failure (malloc) */
   /* rmap,gmap,bmap should be 'desired' colors */
 
+  /* DANGER:  This code assumes that a right-shift on signed integers is
+     performed arithmetically, i.e. the sign bit is copied to the right.  */
+
   byte *pic24, *pp;
-  int  *cxtab, *pxtab;
-  int   y1Off, cyOff;
-  int   ex, ey, cx, cy, px, py, apx, apy, x1, y1;
+  int  *pxtab;
+  int   ex, ey, px, py, x0, x1, y0, y1;
+  int   y0off, y1off;
   int   cA, cB, cC, cD;
   int   pA, pB, pC, pD;
   int   retval, bperpix;
@@ -98,69 +101,61 @@
   else {
     /* dwide >= swide && dhigh >= shigh */
 
-    /* cx,cy = original pixel in pic824.  px,py = relative position 
-       of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%.  
-       0,0 = middle of pixel */
-
-    /* we can save a lot of time by precomputing cxtab[] and pxtab[], both
-       dwide arrays of ints that contain values for the equations:
-         cx = (ex * swide) / dwide;
-         px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */
-
-    cxtab = (int *) malloc(dwide * sizeof(int));
-    if (!cxtab) { free(pic24);  return NULL; }
+    /* px, py = location on original image, in units of 1/256 pixel
+       We can save time by precomputing all values of px.  */
 
     pxtab = (int *) malloc(dwide * sizeof(int));
-    if (!pxtab) { free(pic24);  free(cxtab);  return NULL; }
-
-    for (ex=0; ex<dwide; ex++) {
-      cxtab[ex] = (ex * swide) / dwide;
-      pxtab[ex] = (((ex * swide)* 100) / dwide) 
-	           - (cxtab[ex] * 100) - 50;
-    }
+    if (!pxtab) { free(pic24);  return NULL; }
     
-    for (ey=0; ey<dhigh; ey++) {
+    for (ex=0; ex < dwide; ex++)
+      pxtab[ex] = ((ex << 8) + 128) * swide / dwide - 128;
+    
+    for (ey=0; ey < dhigh; ey++) {
       byte *pptr, rA, gA, bA, rB, gB, bB, rC, gC, bC, rD, gD, bD;
 
       ProgressMeter(0, (dhigh)-1, ey, "Smooth");
 
-      cy = (ey * shigh) / dhigh;
-      py = (((ey * shigh) * 100) / dhigh) - (cy * 100) - 50;
-      if (py<0) { y1 = cy-1;  if (y1<0) y1=0; }
-           else { y1 = cy+1;  if (y1>shigh-1) y1=shigh-1; }
+      py = ((ey << 8) + 128) * shigh / dhigh - 128;
+      y0 = py >> 8;			/* Put integer part in y0 */
+      y1 = y0 + 1;
+      py &= 255;			/* Keep fractional part in py */
+
+      if (y0 < 0)	y0 = y1 = 0;
+      if (y1 >= shigh)	y0 = y1 = shigh-1;
 
-      cyOff = cy * swide * bperpix;    /* current line */
-      y1Off = y1 * swide * bperpix;    /* up or down one line, depending */
+      y0off = y0 * swide * bperpix;	/* current line */
+      y1off = y1 * swide * bperpix;	/* one line down */
 
       if ((ey&15) == 0) WaitCursor();
 
-      for (ex=0; ex<dwide; ex++) {
-	rA = rB = rC = rD = gA = gB = gC = gD = bA = bB = bC = bD = 0;
+      for (ex=0; ex < dwide; ex++) {
 
-	cx = cxtab[ex];
 	px = pxtab[ex];
+	x0 = px >> 8;			/* Put integer part in x0 */
+	x1 = x0 + 1;
+	px &= 255;			/* Keep fractional part in px */
 
-	if (px<0) { x1 = cx-1;  if (x1<0) x1=0; }
-	     else { x1 = cx+1;  if (x1>swide-1) x1=swide-1; }
+	if (x0 < 0)	  x0 = x1 = 0;
+	if (x1 >= swide)  x0 = x1 = swide-1;
 
 	if (is24) {
-	  pptr = pic824 + y1Off + x1*bperpix;   /* corner pixel */
+	  pptr = pic824 + y0off + x0*bperpix;   /* upper left pixel */
 	  rA = *pptr++;  gA = *pptr++;  bA = *pptr++;
 
-	  pptr = pic824 + y1Off + cx*bperpix;   /* up/down center pixel */
+	  pptr = pic824 + y0off + x1*bperpix;   /* upper right pixel */
 	  rB = *pptr++;  gB = *pptr++;  bB = *pptr++;
 
-	  pptr = pic824 + cyOff + x1*bperpix;   /* left/right center pixel */
+	  pptr = pic824 + y1off + x0*bperpix;   /* lower left pixel */
 	  rC = *pptr++;  gC = *pptr++;  bC = *pptr++;
 
-	  pptr = pic824 + cyOff + cx*bperpix;   /* center pixel */
+	  pptr = pic824 + y1off + x1*bperpix;   /* lower right pixel */
 	  rD = *pptr++;  gD = *pptr++;  bD = *pptr++;
 	}
 	else {  /* 8-bit picture */
-	  cA = pic824[y1Off + x1];   /* corner pixel */
-	  cB = pic824[y1Off + cx];   /* up/down center pixel */
-	  cC = pic824[cyOff + x1];   /* left/right center pixel */
-	  cD = pic824[cyOff + cx];   /* center pixel */
+	  cA = pic824[y0off + x0];	/* upper left pixel */
+	  cB = pic824[y0off + x1];	/* upper right pixel */
+	  cC = pic824[y1off + x0];	/* lower left pixel */
+	  cD = pic824[y1off + x1];	/* lower right pixel */
 	}
 	 
 	/* quick check */
@@ -170,38 +165,30 @@
 	}
 
 	else {
-	  /* compute weighting factors */
-	  apx = abs(px);  apy = abs(py);
-	  pA = (apx * apy) / 100;
-	  pB = (apy * (100 - apx)) / 100;
-	  pC = (apx * (100 - apy)) / 100;
-	  pD = 100 - (pA + pB + pC);
+	  pA = (256-px)*(256-py);	/* compute weighting factors */
+	  pB = px * (256-py);		/* total weight is exactly 2^16 */
+	  pC = (256-px) * py;
+	  pD = px * py;
 
 	  if (is24) {
-	    *pp++ = ((int) (pA * rA))/100 + ((int) (pB * rB))/100 + 
-	            ((int) (pC * rC))/100 + ((int) (pD * rD))/100;
-
-	    *pp++ = ((int) (pA * gA))/100 + ((int) (pB * gB))/100 + 
-	            ((int) (pC * gC))/100 + ((int) (pD * gD))/100;
-
-	    *pp++ = ((int) (pA * bA))/100 + ((int) (pB * bB))/100 + 
-	            ((int) (pC * bC))/100 + ((int) (pD * bD))/100;
+	    *pp++ = (pA * rA + pB * rB + pC * rC + pD * rD) + 32768 >> 16;
+	    *pp++ = (pA * gA + pB * gB + pC * gC + pD * gD) + 32768 >> 16;
+	    *pp++ = (pA * bA + pB * bB + pC * bC + pD * bD) + 32768 >> 16;
 	  }
 	  else {  /* 8-bit pic */
-	    *pp++ = ((int) (pA * rmap[cA]))/100 + ((int)(pB * rmap[cB]))/100 + 
-	            ((int) (pC * rmap[cC]))/100 + ((int)(pD * rmap[cD]))/100;
+	    *pp++ = (pA * rmap[cA] + pB * rmap[cB] + pC * rmap[cC] +
+		     pD * rmap[cD]) + 32768 >> 16;
 
-	    *pp++ = ((int) (pA * gmap[cA]))/100 + ((int)(pB * gmap[cB]))/100 + 
-	            ((int) (pC * gmap[cC]))/100 + ((int)(pD * gmap[cD]))/100;
+	    *pp++ = (pA * gmap[cA] + pB * gmap[cB] + pC * gmap[cC] +
+		     pD * gmap[cD]) + 32768 >> 16;
 
-	    *pp++ = ((int)(pA * bmap[cA]))/100 + ((int)(pB * bmap[cB]))/100 + 
-  	            ((int)(pC * bmap[cC]))/100 + ((int)(pD * bmap[cD]))/100;
+	    *pp++ = (pA * bmap[cA] + pB * bmap[cB] + pC * bmap[cC] +
+		     pD * bmap[cD]) + 32768 >> 16;
 	  }
 	}
       }
     }
 
-    free(cxtab);  
     free(pxtab);
     retval = 0;    /* okay */
   }
@@ -369,7 +356,7 @@
 
   lastline = linecnt = 0;
 
-  for (i=0, clptr=pic824; i<=shigh; i++, clptr+=swide*bperpix) {
+  for (i=0, clptr=pic824; i<shigh; i++, clptr+=swide*bperpix) {
     ProgressMeter(0, shigh, i, "Smooth");
     if ((i&15) == 0) WaitCursor();
 
--- xv-3.10a/xvtiff.c	1995-01-13 14:53:34.000000000 -0500
+++ xv-3.10a/xvtiff.c	2009-03-28 11:12:07.000000000 -0400
@@ -186,7 +186,7 @@
     break;
   }
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%lux%lu TIFF.",w,h);
 
   pic8 = (byte *) malloc((size_t) w*h);
   if (!pic8) FatalError("loadPalette() - couldn't malloc 'pic8'");
@@ -214,7 +214,7 @@
 	   "???"),
 	  filesize);
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%lux%lu TIFF.",w,h);
 
   /* allocate 24-bit image */
   pic24 = (byte *) malloc((size_t) w*h*3);
@@ -301,10 +301,10 @@
 static	byte **BWmap;
 static	byte **PALmap;
 
-typedef void (*tileContigRoutine)   PARM((byte*, u_char*, RGBvalue*, 
+typedef void (*xvtileContigRoutine)   PARM((byte*, u_char*, RGBvalue*, 
 					  uint32, uint32, int, int));
 
-typedef void (*tileSeparateRoutine) PARM((byte*, u_char*, u_char*, u_char*, 
+typedef void (*xvtileSeparateRoutine) PARM((byte*, u_char*, u_char*, u_char*, 
                                          RGBvalue*, uint32, uint32, int, int));
 
 
@@ -366,8 +366,8 @@
 static void   putcontig8bitYCbCrtile  PARM((byte *, u_char *, RGBvalue *,
 					  uint32, uint32, int, int));
 
-static tileContigRoutine   pickTileContigCase   PARM((RGBvalue *));
-static tileSeparateRoutine pickTileSeparateCase PARM((RGBvalue *));
+static xvtileContigRoutine   pickTileContigCase   PARM((RGBvalue *));
+static xvtileSeparateRoutine pickTileSeparateCase PARM((RGBvalue *));
 
 
 /*******************************************/
@@ -641,7 +641,7 @@
   u_char *buf;
   int fromskew, toskew;
   u_int nrow;
-  tileContigRoutine put;
+  xvtileContigRoutine put;
 
   put = pickTileContigCase(Map);
   if (put == 0) return (0);
@@ -708,7 +708,7 @@
   int tilesize;
   int fromskew, toskew;
   u_int nrow;
-  tileSeparateRoutine put;
+  xvtileSeparateRoutine put;
   
   put = pickTileSeparateCase(Map);
   if (put == 0) return (0);
@@ -779,7 +779,7 @@
 {
   uint32 row, y, nrow;
   u_char *buf;
-  tileContigRoutine put;
+  xvtileContigRoutine put;
   uint32 rowsperstrip;
   uint32 imagewidth;
   int scanline;
@@ -832,7 +832,7 @@
   u_char *r, *g, *b;
   uint32 row, y, nrow;
   int scanline;
-  tileSeparateRoutine put;
+  xvtileSeparateRoutine put;
   uint32 rowsperstrip;
   uint32 imagewidth;
   u_int stripsize;
@@ -1065,7 +1065,7 @@
      int fromskew, toskew;
 {
   while (h-- > 0) {
-    UNROLL8(w,0, *cp++ = PALmap[*pp++][0]);
+    UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
     cp += toskew;
     pp += fromskew;
   }
@@ -1262,7 +1262,7 @@
     }
   } else {
     while (h-- > 0) {
-      UNROLL8(w,0,
+      UNROLL8(w,,
 	      *cp++ = pp[0];
 	      *cp++ = pp[1];
 	      *cp++ = pp[2];
@@ -1335,7 +1335,7 @@
     }
   } else {
     while (h-- > 0) {
-      UNROLL8(w,0,
+      UNROLL8(w,,
 	      *cp++ = *r++;
 	      *cp++ = *g++;
 	      *cp++ = *b++;
@@ -1489,16 +1489,16 @@
 /*
  * Select the appropriate conversion routine for packed data.
  */
-static tileContigRoutine pickTileContigCase(Map)
+static xvtileContigRoutine pickTileContigCase(Map)
      RGBvalue* Map;
 {
-  tileContigRoutine put = 0;
+  xvtileContigRoutine put = 0;
   
   switch (photometric) {
   case PHOTOMETRIC_RGB:
     switch (bitspersample) {
-    case 8:  put = (tileContigRoutine) putRGBcontig8bittile;   break;
-    case 16: put = (tileContigRoutine) putRGBcontig16bittile;  break;
+    case 8:  put = putRGBcontig8bittile;   break;
+    case 16: put = (xvtileContigRoutine)putRGBcontig16bittile;  break;
     }
     break;
     
@@ -1540,16 +1540,16 @@
  * NB: we assume that unpacked single channel data is directed
  *	 to the "packed routines.
  */
-static tileSeparateRoutine pickTileSeparateCase(Map)
+static xvtileSeparateRoutine pickTileSeparateCase(Map)
      RGBvalue* Map;
 {
-  tileSeparateRoutine put = 0;
+  xvtileSeparateRoutine put = 0;
   
   switch (photometric) {
   case PHOTOMETRIC_RGB:
     switch (bitspersample) {
-    case  8: put = (tileSeparateRoutine) putRGBseparate8bittile;  break;
-    case 16: put = (tileSeparateRoutine) putRGBseparate16bittile; break;
+    case  8: put = (xvtileSeparateRoutine) putRGBseparate8bittile;  break;
+    case 16: put = (xvtileSeparateRoutine) putRGBseparate16bittile; break;
     }
     break;
   }
