
This is v1.2 of the PNG patch for xv.  This version adds a PNG dialog
so that the gamma, compression, interlacing, and filters can be selected
when saving PNG images.  The gamma dial needed floating point values, so
it required modifying the Dial widget, and subsequently affected all of
the popups that use a Dial (jpeg, ps, and color).

To add PNG support to xv, you need the xv-3.10a source code, libpng and zlib.

To apply the patch, go into the xv-3.10a directory and execute
patch -p1 < thisfile

The Makefile expects libpng and zlib to be already compiled.  The versions
I used were libpng-0.89 and zlib 1.0.2, but it should work with later
versions.  You will also have to modify the makefile to give the location
of libpng and zlib on your system.

Andreas Dilger <adilger@enel.ucalgary.ca>
http://www-mddsp.enel.ucalgary.ca/People/adilger/

Alexander Lehmann <lehmann@mathematik.th-darmstadt.de>
http://www.mathematik.th-darmstadt.de/~lehmann/

diff -c3 xv-3.10a/Makefile xv-3.10b/Makefile
*** xv-3.10a/Makefile	Mon Jan 23 13:20:54 1995
--- xv-3.10b/Makefile	Tue Jun  4 00:26:17 1996
***************
*** 53,58 ****
--- 53,77 ----
  	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
+ PNGDIR = /usr/local/src/libpng
+ PNGINC = -I$(PNGDIR)
+ PNGLIB = -L$(PNGDIR) -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
+ ZLIBINC = -I$(ZLIBDIR)
+ ZLIBLIB = -L$(ZLIBDIR) -lz
  
  
  ###
***************
*** 186,194 ****
  
  CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
  	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
! 	$(DXWM) $(MCHN)
  
! LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -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 \
--- 189,197 ----
  
  CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
  	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
! 	$(DXWM) $(MCHN) $(PNG) $(PNGINC) $(ZLIBINC)
  
! LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) $(PNGLIB) $(ZLIBLIB) -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,202 ****
  	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
  
  MISC = README INSTALL CHANGELOG IDEAS
  
--- 199,205 ----
  	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 xvpng.o
  
  MISC = README INSTALL CHANGELOG IDEAS
  
***************
*** 267,273 ****
  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
  
  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
--- 262,268 ----
  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 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
diff -c3 xv-3.10a/Makefile.std xv-3.10b/Makefile.std
*** xv-3.10a/Makefile.std	Mon Jan 23 13:20:54 1995
--- xv-3.10b/Makefile.std	Tue Jun  4 00:26:17 1996
***************
*** 53,58 ****
--- 53,77 ----
  	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
+ PNGDIR = /usr/local/src/libpng
+ PNGINC = -I$(PNGDIR)
+ PNGLIB = -L$(PNGDIR) -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
+ ZLIBINC = -I$(ZLIBDIR)
+ ZLIBLIB = -L$(ZLIBDIR) -lz
  
  
  ###
***************
*** 186,194 ****
  
  CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
  	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
! 	$(DXWM) $(MCHN)
  
! LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -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 \
--- 189,197 ----
  
  CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
  	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
! 	$(DXWM) $(MCHN) $(PNG) $(PNGINC) $(ZLIBINC)
  
! LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) $(PNGLIB) $(ZLIBLIB) -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,202 ****
  	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
  
  MISC = README INSTALL CHANGELOG IDEAS
  
--- 199,205 ----
  	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 xvpng.o
  
  MISC = README INSTALL CHANGELOG IDEAS
  
***************
*** 267,273 ****
  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
  
  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
--- 262,268 ----
  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 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
diff -c3 xv-3.10a/xv.c xv-3.10b/xv.c
*** xv-3.10a/xv.c	Thu Jan 19 11:08:43 1995
--- xv-3.10b/xv.c	Sat Jun  1 15:49:31 1996
***************
*** 277,282 ****
--- 277,286 ----
    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;
***************
*** 782,787 ****
--- 787,796 ----
    XSetTransientForHint(theDisp, tiffW, dirW);
  #endif
    
+ #ifdef HAVE_PNG
+   CreatePNGW();
+   XSetTransientForHint(theDisp, pngW, dirW);
+ #endif
    
    LoadFishCursors();
    SetCursors(-1);
***************
*** 2611,2616 ****
--- 2620,2630 ----
  	   (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 ||
***************
*** 2671,2676 ****
--- 2685,2694 ----
    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
diff -c3 xv-3.10a/xv.h xv-3.10b/xv.h
*** xv-3.10a/xv.h	Mon Jan 23 13:22:23 1995
--- xv-3.10b/xv.h	Wed May 29 14:50:54 1996
***************
*** 8,15 ****
  #include "config.h"
  
  
! #define REVDATE   "Version 3.10a  Rev: 12/29/94"
! #define VERSTR    "3.10a"
  
  /*
   * uncomment the following, and modify for your site, but only if you've
--- 8,15 ----
  #include "config.h"
  
  
! #define REVDATE   "Version 3.10a  Rev: 12/29/94 (PNG patch 1.2)"
! #define VERSTR    "3.10a(PNG)"
  
  /*
   * uncomment the following, and modify for your site, but only if you've
***************
*** 327,332 ****
--- 327,336 ----
  #define HAVE_TIFF
  #endif
  
+ #ifdef DOPNG
+ #define HAVE_PNG
+ #endif
+ 
  #ifdef DOPDS
  #define HAVE_PDS
  #endif
***************
*** 458,481 ****
  #define F_TIFINC  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 */
  
  
  
--- 461,491 ----
  #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_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,510 ****
--- 515,521 ----
  #define RFT_XPM      17
  #define RFT_XWD      18
  #define RFT_FITS     19
+ #define RFT_PNG      20
  
  /* definitions for page up/down, arrow up/down list control */
  #define LS_PAGEUP   0
***************
*** 765,773 ****
  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 */
  		 char *title;           /* title for this guage */
  		 char *units;           /* string appended to value */
  		 u_long fg,bg,hi,lo;    /* colors */
--- 776,785 ----
  typedef struct { Window win;            /* window ID */
  		 int x,y,w,h;           /* window coords in parent */
  		 int active;            /* true if can do anything*/
! 		 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,1159 ****
--- 1166,1178 ----
  #endif
  
  
+ #ifdef HAVE_PNG
+ /* stuff used for 'png' box */
+ WHERE Window        pngW;
+ WHERE int           pngUp;        /* is pngW mapped, or what? */
+ #endif
+ 
+ 
  #undef WHERE
  
  
***************
*** 1465,1476 ****
  
  
  /*************************** 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 DSetRange             PARM((DIAL *, int, int, int, int));
! void DSetVal               PARM((DIAL *, int));
  void DSetActive            PARM((DIAL *, int));
  void DRedraw               PARM((DIAL *));
  int  DTrack                PARM((DIAL *, int, int));
--- 1484,1495 ----
  
  
  /*************************** XVDIAL.C ***************************/
! 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 *, 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));
***************
*** 1612,1617 ****
--- 1631,1643 ----
  void  TIFFDialog           PARM((int));
  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 *));
diff -c3 xv-3.10a/xvbrowse.c xv-3.10b/xvbrowse.c
*** xv-3.10a/xvbrowse.c	Thu Jan 19 10:49:17 1995
--- xv-3.10b/xvbrowse.c	Sun Mar 17 14:56:42 1996
***************
*** 55,60 ****
--- 55,61 ----
  #include "bits/br_xpm"
  #include "bits/br_xwd"
  #include "bits/br_fits"
+ #include "bits/br_png"
  
  #include "bits/br_trash"
  #include "bits/fcurs"
***************
*** 94,100 ****
  #define BF_XPM      25
  #define BF_XWD      26
  #define BF_FITS     27
! #define BF_MAX      28    /* # of built-in icons */
  
  #define ISLOADABLE(ftyp) (ftyp!=BF_DIR  && ftyp!=BF_CHR && ftyp!=BF_BLK && \
  			  ftyp!=BF_SOCK && ftyp!=BF_FIFO) 
--- 95,102 ----
  #define BF_XPM      25
  #define BF_XWD      26
  #define BF_FITS     27
! #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,529 ****
--- 526,532 ----
    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,3025 ****
--- 3023,3029 ----
      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,3572 ****
--- 3571,3577 ----
    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;
    }
    
diff -c3 xv-3.10a/xvdial.c xv-3.10b/xvdial.c
*** xv-3.10a/xvdial.c	Tue Jan  3 14:20:31 1995
--- xv-3.10b/xvdial.c	Wed May 29 14:37:54 1996
***************
*** 41,60 ****
  
  
  /* 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 *));
  
  
  /***************************************************/
! void DCreate(dp, parent, x, y, w, h, minv, maxv, curv, page, 
  	          fg, bg, hi, lo, title, units)
  DIAL         *dp;
  Window        parent;
! int           x,y,w,h,minv,maxv,curv,page;
  unsigned long fg,bg,hi,lo;
  char         *title, *units;
  {
--- 41,61 ----
  
  
  /* 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 double computeDialVal  PARM((DIAL *, int, int));
! static void   dimDial         PARM((DIAL *));
  
  
  /***************************************************/
! 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;
! double        minv,maxv,curv,inc,page;
  unsigned long fg,bg,hi,lo;
  char         *title, *units;
  {
***************
*** 98,115 ****
  				1,fg,bg);
    if (!dp->win) FatalError("can't create dial window");
  
!   DSetRange(dp, minv, maxv, curv, page);
    XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
  }
  
  
  /***************************************************/
! void DSetRange(dp, minv, maxv, curv, page)
! DIAL *dp;
! int   minv, maxv, curv, page;
  {
    if (maxv<minv) maxv=minv;
!   dp->min = minv;    dp->max = maxv;    dp->page = page;
    dp->active =  (minv < maxv);
  
    DSetVal(dp, curv);
--- 99,116 ----
  				1,fg,bg);
    if (!dp->win) FatalError("can't create dial window");
  
!   DSetRange(dp, minv, maxv, curv, inc, page);
    XSelectInput(theDisp, dp->win, ExposureMask | ButtonPressMask);
  }
  
  
  /***************************************************/
! 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->inc = inc; dp->page = page;
    dp->active =  (minv < maxv);
  
    DSetVal(dp, curv);
***************
*** 118,125 ****
  
  /***************************************************/
  void DSetVal(dp, curv)
! DIAL *dp;
! int   curv;
  {
    RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
  
--- 119,126 ----
  
  /***************************************************/
  void DSetVal(dp, curv)
! DIAL  *dp;
! double curv;
  {
    RANGE(curv, dp->min, dp->max);   /* make sure curv is in-range */
  
***************
*** 129,135 ****
    XSetForeground(theDisp, theGC, dp->bg); 
    drawArrow(dp);
  
!   dp->val = curv;
  
    /* draw new arrow and string */
    XSetForeground(theDisp, theGC, dp->fg);
--- 130,136 ----
    XSetForeground(theDisp, theGC, dp->bg); 
    drawArrow(dp);
  
!   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,208 ****
  int mx,my;
  {
    Window       rW,cW;
!   int          rx,ry, x,y, ipos, pos, lit, i, origval;
    unsigned int mask;
  
    lit = 0;
--- 203,210 ----
  int mx,my;
  {
    Window       rW,cW;
!   int          rx, ry, x, y, ipos, pos, lit;
!   double       origval;
    unsigned int mask;
  
    lit = 0;
***************
*** 224,232 ****
    if (ipos != INDIAL) {
      drawButt(dp, ipos, 1);
      switch (ipos) {
!     case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); 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 INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
      }
      if (dp->drawobj != NULL) (dp->drawobj)();  
--- 226,234 ----
    if (ipos != INDIAL) {
      drawButt(dp, ipos, 1);
      switch (ipos) {
!     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-dp->inc);  break;
      case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page); break;
      }
      if (dp->drawobj != NULL) (dp->drawobj)();  
***************
*** 235,242 ****
    }
  
    else { 
!     i = computeDialVal(dp, mx, my);
!     DSetVal(dp, i);
      if (dp->drawobj != NULL) (dp->drawobj)();  
    }
  
--- 237,245 ----
    }
  
    else { 
!     double v;
!     v = computeDialVal(dp, mx, my);
!     DSetVal(dp, v);
      if (dp->drawobj != NULL) (dp->drawobj)();  
    }
  
***************
*** 246,256 ****
      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) {
  	/* track whatever dial controls */
  	if (dp->drawobj != NULL) (dp->drawobj)();  
        }
--- 249,259 ----
      if (!(mask & Button1Mask)) break;    /* button released */
  
      if (ipos == INDIAL) {
!       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,276 ****
  
        if (lit) {
  	switch (ipos) {
! 	case INCW1:  if (dp->val < dp->max) DSetVal(dp, dp->val+1); 
  	             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 INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                       break;
--- 269,279 ----
  
        if (lit) {
  	switch (ipos) {
! 	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-dp->inc);
                       break;
  	case INCCW2: if (dp->val > dp->min) DSetVal(dp, dp->val-dp->page);
                       break;
***************
*** 320,338 ****
  static void drawArrow(dp)
  DIAL *dp;
  {
!   int i, rad, cx, cy;
    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));
    arrow[3].x = arrow[0].x;
    arrow[3].y = arrow[0].y;
    XDrawLines(theDisp, dp->win, theGC, arrow, 4, CoordModeOrigin);
--- 323,342 ----
  static void drawArrow(dp)
  DIAL *dp;
  {
!   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) */
!   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,365 ****
  static void drawValStr(dp)
  DIAL *dp;
  {
!   int  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);
    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);
  
    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," ");
    }
    strcat(foo1, foo);
  
--- 347,383 ----
  static void drawValStr(dp)
  DIAL *dp;
  {
!   int  tot, i, x1, x2;
    char foo[60], foo1[60];
  
    /* compute longest string necessary so we can right-align this thing */
!   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);
  
!   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-=strlen(foo);i>0;i--) strcat(foo1," ");
    }
    strcat(foo1, foo);
  
***************
*** 411,422 ****
  
  
  /***************************************************/
! static int computeDialVal(dp, x, y)
  DIAL *dp;
  int x, y;
  {
!   int dx, dy, val;
!   double angle;
  
    /* compute dx, dy (distance from cx, cy).  Note: +dy is *up* */
    dx = x - dp->cx;  dy = dp->cy - y;
--- 429,441 ----
  
  
  /***************************************************/
! static double computeDialVal(dp, x, y)
  DIAL *dp;
  int x, y;
  {
!   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,443 ****
    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;
  
    return val;
  }
  
--- 455,464 ----
    if (angle > 270.0) angle -= 360.0;
    if (angle < -90.0) angle += 360.0;
  
!   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;
  }
  
diff -c3 xv-3.10a/xvdir.c xv-3.10b/xvdir.c
*** xv-3.10a/xvdir.c	Tue Jan  3 14:21:39 1995
--- xv-3.10b/xvdir.c	Tue May 28 14:59:28 1996
***************
*** 62,67 ****
--- 62,70 ----
  #ifdef HAVE_TIFF
  			       "TIFF",
  #endif
+ #ifdef HAVE_PNG
+ 			       "PNG",
+ #endif
  			       "PostScript",
  			       "PBM/PGM/PPM (raw)",
  			       "PBM/PGM/PPM (ascii)",
***************
*** 1115,1120 ****
--- 1118,1132 ----
    }
  #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,1174 ****
      
    case F_XPM:
      rv = WriteXPM   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
! 		     fullname, picComments);    
    case F_FITS:
      rv = WriteFITS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
  		     picComments);    
--- 1180,1187 ----
      
    case F_XPM:
      rv = WriteXPM   (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
! 		     fullname, picComments);
!     break;
    case F_FITS:
      rv = WriteFITS  (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, 
  		     picComments);    
***************
*** 1380,1393 ****
        (strcmp(lowsuf,"eps" )==0) ||
        (strcmp(lowsuf,"rgb" )==0) ||
        (strcmp(lowsuf,"tga" )==0) ||
-       (strcmp(lowsuf,"xpm" )==0) ||
        (strcmp(lowsuf,"fits")==0) ||
        (strcmp(lowsuf,"fts" )==0) ||
        (strcmp(lowsuf,"jpg" )==0) ||
        (strcmp(lowsuf,"jpeg")==0) ||
        (strcmp(lowsuf,"jfif")==0) ||
        (strcmp(lowsuf,"tif" )==0) ||
!       (strcmp(lowsuf,"tiff")==0)) {
  
      /* found one.  set lowsuf = to the new suffix, and tack on to filename */
  
--- 1393,1413 ----
        (strcmp(lowsuf,"eps" )==0) ||
        (strcmp(lowsuf,"rgb" )==0) ||
        (strcmp(lowsuf,"tga" )==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) ||
! #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 */
  
***************
*** 1422,1427 ****
--- 1442,1451 ----
  
  #ifdef HAVE_TIFF
      case F_TIFF:     strcpy(lowsuf,"tif");  break;
+ #endif
+ 
+ #ifdef HAVE_PNG
+     case F_PNG:      strcpy(lowsuf,"png");  break;
  #endif
      }
  
diff -c3 xv-3.10a/xvevent.c xv-3.10b/xvevent.c
*** xv-3.10a/xvevent.c	Mon Jan 23 16:20:24 1995
--- xv-3.10b/xvevent.c	Wed May 29 01:10:28 1996
***************
*** 154,160 ****
       int    *donep;
  {
    static int wasInfoUp=0, wasCtrlUp=0, wasDirUp=0, wasGamUp=0, wasPsUp=0;
!   static int wasJpegUp=0, wasTiffUp=0;
  
    static int mainWKludge=0;  /* force first mainW expose after a mainW config
  				to redraw all of mainW */
--- 154,160 ----
       int    *donep;
  {
    static int wasInfoUp=0, wasCtrlUp=0, wasDirUp=0, wasGamUp=0, wasPsUp=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,238 ****
--- 233,242 ----
      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,364 ****
--- 363,372 ----
        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,543 ****
--- 546,555 ----
  #ifdef HAVE_TIFF
  	if (wasTiffUp) { TIFFDialog(wasTiffUp);  wasTiffUp=0; }
  #endif
+ 
+ #ifdef HAVE_PNG
+ 	if (wasPngUp)  { PNGDialog(wasJpegUp);   wasPngUp=0; }
+ #endif
        }
      }
    }
***************
*** 576,581 ****
--- 588,597 ----
  #ifdef HAVE_TIFF
  	  if (tiffUp) { wasTiffUp = tiffUp;  TIFFDialog(0); }
  #endif
+ 
+ #ifdef HAVE_PNG
+ 	  if (pngUp)  { wasPngUp  = pngUp;   PNGDialog(0); }
+ #endif
  	}
        }
      }
***************
*** 1147,1152 ****
--- 1163,1172 ----
      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,1371 ****
--- 1386,1395 ----
      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;
***************
*** 2370,2375 ****
--- 2394,2403 ----
  
  #ifdef HAVE_TIFF
    if (tiffUp) TIFFDialog(0);  /* close tiff window */
+ #endif
+ 
+ #ifdef HAVE_PNG
+   if (pngUp) PNGDialog(0);    /* close png window */
  #endif
  
    ClosePopUp();
diff -c3 xv-3.10a/xvgam.c xv-3.10b/xvgam.c
*** xv-3.10a/xvgam.c	Fri Jan 13 12:51:14 1995
--- xv-3.10b/xvgam.c	Wed May 29 11:13:56 1996
***************
*** 265,275 ****
    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, 
  	  infofg, infobg, hicol, locol, "Hue", NULL);
!   DCreate(&gsDial, cmapF, 72, 215, 66, 100,  0,360,180, 5, 
  	  infofg, infobg, hicol, locol, "Sat.", NULL);
!   DCreate(&bvDial, cmapF, 139, 215, 66, 100,   0,360,180, 5, 
  	  infofg, infobg, hicol, locol, "Value", NULL);
  
    rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
--- 265,275 ----
    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.0, 360.0, 180.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Hue", NULL);
!   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.0, 360.0, 180.0, 1.0, 5.0, 
  	  infofg, infobg, hicol, locol, "Value", NULL);
  
    rhDial.drawobj = gsDial.drawobj = bvDial.drawobj = dragEditColor;
***************
*** 359,365 ****
  
    srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
  
!   DCreate(&satDial, hsvF, 100, 199, 100, 121, -100, 100, 0, 5, 
  	   infofg, infobg,hicol,locol, "Saturation", "%");
  
    hueRB = RBCreate(NULL, hsvF,  7, 153, "1", 
--- 359,365 ----
  
    srcHD.drawobj = dstHD.drawobj = whtHD.drawobj = dragHueDial;
  
!   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,728 ****
  
    if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
  
!   if (satDial.val != 0) hsvnonlinear++;
  
    /* check intensity graf */
    for (i=0; i<256 && intGraf.func[i]==i; i++);
--- 722,728 ----
  
    if (whtHD.enabCB.val && whtHD.satval) hsvnonlinear++;
  
!   if (satDial.val != 0.0) hsvnonlinear++;
  
    /* check intensity graf */
    for (i=0; i<256 && intGraf.func[i]==i; i++);
***************
*** 1291,1304 ****
      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));
    }
    else {
!     DSetVal(&rhDial, rcmap[editColor]);
!     DSetVal(&gsDial, gcmap[editColor]);
!     DSetVal(&bvDial, bcmap[editColor]);
    }
  }
    
--- 1291,1304 ----
      rgb2hsv(rcmap[editColor], gcmap[editColor], bcmap[editColor], &h, &s, &v);
      if (h<0) h = 0;
  
!     DSetVal(&rhDial, h);
!     DSetVal(&gsDial, s*100);
!     DSetVal(&bvDial, v*100);
    }
    else {
!     DSetVal(&rhDial, (double)rcmap[editColor]);
!     DSetVal(&gsDial, (double)gcmap[editColor]);
!     DSetVal(&bvDial, (double)bcmap[editColor]);
    }
  }
    
***************
*** 1310,1325 ****
  
    if (hsvmode) {
      int rv, gv, bv;
!     hsv2rgb((double) rhDial.val, ((double) gsDial.val) / 100.0, 
! 	    ((double) 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;
    }
  }
  
--- 1310,1324 ----
  
    if (hsvmode) {
      int 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] = (int)rhDial.val;
!     gcmap[editColor] = (int)gsDial.val;
!     bcmap[editColor] = (int)bvDial.val;
    }
  }
  
***************
*** 1561,1569 ****
      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);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
--- 1560,1568 ----
      gsDial.title = "Green";
      bvDial.title = "Blue";
  		   
!     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,1589 ****
  	    &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);
  
      XClearWindow(theDisp, rhDial.win);    DRedraw(&rhDial);
      XClearWindow(theDisp, gsDial.win);    DRedraw(&gsDial);
--- 1580,1588 ----
  	    &h, &s, &v);
  
      if (h<0.0) h = 0.0;
!     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,1897 ****
      }
  
      /* apply satDial value to s */
!     s = s + ((double) satDial.val) / 100.0;
      if (s<0.0) s = 0.0;
      if (s>1.0) s = 1.0;
  
--- 1890,1896 ----
      }
  
      /* apply satDial value to s */
!     s = s + satDial.val / 100.0;
      if (s<0.0) s = 0.0;
      if (s>1.0) s = 1.0;
  
***************
*** 2007,2013 ****
  
    gs->hueRBnum = RBWhich(hueRB);
  
!   gs->satval = satDial.val;
    GetGrafState(&intGraf,&gs->istate);
    GetGrafState(&rGraf,  &gs->rstate);
    GetGrafState(&gGraf,  &gs->gstate);
--- 2006,2012 ----
  
    gs->hueRBnum = RBWhich(hueRB);
  
!   gs->satval = (int)satDial.val;
    GetGrafState(&intGraf,&gs->istate);
    GetGrafState(&rGraf,  &gs->rstate);
    GetGrafState(&gGraf,  &gs->gstate);
***************
*** 2064,2071 ****
      changed++;
    }
      
!   if (gs->satval != satDial.val) {
!     DSetVal(&satDial,gs->satval);
      changed++;
    }
  
--- 2063,2070 ----
      changed++;
    }
      
!   if (gs->satval != (int)satDial.val) {
!     DSetVal(&satDial,(double)gs->satval);
      changed++;
    }
  
***************
*** 3200,3206 ****
  
    if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
  
!   if (satDial.val != 0) hsvmod++;
  
    /* check intensity graf */
    for (i=0; i<256; i++) {
--- 3199,3205 ----
  
    if (whtHD.enabCB.val && whtHD.satval) hsvmod++;
  
!   if (satDial.val != 0.0) hsvmod++;
  
    /* check intensity graf */
    for (i=0; i<256; i++) {
***************
*** 3284,3290 ****
        }
  
        /* apply satDial value to s */
!       s = s + satDial.val;
        if (s<  0) s =   0;
        if (s>100) s = 100;
  
--- 3283,3289 ----
        }
  
        /* apply satDial value to s */
!       s = s + (int)satDial.val;
        if (s<  0) s =   0;
        if (s>100) s = 100;
  
diff -c3 xv-3.10a/xvjpeg.c xv-3.10b/xvjpeg.c
*** xv-3.10a/xvjpeg.c	Thu Jan  5 01:17:13 1995
--- xv-3.10b/xvjpeg.c	Wed May 29 11:15:02 1996
***************
*** 87,96 ****
    
    XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
    
!   DCreate(&qDial, jpegW, 10, 10, 80, 100, 1, 100, 75, 5, 
  	  infofg, infobg, hicol, locol, "Quality", "%");
    
!   DCreate(&smDial, jpegW, 120, 10, 80, 100, 0, 100, 0, 5, 
  	  infofg, infobg, hicol, locol, "Smoothing", "%");
    
    BTCreate(&jbut[J_BOK], jpegW, JWIDE-180-1, JHIGH-10-BUTTH-1, 80, BUTTH, 
--- 85,94 ----
    
    XSelectInput(theDisp, jpegW, ExposureMask | ButtonPressMask | KeyPressMask);
    
!   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.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, 
***************
*** 759,766 ****
  
  
    jpeg_set_defaults(&cinfo);
!   jpeg_set_quality(&cinfo, qDial.val, TRUE);
!   cinfo.smoothing_factor = smDial.val;
  
  
    jpeg_start_compress(&cinfo, TRUE);
--- 757,764 ----
  
  
    jpeg_set_defaults(&cinfo);
!   jpeg_set_quality(&cinfo, (int)qDial.val, TRUE);
!   cinfo.smoothing_factor = (int)smDial.val;
  
  
    jpeg_start_compress(&cinfo, TRUE);
***************
*** 769,775 ****
    /*** COMMENT HANDLING ***/
  
    sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
! 	  CREATOR_STR, REVDATE, qDial.val, smDial.val);
    
    if (picComments) {   /* append XV comment */
      char *sp, *sp1;  int done;
--- 767,773 ----
    /*** COMMENT HANDLING ***/
  
    sprintf(xvcmt, "%sXV %s  Quality = %d, Smoothing = %d\n",
! 	  CREATOR_STR, REVDATE, (int)qDial.val, (int)smDial.val);
    
    if (picComments) {   /* append XV comment */
      char *sp, *sp1;  int done;
diff -c3 xv-3.10a/xvmisc.c xv-3.10b/xvmisc.c
*** xv-3.10a/xvmisc.c	Fri Jan 13 16:41:34 1995
--- xv-3.10b/xvmisc.c	Tue May 28 14:57:52 1996
***************
*** 520,525 ****
--- 520,529 ----
      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;
***************
*** 715,720 ****
--- 719,728 ----
    
  #ifdef HAVE_TIFF
    if (tiffW) XDefineCursor(theDisp, tiffW, otherc);
+ #endif
+ 
+ #ifdef HAVE_PNG
+   if (pngW)  XDefineCursor(theDisp, pngW, otherc);
  #endif
  }
  
diff -c3 xv-3.10a/xvpopup.c xv-3.10b/xvpopup.c
*** xv-3.10a/xvpopup.c	Thu Jan 19 11:09:31 1995
--- xv-3.10b/xvpopup.c	Wed May 29 11:18:43 1996
***************
*** 200,213 ****
      
      if (!padHaveDooDads) {
        DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
! 	      1, 2048, pWIDE, 10,
  	      infofg, infobg, hicol, locol, "Width", NULL);
        DCreate(&padHDial, popW, 16+1+75, puhigh-16-100-1,75,100,
! 	      1, 2048, pHIGH, 10,
  	      infofg, infobg, hicol, locol, "Height", NULL);
  
        DCreate(&padODial, popW, 16+1+75+75+9, puhigh-16-100-1,75,100,
! 	      0, 100, 100, 10,
  	      infofg, infobg, hicol, locol, "Opaque", NULL);
  
        MBCreate(&padMthdMB, popW, 100-2+44, 10, 140, 19, NULL,
--- 200,213 ----
      
      if (!padHaveDooDads) {
        DCreate(&padWDial, popW, 16,      puhigh-16-100-1,75,100,
! 	      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.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.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,266 ****
    else if (poptyp == ISPAD) {
      BTSetActive(&bts[0], (int) strlen(gsBuf));
      i = pWIDE * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padWDial, 1, i, padWDial.val, 10);
      i = pHIGH * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padHDial, 1, i, padHDial.val, 10);
  
      DSetActive(&padWDial, (padMode!=PAD_LOAD));  /* DSetRange activates dial */
      DSetActive(&padHDial, (padMode!=PAD_LOAD));
--- 258,266 ----
    else if (poptyp == ISPAD) {
      BTSetActive(&bts[0], (int) strlen(gsBuf));
      i = pWIDE * 3;  RANGE(i,2048,9999);  
!     DSetRange(&padWDial, 1.0, (double)i, padWDial.val, 1.0, 10.0);
      i = pHIGH * 3;  RANGE(i,2048,9999);  
!     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,473 ****
    changedGSBuf();      /* careful!  popW doesn't exist yet! */
  
    if (padHaveDooDads) { 
!     oldW = padWDial.val;  
!     oldH = padHDial.val;
!     oldO = padODial.val;
    }
    else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
  
--- 465,473 ----
    changedGSBuf();      /* careful!  popW doesn't exist yet! */
  
    if (padHaveDooDads) { 
!     oldW = (int)padWDial.val;  
!     oldH = (int)padHDial.val;
!     oldO = (int)padODial.val;
    }
    else { oldW = pWIDE;  oldH = pHIGH;  oldO = 100; }
  
***************
*** 486,494 ****
    }
  
    if (rv == 1) {   /* cancelled:  restore normal values */
!     DSetVal(&padWDial, oldW);
!     DSetVal(&padHDial, oldH);
!     DSetVal(&padODial, oldO);
    }
  
    XUnmapWindow(theDisp, padWDial.win);
--- 486,494 ----
    }
  
    if (rv == 1) {   /* cancelled:  restore normal values */
!     DSetVal(&padWDial, (double)oldW);
!     DSetVal(&padHDial, (double)oldH);
!     DSetVal(&padODial, (double)oldO);
    }
  
    XUnmapWindow(theDisp, padWDial.win);
***************
*** 498,506 ****
    /* load up return values */
    *pMode   = padMode;  
    *pStr    = padBuf;  
!   *pWide   = padWDial.val;
!   *pHigh   = padHDial.val;
!   *pOpaque = padODial.val;
    *pOmode  = padOMode;
  
    return rv;
--- 498,506 ----
    /* load up return values */
    *pMode   = padMode;  
    *pStr    = padBuf;  
!   *pWide   = (int)padWDial.val;
!   *pHigh   = (int)padHDial.val;
!   *pOpaque = (int)padODial.val;
    *pOmode  = padOMode;
  
    return rv;
***************
*** 972,979 ****
    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);
        }
      }
  
--- 970,977 ----
    else if (popUp == ISPAD) {
      if (PTINRECT(x, y, padDButt.x, padDButt.y, padDButt.w, padDButt.h)) {
        if (BTTrack(&padDButt)) {
! 	DSetVal(&padWDial, (double)pWIDE);
! 	DSetVal(&padHDial, (double)pHIGH);
        }
      }
  
diff -c3 xv-3.10a/xvps.c xv-3.10b/xvps.c
*** xv-3.10a/xvps.c	Thu Dec 22 15:34:42 1994
--- xv-3.10b/xvps.c	Wed May 29 11:04:28 1996
***************
*** 139,147 ****
    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, 
  	  infofg, infobg, hicol, locol, "Width", "%");
!   DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5, 
  	  infofg, infobg, hicol, locol, "Height", "%");
    xsDial.drawobj = changedScale;
    ysDial.drawobj = changedScale;
--- 139,147 ----
    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.0, 800.0, 100.0, 0.5, 5.0, 
  	  infofg, infobg, hicol, locol, "Width", "%");
!   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,245 ****
  
    if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
      if (def_int >= 10 && def_int <= 720) {
!       int i = (int) ((PIX2INCH * 100) / def_int);
  
!       DSetVal(&xsDial, i);
!       DSetVal(&ysDial, i);
      }
    }
  
--- 236,245 ----
  
    if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
      if (def_int >= 10 && def_int <= 720) {
!       double v = (PIX2INCH * 100) / def_int;
  
!       DSetVal(&xsDial, v);
!       DSetVal(&ysDial, v);
      }
    }
  
***************
*** 836,842 ****
    if (scx < scy) { sz_iny = h * scx; }
              else { sz_inx = w * scy; }
  
!   DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
    DSetVal(&ysDial, xsDial.val);
  
    sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
--- 836,842 ----
    if (scx < scy) { sz_iny = h * scx; }
              else { sz_inx = w * scy; }
  
!   DSetVal(&xsDial, 100 * (sz_inx * PIX2INCH) / w);
    DSetVal(&ysDial, xsDial.val);
  
    sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
