diff -Nur xv-3.10a.clean/Imakefile xv-3.10a.darwin/Imakefile
--- xv-3.10a.clean/Imakefile	Fri Jan 13 12:24:01 1995
+++ xv-3.10a.darwin/Imakefile	Sun Apr 27 17:09:29 2003
@@ -157,7 +157,7 @@
 	xvdial.c xvgraf.c xvsunras.c xvjpeg.c xvps.c xvpopup.c xvdflt.c \
 	xvtiff.c xvtiffwr.c xvpds.c xvrle.c xviris.c xvgrab.c vprintf.c \
 	xvbrowse.c xvtext.c xvpcx.c xviff.c xvtarga.c xvxpm.c xvcut.c \
-	xvxwd.c xvfits.c
+	xvxwd.c xvfits.c xvpcd.c
 
 OBJS1 =	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 \
@@ -165,7 +165,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 xvpcd.o
 
 SRCS2=	bggen.c
 OBJS2=	bggen.o
diff -Nur xv-3.10a.clean/Makefile xv-3.10a.darwin/Makefile
--- xv-3.10a.clean/Makefile	Mon Jan 23 12:20:54 1995
+++ xv-3.10a.darwin/Makefile	Tue Sep 16 00:52:46 2003
@@ -2,7 +2,7 @@
 
 # your C compiler (and options) of choice
 CC = cc
-# CC = gcc -ansi
+# CC = gcc -ansi 
 
 # use this if you're using 'cc' on a DEC Alpha (OSF/1) or MIPS (Ultrix) system:
 # CC = cc -std1 -Olimit 750
@@ -14,7 +14,7 @@
 #       -Wuninitialized -Wparentheses
 
 
-CCOPTS = -O 
+CCOPTS = -O -I/usr/X11R6/include 
 
 
 ### NOTE: Sun running OpenWindows:
@@ -28,10 +28,11 @@
 
 
 ### Installation locations
-BINDIR = /usr/local/bin
-MANDIR = /usr/local/man/man1
+BINDIR = @DEST@/bin
+MANDIR = @DEST@/man/man1
 MANSUF = 1
-LIBDIR = /usr/local/lib
+LIBDIR = @DEST@/lib
+DOCDIR = @DEST@/share/doc/xv-3.10a/
 
 
 buildit: all
@@ -45,27 +46,46 @@
 ### if, for whatever reason, you're unable to get the JPEG library to compile
 ### 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
+JPEG    = -DDOJPEG
+JPEGDIR = @INST@
+JPEGINC = -I$(JPEGDIR)/include
+JPEGLIB = -L$(JPEGDIR)/lib -ljpeg
+#$(JPEGDIR)/jconfig.h:
+#	cd $(JPEGDIR) ; ./configure CC='$(CC)'
+#$(JPEGLIB):  $(JPEGDIR)/jconfig.h
+#	cd $(JPEGDIR) ; make
+#JPEGLIB = -ljpeg
 
+###
+### 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 = @INST@
+PNGINC = -I$(PNGDIR)/include
+PNGLIB = -L$(PNGDIR)/lib -lpng
+#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
+#ZLIBINC = -I$(ZLIBDIR) 
+#ZLIBLIB = -L$(ZLIBDIR) -lz  
+ZLIBLIB = -lz
 
 ###
 ### if, for whatever reason, you're unable to get the TIFF library to compile
 ### 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)' )
-
+TIFF    = -DDOTIFF
+TIFFDIR = @INST@
+TIFFINC = -I$(TIFFDIR)/include
+#TIFFLIB = $(TIFFDIR)/lib/libtiff.a
+#$(TIFFLIB):
+#	( cd $(TIFFDIR) ; make CC='$(CC)' )
+TIFFLIB = -L$(TIFFDIR)/lib -ltiff
 
 ###
 ### if, for whatever reason, you're unable to get the PDS/VICAR support
@@ -84,10 +104,12 @@
 
 #----------Machine Specific Configurations----------
 
+### If you are using a MacOS X/darwin system, uncomment the following line
+MCHN = -Ddarwin
+
 ### If you are using an SGI system, uncomment the following line
 #MCHN = -Dsgi
 
-
 ### For HP-UX, uncomment the following line:
 #MCHN= -Dhpux -D_HPUX_SOURCE
 # To use old HP compilers (HPUX 7.0 or so), you may need
@@ -100,11 +122,9 @@
 # to whichever of those lines you used, as HP tends to store their X11
 # include files in a non-standard place...
 
-
 ### for LINUX, uncomment the following line
 #MCHN = -DLINUX
 
-
 # For SCO 1.1 (UNIX 3.2v2) machines, uncomment the following:
 #MCHN = -Dsco -DPOSIX
 #
@@ -144,7 +164,7 @@
 
 # if your machine has the usleep() function, uncomment the following line:
 # if it doesn't, or you're not sure, leave this line alone.
-#TIMERS = -DUSLEEP
+TIMERS = -DUSLEEP
 
 
 # if XV locks up whenever you click on *any* of the buttons, the Timer() 
@@ -188,7 +208,7 @@
 	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
 	$(DXWM) $(MCHN)
 
-LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm
+LIBS = -L/usr/X11R6/lib -L@INST@/lib -lX11 $(JPEGLIB) $(TIFFLIB) $(PNGLIB) $(ZLIBLIB) -lc -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 +216,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 xvpcd.o xvpng.o
 
 MISC = README INSTALL CHANGELOG IDEAS
 
@@ -206,10 +226,10 @@
 
 
 
-all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm
+all: xv bggen vdcomp xcmap xvpictoppm
 
 
-xv: $(OBJS) $(JPEGLIB) $(TIFFLIB)
+xv: $(OBJS) 
 	$(CC) -o xv $(CFLAGS) $(OBJS) $(LIBS)
 
 bggen: bggen.c
@@ -237,13 +257,16 @@
 
 
 install: all
-	cp xv bggen vdcomp xcmap xvpictoppm $(BINDIR)
-	cp docs/xv.man     $(MANDIR)/xv.$(MANSUF)
-	cp docs/bggen.man  $(MANDIR)/bggen.$(MANSUF)
-	cp docs/xcmap.man  $(MANDIR)/xcmap.$(MANSUF)
-	cp docs/xvp2p.man  $(MANDIR)/xvpictoppm.$(MANSUF)
-	cp docs/vdcomp.man $(MANDIR)/vdcomp.$(MANSUF)
-	cp docs/xvdocs.ps* $(LIBDIR)
+	install -d $(BINDIR)
+	install -d $(MANDIR)
+	install -d $(DOCDIR)
+	install xv bggen vdcomp xcmap xvpictoppm $(BINDIR)
+	install docs/xv.man     $(MANDIR)/xv.$(MANSUF)
+	install docs/bggen.man  $(MANDIR)/bggen.$(MANSUF)
+	install docs/xcmap.man  $(MANDIR)/xcmap.$(MANSUF)
+	install docs/xvp2p.man  $(MANDIR)/xvpictoppm.$(MANSUF)
+	install docs/vdcomp.man $(MANDIR)/vdcomp.$(MANSUF)
+	install docs/xvdocs.ps* $(DOCDIR)
 
 tar:
 	tar cvf xv.tar Makefile* Imakefile *.c *.h bits \
@@ -267,7 +290,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_pcd 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 -Nur xv-3.10a.clean/Makefile.std xv-3.10a.darwin/Makefile.std
--- xv-3.10a.clean/Makefile.std	Mon Jan 23 17:06:26 1995
+++ xv-3.10a.darwin/Makefile.std	Sun Apr 27 17:10:54 2003
@@ -56,6 +56,25 @@
 
 
 ###
+### 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 = @INST@
+PNGINC = -I$(PNGDIR)/include
+PNGLIB = -L$(PNGDIR)/lib -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
+ZLIBINC = -I$(ZLIBDIR)/include
+ZLIBLIB = -L$(ZLIBDIR)/lib -lz
+
+
+###
 ### if, for whatever reason, you're unable to get the TIFF library to compile
 ### on your machine, *COMMENT OUT* the following lines
 ###
@@ -186,9 +205,9 @@
 
 CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \
 	$(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \
-	$(DXWM) $(MCHN)
+	$(DXWM) $(MCHN) $(PNG) $(PNGINC) $(ZLIBINC)
 
-LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm
+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,7 +215,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 xvpcd.o
 
 MISC = README INSTALL CHANGELOG IDEAS
 
@@ -267,7 +286,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
diff -Nur xv-3.10a.clean/README.PNG xv-3.10a.darwin/README.PNG
--- xv-3.10a.clean/README.PNG	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/README.PNG	Sun Apr 27 17:09:28 2003
@@ -0,0 +1,33 @@
+This archive contains context diffs suitable for use with the GNU
+patch utility.  It adds the ability to read and write PNG format
+files with XV 3.10a.  This patch was written by Andreas Dilger
+<adilger@enel.ucalgary.ca> based on a patch written by Alexander
+Lehmann <lehmann@mathematik.th-darmstadt.de>.  No warranty, expressed
+or implied, of merchant-ability or fitness for a particular purpose
+is given with this patch.  It is also an unofficial patch, in the
+sense that the XV author had nothing to do with it.  Despite all that,
+it is reasonably reliable.
+
+The following files are required for adding PNG to XV 3.10a.
+xvpng.c
+xvpng.diff
+bits/br_png
+
+Move them into the same directory as the XV source code, and apply
+the patch via "patch -p1 < xvpng.diff".  You may need to edit your
+makefile to indicate the location of libpng and zlib, which are not
+included here.  Both are available at ftp.uu.net and various other
+locations on the internet.  This patch was created with libpng-0.89
+and zlib-1.0.2, but later versions should also work.
+
+The xvjpeg.diff and xvtiff.diff are not required for the PNG
+functionality, but were modifications I needed to make to get XV
+to compile with the latest versions of the respective libraries
+(libjpeg 6.0 and libtiff 3.4.beta027 respectively).  You do not
+need to apply them if you are using the libraries included with XV.
+
+The xcmap.diff file allows this program to work properly with a 1-bit
+X display.  It is not required for PNG functionality.  Why use xcmap
+for a 1-bit display?  Because I have an xcmap icon for fvwm, and it
+always starts regardless of the display, so it was easier to fix xcmap
+than to stop xcmap from starting based on the display depth.
diff -Nur xv-3.10a.clean/README.pcd xv-3.10a.darwin/README.pcd
--- xv-3.10a.clean/README.pcd	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/README.pcd	Sun Apr 27 17:09:29 2003
@@ -0,0 +1,159 @@
+Copyright 1993-2001 David Clunie.
+
+PCD patch for XV 3.10a Release Notes 2001/07/08.
+
+See also the progress notes at the end of this file. Thanks to all those
+contributors who have substantially improved this patch.
+
+These patches allow xv to read Kodak photocd files and choose which of the
+5 available resolutions one wants to view.
+
+When a photocd file is loaded, a dialog box asks which resolution you
+would like. The visual schnauzer builds thumbnails by reading the lowest
+resolution image. The selected resolution can be selected from the
+command line with the -pcd option:
+
+	[-pcd 0|1|2|3|4]
+
+where:
+
+	0=192*128,	base/16 resolution
+	1=384*256,	base/4 resolution
+	2=768*512,	base resolution
+	3=1536*1024,	4base resolution
+	4=3072*2048	16base resolution.
+
+Note that the Pro format is not supported.
+
+The command line option allows loops without the dialog box popping up, eg.:
+
+	xv -pcd 1 -wloop -wait 10 *.pcd
+
+The code is pretty crude and was written quickly for a specific purpose and
+has not really been cleaned up. It is poorly structured, full of debugging
+codes and verbose comments, and there is very little attempt at optimizing
+things. No profiling has been done.
+
+There is not yet support for overview files, nor is there a facility to
+use the higher resolution chroma planes from when viewing lower resolution
+images.
+
+It's only claim to fame is that it works and produces reasonable looking
+images.
+
+The outline of this is shamelessly derived from xvpbm.c to read the
+file, and xvtiffwr.c to handle the popup window and X stuff (X never
+has been my forte !), and the PhotoCD format information (though not
+the code) was found in Hadmut Danisch's (danisch@ira.uka.de) hpcdtoppm
+program in which he has reverse engineered the format by studying
+hex dumps of PhotoCDs ! The color stuff and Huffman decding were
+extensivelt revised by Matthew Francey.
+
+Feel free to send me comments or improvements, or even better, more
+information about the photo CD format ... hopefully someone who really
+knows what they are doing will tidy it up or do a neater job.
+
+david (dclunie@dclunie.com)
+
+---------
+
+The trace #define in xvpcd.c is now in the right place, and the ansi
+prototype for the magnify function has been fixed. Colin made me switch to
+xvbcopy() which seems like a good idea for System V victims.
+
+---------
+
+Date: Wed, 22 Dec 1993 16:09:52 --1000
+From: colinc@fitmail.fit.qut.edu.au (Colin Canfield )
+
+I have done some more work using your patch I thought you might be intested in.
+The major change was adding a size parameter to the LoadPCD; either -1 to mean
+the popup or else the size you desired. This allows batch mode processing,
+specifically xv -pcd <size> <filename>, and the visual schnauzer can work in 
+quick mode (ie. you don't have to select each image size when it is building 
+the icons)
+
+I have added an xbm file for the file type but haven't drawn an icon for it,
+this is in bitmaps/br_pcd.xbm. I will just send you the new files.
+
+---------
+
+From: andrew@andrew.triumf.ca (Andrew Daviel)
+Date: 16 Feb 1995 23:32:21 GMT
+
+This is David Clunie's patch for xv-3.00 tuned a bit to work
+on xv-3.10. The code's all the same except for replacing 
+"trace" with "fprintf" in xvpcd.c and adding an "unsigned" qualifier to 
+keep my compiler (gcc) happy. Oh yes, changed RFT_PCD to 20 as
+John Bradley has now used 15 through 19.
+
+---------
+
+From: dclunie@flash.us.com (David A. Clunie)
+Date: Thu Jun 15 14:43:46 GMT+0300 1995
+
+Andrew's patch didn't include Colin's browser changes, so I redid the
+xv-3.10 update from scratch ... it seems pretty much the same as
+Andrew's changes. I also edited the Imakefile and Makefiles in order
+to support the PCD changes, as well as make the install process a
+little more flexible, with options to strip and set modes and so on.
+Also made RFT_PCD 25 so as not to conflict with magpic patch from Japan
+by Ikemoto Masahiro <ikeyan@airlab.cs.ritsumei.ac.jp>, and used his
+bitmap icon for pcd files.
+
+Now there are two versions of the patch, one which should be applied
+to the xv-3.10 distribution.
+
+The other should be applied to xv-3.10 AFTER Ikemoto Masahiro's 
+Patch.magpic2.PhotoCD.XV319a, in order to add the browser features to
+the latter, as well as fixing a Makefile typo (was xcpcd.c not xvpcd.c)
+and including unistd.h for the SEEK_xxx constants in the magicpic
+stuff.
+
+---------
+
+Subject: Re: photo-cd patch for xv 
+From: Matthew Francey <mdf@angoss.com>
+Date: Mon, 26 Mar 2001 15:37:55 +0000
+
+Attached is a revised version of xvpcd.c;  the areas that I have
+re-written or changed are in a different coding style so you can tell
+what has changed.  The GNU 'indent' program can be run against the file
+to enforce a consistent style ..
+
+Here is what I've done though:
+
+a) huffman table reader re-written, because it would fail on some
+   photocd files with "unusual" huffman codes.
+
+b) the huffman-coded corrections are now properly applied
+
+c) the corrections can sometimes over or underflow;  clipping has been
+   introduced and effectively fixes the problem, but I suspect that
+   there is something deeper going on.
+
+d) the "official" YCC->sRGB transform is done.  a "beyond 100% white"
+   mapping table was snarfed from ImageMagick.  an option for using a
+   flat linear LUT was added -- this can make somewhat over-exposed images
+   look alot nicer.
+
+e) there were strange problems where the code wouldn't be able to find
+   the huffman tables and data for the 16base image (the bit-buffering
+   code was starting mid-sector, instead of at a sector boundary).  Looking
+   at a pcd file with a hex editor suggests to me that it is possible to
+   just skip directly to these huffman tables -- no special "+12" and such
+   constants necessary.  But I haven't tried this yet.
+
+The results:  I've been able to read about 50 or 60 .pcd files [scattered
+in age from 6 years old to scans done last week] with this code without
+incident.  Image quality at the high resolution is excellent.  Even the
+trivial amount of LUT control is useful when dealing with over-exposed
+images.
+
+If I get around to it:  finer LUT control to take advantage of the
+slightly extended dynamic range of PhotoCD scans, especially in regards to
+dark or somewhat underexposed scenes.
+
+
+
+
diff -Nur xv-3.10a.clean/bits/br_pcd xv-3.10a.darwin/bits/br_pcd
--- xv-3.10a.clean/bits/br_pcd	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/bits/br_pcd	Sun Apr 27 21:37:41 2003
@@ -0,0 +1,27 @@
+#define br_pcd_width 48
+#define br_pcd_height 48
+static unsigned char br_pcd_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, 0x67, 0x00, 0xe0, 0x1c, 0x02,
+   0x20, 0x6f, 0x00, 0xf0, 0x3d, 0x02, 0x20, 0x6b, 0x00, 0xb0, 0x2d, 0x02,
+   0x20, 0x6b, 0x00, 0x33, 0x2c, 0x02, 0x20, 0x6b, 0x00, 0x33, 0x2c, 0x02,
+   0x20, 0xeb, 0x98, 0x37, 0x2c, 0x02, 0x20, 0xef, 0xbd, 0x37, 0x2c, 0x02,
+   0x20, 0x67, 0x2d, 0x33, 0x2c, 0x02, 0x20, 0x63, 0x2d, 0x33, 0x2c, 0x02,
+   0x20, 0x63, 0x2d, 0x33, 0x2c, 0x02, 0x20, 0x63, 0x2d, 0xb3, 0x2d, 0x02,
+   0x20, 0x63, 0x3d, 0xf7, 0x3d, 0x02, 0x20, 0x63, 0x19, 0xe6, 0x1c, 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};
diff -Nur xv-3.10a.clean/bits/br_png xv-3.10a.darwin/bits/br_png
--- xv-3.10a.clean/bits/br_png	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/bits/br_png	Sun Apr 27 21:37:41 2003
@@ -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,
+  };
diff -Nur xv-3.10a.clean/vdcomp.c xv-3.10a.darwin/vdcomp.c
--- xv-3.10a.clean/vdcomp.c	Thu Dec 22 14:34:47 1994
+++ xv-3.10a.darwin/vdcomp.c	Mon Sep 15 21:44:19 2003
@@ -110,10 +110,13 @@
      !defined(__bsdi__)                  && \
      !defined(sequent)
 
-#  if defined(hp300) || defined(hp800) || defined(NeXT)
+#  if defined(hp300) || defined(hp800) || defined(NeXT) || defined(darwin)
 #   include <sys/malloc.h>                /* it's in 'sys' on HPs and NeXT */
 #  else
 #   include <malloc.h>
+#  endif
+#  if defined(darwin)
+#   include <sys/types.h>
 #  endif
 # endif
 #endif /* !VMS */
diff -Nur xv-3.10a.clean/xcmap.c xv-3.10a.darwin/xcmap.c
--- xv-3.10a.clean/xcmap.c	Tue Jan  3 13:14:52 1995
+++ xv-3.10a.darwin/xcmap.c	Sun Apr 27 17:09:29 2003
@@ -140,8 +140,13 @@
     nxcells = nycells = 8;
   else if (dispcells>4)
     nxcells = nycells = 4;
-  else
+  else if (dispcells>2)
     nxcells = nycells = 2;
+  else
+  {
+    nxcells = 2;
+    nycells = 1;
+  }
   
   /**************** Create/Open X Resources ***************/
   if ((mfinfo = XLoadQueryFont(theDisp,FONT))==NULL) {
@@ -267,18 +272,25 @@
   
   x=y=w=h=1;
   i=XParseGeometry(geom,&x,&y,&w,&h);
-  if (i&WidthValue)  WIDE = (int) w;
-  if (i&HeightValue) HIGH = (int) h;
-  
-  if (i&XValue || i&YValue) hints.flags = USPosition;  
-  else hints.flags = PPosition;
-  
-  hints.flags |= USSize;
-  
-  if (i&XValue && i&XNegative) 
-    x = XDisplayWidth(theDisp,theScreen)-WIDE-abs(x);
-  if (i&YValue && i&YNegative) 
-    y = XDisplayHeight(theDisp,theScreen)-HIGH-abs(y);
+  if (i&WidthValue)
+  {
+    WIDE = (int) w;
+    hints.flags |= USSize;
+  }
+  if (i&HeightValue)
+  {
+    HIGH = (int) h;
+    hints.flags |= USSize;
+  }
+  
+  if (i&XValue || i&YValue)
+  {
+    if (i&XNegative) 
+      x = XDisplayWidth(theDisp,theScreen)-WIDE-abs(x);
+    if (i&YNegative) 
+      y = XDisplayHeight(theDisp,theScreen)-HIGH-abs(y);
+    hints.flags |= USPosition;  
+  }
   
   hints.x=x;             hints.y=y;
   hints.width  = WIDE;   hints.height = HIGH;
diff -Nur xv-3.10a.clean/xv.c xv-3.10a.darwin/xv.c
--- xv-3.10a.clean/xv.c	Thu Jan 19 10:08:43 1995
+++ xv-3.10a.darwin/xv.c	Sun Apr 27 21:35:32 2003
@@ -78,6 +78,7 @@
 
 static int    force8     = 0;   /* force 8-bit mode */
 static int    force24    = 0;   /* force 24-bit mode */
+static int    PcdSize    = -1;   /* force dialog to ask */
 
 /* used in DeleteCmd() and Quit() */
 static char  **mainargv;
@@ -277,6 +278,12 @@
   tiffW = (Window) NULL;  tiffUp = 0;
 #endif
 
+#ifdef HAVE_PNG
+  pngW = (Window) NULL;  pngUp = 0;
+#endif
+
+  pcdW = (Window) NULL;  pcdUp = 0;
+
   imap = ctrlmap = gmap = browmap = cmtmap = 0;
 
   ch_offx = ch_offy = p_offx = p_offy = 0;
@@ -309,7 +316,11 @@
   
   theScreen = DefaultScreen(theDisp);
   theCmap   = DefaultColormap(theDisp, theScreen);
-  rootW     = RootWindow(theDisp,theScreen);
+  if (spec_window) {
+	rootW = spec_window;
+  } else {
+  	rootW = RootWindow(theDisp,theScreen);
+  }
   theGC     = DefaultGC(theDisp,theScreen);
   theVisual = DefaultVisual(theDisp,theScreen);
   ncells    = DisplayCells(theDisp, theScreen);
@@ -326,37 +337,51 @@
    */
 
 
-
   /* if we *haven't* had a non-default visual specified,
      see if we have a TrueColor or DirectColor visual of 24 or 32 bits, 
      and if so, use that as the default visual (prefer TrueColor) */
 
   if (!visualstr && !useroot) {
+    VisualID     defvid;
     XVisualInfo *vinfo, rvinfo;
     int          best,  numvis;
     long         flags;
 
-    best = -1;
+    best          = -1;
     rvinfo.class  = TrueColor;
     rvinfo.screen = theScreen;
-    flags = VisualClassMask | VisualScreenMask;
+    flags         = VisualClassMask | VisualScreenMask;
+    defvid        = XVisualIDFromVisual(DefaultVisual(theDisp, 
+						      DefaultScreen(theDisp)));
     
     vinfo = XGetVisualInfo(theDisp, flags, &rvinfo, &numvis);
-    if (vinfo) {     /* look for a TrueColor, 24-bit or more (pref 24) */
-      for (i=0, best = -1; i<numvis; i++) {
+    if (vinfo) {
+      /* Check list, use 'default', first 24-bit, or first >24-bit */
+      for (i=0; i<numvis && best==-1; i++) {   /* default? */
+	if ((vinfo[i].visualid == defvid) && (vinfo[i].depth >= 24)) best=i;
+      }
+      for (i=0; i<numvis && best==-1; i++) {   /* 24-bit ? */
 	if (vinfo[i].depth == 24) best = i;
-	else if (vinfo[i].depth>24 && best<0) best = i;
+      }
+      for (i=0; i<numvis && best==-1; i++) {   /* >24-bit ? */
+	if (vinfo[i].depth >= 24) best = i;
       }
     }
-
+    
     if (best == -1) {   /* look for a DirectColor, 24-bit or more (pref 24) */
       rvinfo.class = DirectColor;
       if (vinfo) XFree((char *) vinfo);
+      
       vinfo = XGetVisualInfo(theDisp, flags, &rvinfo, &numvis);
       if (vinfo) {
-	for (i=0, best = -1; i<numvis; i++) {
+	for (i=0; i<numvis && best==-1; i++) {   /* default? */
+	  if ((vinfo[i].visualid == defvid) && (vinfo[i].depth >= 24)) best=i;
+	}
+	for (i=0; i<numvis && best==-1; i++) {   /* 24-bit ? */
 	  if (vinfo[i].depth == 24) best = i;
-	  else if (vinfo[i].depth>24 && best<0) best = i;
+	}
+	for (i=0; i<numvis && best==-1; i++) {   /* >24-bit ? */
+	  if (vinfo[i].depth >= 24) best = i;
 	}
       }
     }
@@ -364,8 +389,8 @@
     if (best>=0 && best<numvis) useOtherVisual(vinfo, best);
     if (vinfo) XFree((char *) vinfo);
   }
-
-
+  
+  
 			   
   if (visualstr && useroot) {
     fprintf(stderr, "%s: %sUsing default visual.\n",
@@ -782,7 +807,14 @@
   XSetTransientForHint(theDisp, tiffW, dirW);
 #endif
   
+#ifdef HAVE_PNG
+  CreatePNGW();
+  XSetTransientForHint(theDisp, pngW, dirW);
+#endif
   
+  CreatePCDW();
+  XSetTransientForHint(theDisp, pcdW, dirW);
+
   LoadFishCursors();
   SetCursors(-1);
   
@@ -950,7 +982,11 @@
   
   dispDEEP  = vinfo[best].depth;
   theScreen = vinfo[best].screen;
-  rootW     = RootWindow(theDisp, theScreen);
+  if (spec_window) {
+	rootW = spec_window;
+  } else {
+  	rootW = RootWindow(theDisp,theScreen);
+  }
   ncells    = vinfo[best].colormap_size;
   theCmap   = XCreateColormap(theDisp, rootW, theVisual, AllocNone);
   
@@ -1184,6 +1220,14 @@
       }
     }
 
+    else if (!argcmp(argv[i],"-windowid",3,0,&pm)) {
+      if (++i<argc) {
+	if (sscanf(argv[i], "%ld", &spec_window) != 1) {
+		fprintf(stderr,"%s: bad argument to -windowid '%s'\n",cmd,argv[i]);
+        }
+      }
+    }
+
     else if (!argcmp(argv[i],"-best24",3,0,&pm))          /* -best */
       conv24 = CONV24_BEST;
     
@@ -1361,6 +1405,11 @@
     else if (!argcmp(argv[i],"-norm",      5,1,&autonorm));   /* norm */
     else if (!argcmp(argv[i],"-nostat",    4,1,&nostat));     /* nostat */
     else if (!argcmp(argv[i],"-owncmap",   2,1,&owncmap));    /* own cmap */
+    else if (!argcmp(argv[i],"-pcd",4,0,&pm))	/* pcd with size */
+ 	{ if (i+1<argc) {
+ 		PcdSize = atoi(argv[++i]); 
+ 		}
+ 	}
     else if (!argcmp(argv[i],"-perfect",   3,1,&perfect));    /* -perfect */
     else if (!argcmp(argv[i],"-pkludge",   3,1,&winCtrPosKludge));
     else if (!argcmp(argv[i],"-poll",      3,1,&polling));    /* chk mod? */
@@ -1616,6 +1665,7 @@
   printoption("[-/+norm]");
   printoption("[-/+nostat]");
   printoption("[-/+owncmap]");
+  printoption("[-pcd size(0=192*128,1=384*256,2=768*512,3=1536*1024,4=3072*2048)]");
   printoption("[-/+perfect]");
   printoption("[-/+pkludge]");
   printoption("[-/+poll]");
@@ -1646,6 +1696,7 @@
   printoption("[-/+vsperfect]");
   printoption("[-wait seconds]");
   printoption("[-white color]");
+  printoption("[-windowid windowid]");
   printoption("[-/+wloop]");
   printoption("[filename ...]");
   fprintf(stderr,"\n\n");
@@ -1668,6 +1719,7 @@
   fprintf(stderr,"\t7: centered on a 'brick' background\n");
   fprintf(stderr,"\t8: symmetrical tiling\n");
   fprintf(stderr,"\t9: symmetrical mirrored tiling\n");
+  fprintf(stderr,"\t10: upper left corner\n");
   fprintf(stderr,"\n");
   Quit(1);
 }
@@ -1968,7 +2020,7 @@
 #else /* it is VMS */
       sprintf(filename, "[]xvXXXXXX");
 #endif
-      mktemp(filename);
+      mkstemp(filename);
 
       clearerr(stdin);
       fp = fopen(filename,"w");
@@ -2611,6 +2663,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 ||
@@ -2625,6 +2682,13 @@
 	   strncmp((char *) magicno, "\004%!", (size_t) 3)==0)   rv = RFT_PS;
 #endif
 
+#ifdef GS_PATH
+  else if (strncmp((char *) magicno, "%PDF",   (size_t) 4)==0)   rv = RFT_PS;
+#endif
+
+  else if (magicno[0]==0xff && magicno[1]==0xff &&
+           magicno[2]==0xff && magicno[3]==0xff) rv = RFT_PCD;
+
   return rv;
 }
 
@@ -2639,7 +2703,8 @@
   /* if quick is set, we're being called to generate icons, or something
      like that.  We should load the image as quickly as possible.  Currently,
      this only affects the LoadPS routine, which, if quick is set, only
-     generates the page file for the first page of the document */
+     generates the page file for the first page of the document .
+	 Also now affects PCD which now only loads a thumbnail */
 
   int rv = 0;
 
@@ -2668,7 +2733,11 @@
 #endif
 
 #ifdef HAVE_TIFF
-  case RFT_TIFF:    rv = LoadTIFF  (fname, pinfo);           break;
+  case RFT_TIFF:    rv = LoadTIFF  (fname, pinfo, quick);    break;
+#endif
+
+#ifdef HAVE_PNG
+  case RFT_PNG:     rv = LoadPNG   (fname, pinfo);         break;
 #endif
 
 #ifdef HAVE_PDS
@@ -2679,6 +2748,16 @@
   case RFT_PS:      rv = LoadPS    (fname, pinfo, quick);    break;
 #endif
 
+  case RFT_PCD:      
+	if (quick == 1)
+		rv = LoadPCD(fname, pinfo, 0);  
+	else
+		rv = LoadPCD(fname, pinfo, PcdSize);  
+	break;
+
+	/* If quick is switched on use the smallest image size don't ask
+	*	the user.
+	*/
   }
   return rv;
 }
@@ -2724,11 +2803,11 @@
   
 #ifndef VMS
   sprintf(uncompname, "%s/xvuXXXXXX", tmpdir);
-  mktemp(uncompname);
+  mkstemp(uncompname);
   sprintf(buf,"%s -c %s >%s", UNCOMPRESS, fname, uncompname);
 #else /* it IS VMS */
   strcpy(uncompname, "[]xvuXXXXXX");
-  mktemp(uncompname);
+  mkstemp(uncompname);
 #  ifdef GUNZIP
   sprintf(buf,"%s %s %s", UNCOMPRESS, fname, uncompname);
 #  else
@@ -2899,8 +2978,8 @@
   if (!cmd || (strlen(cmd) < (size_t) 2)) return 1;
 
   sprintf(tmpname,"%s/xvXXXXXX", tmpdir);
-  mktemp(tmpname);
-  if (tmpname[0] == '\0') {   /* mktemp() blew up */
+  mkstemp(tmpname);
+  if (tmpname[0] == '\0') {   /* mkstemp() blew up */
     sprintf(str,"Unable to create temporary filename.");
     ErrPopUp(str, "\nHow unlikely!");
     return 1;
@@ -4043,16 +4122,30 @@
       unsigned long nitems, nleft;
       byte *data;
 
+      if (spec_window) {
+      i = XGetWindowProperty(theDisp, spec_window,
+			     resAtom, 0L, 1L, False, 
+			     XA_STRING, &actType, &actFormat, &nitems, &nleft, 
+			     (unsigned char **) &data);
+      } else {
       i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0),
 			     resAtom, 0L, 1L, False, 
 			     XA_STRING, &actType, &actFormat, &nitems, &nleft, 
 			     (unsigned char **) &data);
+      }
       if (i==Success && actType==XA_STRING && actFormat==8) {
 	if (nitems>0 && data) XFree(data);
+        if (spec_window) {
+	i = XGetWindowProperty(theDisp, spec_window, resAtom, 0L, 
+			       (long) ((nleft+4+3)/4),
+			       False, XA_STRING, &actType, &actFormat, 
+			       &nitems, &nleft, (unsigned char **) &data);
+        } else {
 	i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0), resAtom, 0L, 
 			       (long) ((nleft+4+3)/4),
 			       False, XA_STRING, &actType, &actFormat, 
 			       &nitems, &nleft, (unsigned char **) &data);
+        }
 	if (i==Success && actType==XA_STRING && actFormat==8 && data) {
 	  def_resource = XrmGetStringDatabase((char *) data);
 	  XFree(data);
diff -Nur xv-3.10a.clean/xv.h xv-3.10a.darwin/xv.h
--- xv-3.10a.clean/xv.h	Mon Jan 23 12:22:23 1995
+++ xv-3.10a.darwin/xv.h	Mon Sep 15 19:42:37 2003
@@ -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 (PCD, PNG-1.2)"
+#define VERSTR    "3.10a(PCD, PNG)"
 
 /*
  * uncomment the following, and modify for your site, but only if you've
@@ -116,7 +116,11 @@
 #  include <errno.h>
    extern int   errno;             /* SHOULD be in errno.h, but often isn't */
 #  ifndef __NetBSD__
-     extern char *sys_errlist[];     /* this too... */
+#    ifdef darwin
+       extern __const char *__const sys_errlist[];
+#    else
+       extern char *sys_errlist[];     /* this too... */
+#    endif
 #  endif
 #endif
 
@@ -161,7 +165,7 @@
      !defined(__bsdi__)                  && \
      !defined(sequent)
 
-#  if defined(hp300) || defined(hp800) || defined(NeXT)
+#  if defined(hp300) || defined(hp800) || defined(NeXT) || defined(darwin)
 #   include <sys/malloc.h>                /* it's in 'sys' on HPs and NeXT */
 #  else
 #   include <malloc.h>
@@ -327,6 +331,10 @@
 #define HAVE_TIFF
 #endif
 
+#ifdef DOPNG
+#define HAVE_PNG
+#endif
+
 #ifdef DOPDS
 #define HAVE_PDS
 #endif
@@ -458,24 +466,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 +520,8 @@
 #define RFT_XPM      17
 #define RFT_XWD      18
 #define RFT_FITS     19
+#define RFT_PNG      20
+#define RFT_PCD      25
 
 /* definitions for page up/down, arrow up/down list control */
 #define LS_PAGEUP   0
@@ -563,7 +580,8 @@
 #define RM_CBRICK  7     /* centered on a 'brick' bg */
 #define RM_ECENTER 8     /* symmetrical tiled */
 #define RM_ECMIRR  9     /* symmetrical mirror tiled */
-#define RM_MAX     RM_ECMIRR
+#define RM_UPLEFT 10     /* just in upper left corner */
+#define RM_MAX     RM_UPLEFT
 
 
 /* values of colorMapMode */
@@ -613,7 +631,8 @@
 #define RMB_CBRICK   8
 #define RMB_ECENTER  9
 #define RMB_ECMIRR   10
-#define RMB_MAX      11
+#define RMB_UPLEFT   11
+#define RMB_MAX      12
 
 
 /* indicies into conv24MB */
@@ -765,9 +784,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 */
@@ -935,7 +955,7 @@
 WHERE unsigned int  ncells, dispWIDE, dispHIGH, dispDEEP;
 WHERE unsigned int  vrWIDE, vrHIGH, maxWIDE, maxHIGH;
 WHERE Colormap      theCmap, LocalCmap;
-WHERE Window        rootW, mainW, vrootW;
+WHERE Window        spec_window, rootW, mainW, vrootW;
 WHERE GC            theGC;
 WHERE u_long        black, white, fg, bg, infofg, infobg;
 WHERE u_long        hicol, locol;
@@ -1154,6 +1174,17 @@
 #endif
 
 
+#ifdef HAVE_PNG
+/* stuff used for 'png' box */
+WHERE Window        pngW;
+WHERE int           pngUp;        /* is pngW mapped, or what? */
+#endif
+
+/* stuff used for 'pcd' box */
+WHERE Window        pcdW;
+WHERE int           pcdUp;       /* is pcdW mapped, or what? */
+
+
 #undef WHERE
 
 
@@ -1248,6 +1279,7 @@
 void xv_getwd               PARM((char *, size_t));
 char *xv_strstr             PARM((char *, char *));
 FILE *xv_fopen              PARM((char *, char *));
+void xv_mktemp              PARM((char *, char *));
 void Timer                  PARM((int));
 
 /*************************** XVCOLOR.C ***************************/
@@ -1465,12 +1497,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));
@@ -1607,12 +1639,19 @@
 void JPEGSaveParams        PARM((char *, int));
 
 /**************************** XVTIFF.C ***************************/
-int   LoadTIFF             PARM((char *, PICINFO *));
+int   LoadTIFF             PARM((char *, PICINFO *, int));
 void  CreateTIFFW          PARM((void));
 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 *));
 
@@ -1623,6 +1662,13 @@
 void  PSSaveParams         PARM((char *, int));
 void  PSResize             PARM((void));
 int   LoadPS               PARM((char *, PICINFO *, int));
+
+/**************************** XVPCD.C ***************************/
+int   LoadPCD              PARM((char *, PICINFO *, int));
+void  CreatePCDW           PARM((void));
+void  PCDDialog            PARM((int));
+int   PCDCheckEvent        PARM((XEvent *));
+void  PCDSetParamOptions   PARM((char *));
 
 /*************************** XVPOPUP.C ***************************/
 void  CenterMapWindow      PARM((Window, int, int, int, int));
diff -Nur xv-3.10a.clean/xvbmp.c xv-3.10a.darwin/xvbmp.c
--- xv-3.10a.clean/xvbmp.c	Thu Dec 22 14:34:42 1994
+++ xv-3.10a.darwin/xvbmp.c	Sun Apr 27 17:09:28 2003
@@ -32,7 +32,7 @@
 static int   loadBMP1   PARM((FILE *, byte *, u_int, u_int));
 static int   loadBMP4   PARM((FILE *, byte *, u_int, u_int, u_int));
 static int   loadBMP8   PARM((FILE *, byte *, u_int, u_int, u_int));
-static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int));
+static int   loadBMP24  PARM((FILE *, byte *, u_int, u_int, u_int));
 static u_int getshort   PARM((FILE *));
 static u_int getint     PARM((FILE *));
 static void  putshort   PARM((FILE *, int));
@@ -127,7 +127,8 @@
 
 
   /* error checking */
-  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && biBitCount!=24) || 
+  if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && 
+       biBitCount!=24 && biBitCount!=32) || 
       biPlanes!=1 || biCompression>BI_RLE4) {
 
     sprintf(buf,"Bogus BMP File!  (bitCount=%d, Planes=%d, Compression=%d)",
@@ -137,7 +138,8 @@
     goto ERROR;
   }
 
-  if (((biBitCount==1 || biBitCount==24) && biCompression != BI_RGB) ||
+  if (((biBitCount==1 || biBitCount==24 || biBitCount==32)
+       && biCompression != BI_RGB) ||
       (biBitCount==4 && biCompression==BI_RLE8) ||
       (biBitCount==8 && biCompression==BI_RLE4)) {
 
@@ -159,7 +161,7 @@
   }
 
   /* load up colormap, if any */
-  if (biBitCount!=24) {
+  if (biBitCount!=24 && biBitCount!=32) {
     int i, cmaplen;
 
     cmaplen = (biClrUsed) ? biClrUsed : 1 << biBitCount;
@@ -197,7 +199,7 @@
 
   /* create pic8 or pic24 */
 
-  if (biBitCount==24) {
+  if (biBitCount==24 || biBitCount==32) {
     pic24 = (byte *) calloc((size_t) biWidth * biHeight * 3, (size_t) 1);
     if (!pic24) return (bmpError(bname, "couldn't malloc 'pic24'"));
   }
@@ -212,16 +214,18 @@
   if      (biBitCount == 1) rv = loadBMP1(fp,pic8,biWidth,biHeight);
   else if (biBitCount == 4) rv = loadBMP4(fp,pic8,biWidth,biHeight,
 					  biCompression);
-  else if (biBitCount == 8) rv = loadBMP8(fp,pic8,biWidth,biHeight,
+  else if (biBitCount == 8) rv = loadBMP8(fp,pic8,biWidth,biHeight, 
 					  biCompression);
-  else                      rv = loadBMP24(fp,pic24,biWidth,biHeight);
+  else                      rv = loadBMP24(fp,pic24,biWidth,biHeight,
+					   biBitCount);
+
 
   if (rv) bmpError(bname, "File appears truncated.  Winging it.\n");
 
   fclose(fp);
 
 
-  if (biBitCount == 24) {
+  if (biBitCount == 24 || biBitCount == 32) {
     pinfo->pic  = pic24;
     pinfo->type = PIC24;
   }
@@ -384,10 +388,12 @@
      u_int  w,h,comp;
 {
   int   i,j,c,c1,padw,x,y,rv;
-  byte *pp;
+  byte *pp, *pend;
   
   rv = 0;
 
+  pend = pic8 + w * h;
+
   if (comp == BI_RGB) {   /* read uncompressed data */
     padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */
 
@@ -407,12 +413,12 @@
     x = y = 0;  
     pp = pic8 + x + (h-y-1)*w;
 
-    while (y<h) {
+    while (y<h && pp<=pend) {
       c = getc(fp);  if (c == EOF) { rv = 1;  break; }
 
       if (c) {                                   /* encoded mode */
 	c1 = getc(fp);
-	for (i=0; i<c; i++,x++,pp++) *pp = c1;
+	for (i=0; i<c && pp<=pend; i++,x++,pp++) *pp = c1;
       }
 
       else {    /* c==0x00  :  escape codes */
@@ -431,7 +437,7 @@
 	}
 
 	else {                                   /* absolute mode */
-	  for (i=0; i<c; i++, x++, pp++) {
+	  for (i=0; i<c && pp<=pend; i++, x++, pp++) {
 	    c1 = getc(fp);
 	    *pp = c1;
 	  }
@@ -454,10 +460,10 @@
 
 
 /*******************************************/
-static int loadBMP24(fp, pic24, w, h)
+static int loadBMP24(fp, pic24, w, h, bits)
      FILE *fp;
      byte *pic24;
-     u_int  w,h;
+     u_int  w,h, bits;
 {
   int   i,j,padb,rv;
   byte *pp;
@@ -465,6 +471,7 @@
   rv = 0;
 
   padb = (4 - ((w*3) % 4)) & 0x03;  /* # of pad bytes to read at EOscanline */
+  if (bits==32) padb = 0;
 
   for (i=h-1; i>=0; i--) {
     pp = pic24 + (i * w * 3);
@@ -474,6 +481,7 @@
       pp[2] = getc(fp);   /* blue */
       pp[1] = getc(fp);   /* green */
       pp[0] = getc(fp);   /* red */
+      if (bits==32) getc(fp);
       pp += 3;
     }
 
diff -Nur xv-3.10a.clean/xvbrowse.c xv-3.10a.darwin/xvbrowse.c
--- xv-3.10a.clean/xvbrowse.c	Thu Jan 19 09:49:17 1995
+++ xv-3.10a.darwin/xvbrowse.c	Sun Apr 27 23:03:32 2003
@@ -50,11 +50,13 @@
 #include "bits/br_tiff"
 #include "bits/br_pds"
 #include "bits/br_ps"
+#include "bits/br_pcd"
 #include "bits/br_iff"
 #include "bits/br_targa"
 #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 +96,9 @@
 #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_PCD      29
+#define BF_MAX      30    /* # of built-in icons */
 
 #define ISLOADABLE(ftyp) (ftyp!=BF_DIR  && ftyp!=BF_CHR && ftyp!=BF_BLK && \
 			  ftyp!=BF_SOCK && ftyp!=BF_FIFO) 
@@ -524,6 +528,8 @@
   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);
+  bfIcons[BF_PCD]=MakePix1(br->win,br_pcd_bits,br_pcd_width,br_pcd_height);
 
 
   /* check that they all got built */
@@ -956,6 +962,7 @@
      char *str;
 {
   strncpy(br->dispstr, str, (size_t) 256);
+  br->dispstr[255] = '\0';
   drawBrowStr(br);
   XFlush(theDisp);
 }
@@ -1490,6 +1497,7 @@
   if (StringWidth(str) > ISPACE_WIDE-6) {
     int dotpos; 
     strncpy(tmpstr, str, (size_t) 56);
+    tmpstr[56] = '\0'; /* MR: otherwise it dies on long file names */
     dotpos = strlen(tmpstr);
     strcat(tmpstr,"...");
 
@@ -1505,7 +1513,7 @@
     nstr = tmpstr;
   }
   else nstr = str;
-  
+ 
 
   /* draw the title */
   sw = StringWidth(nstr);
@@ -3020,6 +3028,8 @@
     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;
+    case RFT_PCD:      bf->ftype = BF_PCD;      break;
     }
   }
 }
@@ -3567,6 +3577,8 @@
   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;
+  case RFT_PCD:      strcat(str,"PhotoCD file");          break;
   default:           strcat(str,"file of unknown type");  break;
   }
   
@@ -4747,6 +4759,17 @@
     sprintf(src, "%s%s/bozo", dstp, THUMBDIR);
     DIRCreatedFile(src);
   }
+
+
+  if (!cpymode) {
+    /* clear all lit files in the source folder (as they've been moved)
+       note:  this won't be the optimal behavior if any files failed to
+       move, but screw it, that's not going to happen too often... */
+
+    for (i=0; i<srcBr->bfLen; i++) srcBr->bfList[i].lit = 0;
+    srcBr->numlit = 0;
+  }
+
 
 
   /* clear all files in the destination folder */
diff -Nur xv-3.10a.clean/xvctrl.c xv-3.10a.darwin/xvctrl.c
--- xv-3.10a.clean/xvctrl.c	Thu Dec 22 14:34:41 1994
+++ xv-3.10a.darwin/xvctrl.c	Sun Apr 27 17:09:29 2003
@@ -101,7 +101,8 @@
 			     "Root: centered, warp",
 			     "Root: centered, brick",
     		             "Root: symmetrical tiled",
-			     "Root: symmetrical mirrored" };
+			     "Root: symmetrical mirrored",
+			     "Root: upper left corner" };
 
 static char *conv24MList[] = { "8-bit mode\t\2448",
 			       "24-bit mode\t\2448",
diff -Nur xv-3.10a.clean/xvdial.c xv-3.10a.darwin/xvdial.c
--- xv-3.10a.clean/xvdial.c	Tue Jan  3 13:20:31 1995
+++ xv-3.10a.darwin/xvdial.c	Sun Apr 27 17:09:29 2003
@@ -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;
 }
 
diff -Nur xv-3.10a.clean/xvdir.c xv-3.10a.darwin/xvdir.c
--- xv-3.10a.clean/xvdir.c	Tue Jan  3 13:21:39 1995
+++ xv-3.10a.darwin/xvdir.c	Sun Apr 27 21:36:01 2003
@@ -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);    
@@ -1200,6 +1213,7 @@
      char *st;
 {
   strncpy(deffname, st, (size_t) MAXFNLEN-1);
+  deffname[MAXFNLEN-1] = '\0';
   setFName(st);
 }
 
@@ -1380,14 +1394,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 +1444,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 */
@@ -1596,7 +1621,7 @@
 #else
     strcpy(outFName, "[]xvXXXXXX.lis");
 #endif
-    mktemp(outFName);
+    mkstemp(outFName);
     dopipe = 1;
   }
 
diff -Nur xv-3.10a.clean/xvevent.c xv-3.10a.darwin/xvevent.c
--- xv-3.10a.clean/xvevent.c	Mon Jan 23 15:20:24 1995
+++ xv-3.10a.darwin/xvevent.c	Sun Apr 27 17:19:04 2003
@@ -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, wasPcdUp=0;
 
   static int mainWKludge=0;  /* force first mainW expose after a mainW config
 				to redraw all of mainW */
@@ -233,6 +233,12 @@
     if (TIFFCheckEvent(event)) break;   /* event has been processed */
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;   /* event has been processed */
+#endif
+
+    if (PCDCheckEvent(event)) break;    /* event has been processed */
+
     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 +365,12 @@
       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 == pcdW) PCDDialog(0);
+
       else if (client_event->window == mainW) Quit(0);
     }
   }
@@ -538,6 +550,12 @@
 #ifdef HAVE_TIFF
 	if (wasTiffUp) { TIFFDialog(wasTiffUp);  wasTiffUp=0; }
 #endif
+
+#ifdef HAVE_PNG
+	if (wasPngUp)  { PNGDialog(wasJpegUp);   wasPngUp=0; }
+#endif
+
+	if (wasPcdUp)  { PCDDialog(wasPcdUp);    wasPcdUp=0; }
       }
     }
   }
@@ -576,6 +594,12 @@
 #ifdef HAVE_TIFF
 	  if (tiffUp) { wasTiffUp = tiffUp;  TIFFDialog(0); }
 #endif
+
+#ifdef HAVE_PNG
+	  if (pngUp)  { wasPngUp  = pngUp;   PNGDialog(0); }
+#endif
+
+	  if (pcdUp) { wasPcdUp = pcdUp;  PCDDialog(0); }
 	}
       }
     }
@@ -1147,6 +1171,12 @@
     if (TIFFCheckEvent(event)) break;
 #endif
     
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+    
+    if (PCDCheckEvent(event)) break;    /* event has been processed */
+
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
@@ -1366,6 +1396,12 @@
     if (TIFFCheckEvent(event)) break;
 #endif
 
+#ifdef HAVE_PNG
+    if (PNGCheckEvent (event)) break;
+#endif
+
+    if (PCDCheckEvent(event)) break;
+
     if (GamCheckEvent (event)) break;
     if (BrowseCheckEvent (event, &retval, &done)) break;
     if (TextCheckEvent   (event, &retval, &done)) break;
@@ -2368,8 +2404,14 @@
   if (jpegUp) JPEGDialog(0);  /* close jpeg window */
 #endif
 
+  if (pcdUp) PCDDialog(0);    /* close pcd window */
+
 #ifdef HAVE_TIFF
   if (tiffUp) TIFFDialog(0);  /* close tiff window */
+#endif
+
+#ifdef HAVE_PNG
+  if (pngUp) PNGDialog(0);    /* close png window */
 #endif
 
   ClosePopUp();
diff -Nur xv-3.10a.clean/xvfits.c xv-3.10a.darwin/xvfits.c
--- xv-3.10a.clean/xvfits.c	Tue Dec 27 23:43:29 1994
+++ xv-3.10a.darwin/xvfits.c	Sun Apr 27 21:35:46 2003
@@ -235,7 +235,7 @@
   sprintf(basename, "Sys$Disk:[]xvpgXXXXXX");
 #endif
   
-  mktemp(basename);
+  mkstemp(basename);
   if (basename[0] == '\0') {
     SetISTR(ISTR_WARNING, "%s", "Unable to build temporary filename");
     return 1;
diff -Nur xv-3.10a.clean/xvgam.c xv-3.10a.darwin/xvgam.c
--- xv-3.10a.clean/xvgam.c	Fri Jan 13 11:51:14 1995
+++ xv-3.10a.darwin/xvgam.c	Sun Apr 27 17:09:29 2003
@@ -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;
 
diff -Nur xv-3.10a.clean/xvgif.c xv-3.10a.darwin/xvgif.c
--- xv-3.10a.clean/xvgif.c	Tue Jan 10 11:54:41 1995
+++ xv-3.10a.darwin/xvgif.c	Sun Apr 27 17:09:28 2003
@@ -113,7 +113,8 @@
   int            aspect, gotimage;
 
   /* initialize variables */
-  BitOffset = XC = YC = Pass = OutCount = gotimage = 0;
+  BitOffset = XC = YC = OutCount = gotimage = 0;
+  Pass = -1;
   RawGIF = Raster = pic8 = NULL;
   gif89 = 0;
 
@@ -692,7 +693,12 @@
 {
   static byte *ptr = NULL;
   static int   oldYC = -1;
-  
+
+  if (Pass == -1) {  /* first time through - init stuff */
+    oldYC = -1;
+    Pass = 0;
+  }
+
   if (oldYC != YC) {  ptr = pic8 + YC * Width;  oldYC = YC; }
   
   if (YC<Height)
diff -Nur xv-3.10a.clean/xvgrab.c xv-3.10a.darwin/xvgrab.c
--- xv-3.10a.clean/xvgrab.c	Thu Dec 22 14:34:47 1994
+++ xv-3.10a.darwin/xvgrab.c	Sun Apr 27 17:09:28 2003
@@ -341,16 +341,16 @@
 	 ConfigureNotify on mainW */
 
       state = 0;
-      while (1) {
+      while (state != 3) {
 	XEvent event;
 	XNextEvent(theDisp, &event);
 	HandleEvent(&event, &i);
 
-	if (state==0 && event.type == MapNotify &&
-	    event.xmap.window == mainW) state = 1;
+	if (!(state&1) && event.type == MapNotify &&
+	    event.xmap.window == mainW) state |= 1;
 
-	if (state==1 && event.type == ConfigureNotify && 
-	    event.xconfigure.window == mainW) break;
+	if (!(state&2) && event.type == ConfigureNotify && 
+	    event.xconfigure.window == mainW) state |= 2;
       }
 
       if (DEBUG) fprintf(stderr,"==after remapping mainW, GOT Config.\n");
@@ -641,8 +641,27 @@
 
 
   bits_per_item = image->bitmap_unit;
-  bits_used = bits_per_item;
   bits_per_pixel = image->bits_per_pixel;
+
+
+  /* add code for freako 'exceed' server, where bitmapunit = 8
+     and bitsperpix = 32 (and depth=24)... */
+
+  if (bits_per_item < bits_per_pixel) {
+    bits_per_item = bits_per_pixel;
+  
+    /* round bits_per_item up to next legal value, if necc */
+    if      (bits_per_item <  8) bits_per_item = 8;
+    else if (bits_per_item < 16) bits_per_item = 16;
+    else                         bits_per_item = 32;
+  }
+
+
+  /* which raises the question:  how (can?) you ever have a 24 bits per pix,
+     (ie, 3 bytes, no alpha/padding) */
+
+
+  bits_used = bits_per_item;  /* so it will get a new item first time */
 
   if (bits_per_pixel == 32) pixmask = 0xffffffff;
   else pixmask = (((CARD32) 1) << bits_per_pixel) - 1;
diff -Nur xv-3.10a.clean/xvimage.c xv-3.10a.darwin/xvimage.c
--- xv-3.10a.clean/xvimage.c	Fri Jan 13 16:11:36 1995
+++ xv-3.10a.darwin/xvimage.c	Sun Apr 27 21:37:04 2003
@@ -1736,10 +1736,12 @@
     if (xim->byte_order == MSBFirst) {
       for (i=wide*high, ip=imagedata; i>0; i--,pp++) {
 	if (((i+1)&0x1ffff) == 0) WaitCursor();
-	if (dithpic) {
-	  *ip++ = ((*pp) ? white : black) & 0xffff;
-	}
-	else *ip++ = xcolors[*pp] & 0xffff;
+
+	if (dithpic) xcol = ((*pp) ? white : black) & 0xffff;
+		else xcol = xcolors[*pp] & 0xffff;
+
+	*((unsigned char *)ip)++ = (xcol>>8) & 0xff;
+	*((unsigned char *)ip)++ = (xcol) & 0xff;
       }
     }
     else {   /* LSBFirst */
@@ -1749,8 +1751,8 @@
 	if (dithpic) xcol = ((*pp) ? white : black) & 0xffff;
 	        else xcol = xcolors[*pp];
 
-	/*  WAS *ip++ = ((xcol>>8) & 0xff) | ((xcol&0xff) << 8);  */
-	*ip++ = (unsigned short) (xcol);
+	*((unsigned char *)ip)++ = (xcol) & 0xff;
+	*((unsigned char *)ip)++ = (xcol>>8) & 0xff;
       }
     }
   }
@@ -2697,7 +2699,7 @@
 #else
   strcpy(fname, "Sys$Disk:[]xvuXXXXXX");
 #endif
-  mktemp(fname);
+  mkstemp(fname);
 
   /* run bggen to generate the background */
   sprintf(syscmd, "bggen -g %dx%d %s > %s", wide, high, str, fname);
diff -Nur xv-3.10a.clean/xvjpeg.c xv-3.10a.darwin/xvjpeg.c
--- xv-3.10a.clean/xvjpeg.c	Thu Jan  5 00:17:13 1995
+++ xv-3.10a.darwin/xvjpeg.c	Sun Apr 27 17:09:29 2003
@@ -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,8 @@
 
 
   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;
 
 
   jpeg_start_compress(&cinfo, TRUE);
@@ -769,7 +769,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;
diff -Nur xv-3.10a.clean/xvmisc.c xv-3.10a.darwin/xvmisc.c
--- xv-3.10a.clean/xvmisc.c	Fri Jan 13 15:41:34 1995
+++ xv-3.10a.darwin/xvmisc.c	Sun Apr 27 17:09:30 2003
@@ -28,6 +28,8 @@
  *     int    xvbcmp (s1,  s2,  length)
  *     void   xvbzero(s, length)
  *     char  *xv_strstr(s1, s2)
+ *     FILE  *xv_fopen(str, str)
+ *     void   xv_mktemp(str)
  *     void   Timer(milliseconds)
  */
 
@@ -520,6 +522,12 @@
     if (tiffW) XDestroyWindow(theDisp, tiffW);
 #endif
 
+#ifdef HAVE_PNG
+    if (pngW)  XDestroyWindow(theDisp, pngW);
+#endif
+
+    if (pcdW) XDestroyWindow(theDisp, pcdW);
+
     /* if NOT using stdcmap for images, free stdcmap */
     if (colorMapMode != CM_STDCMAP) { 
       int j;
@@ -716,6 +724,12 @@
 #ifdef HAVE_TIFF
   if (tiffW) XDefineCursor(theDisp, tiffW, otherc);
 #endif
+
+#ifdef HAVE_PNG
+  if (pngW)  XDefineCursor(theDisp, pngW, otherc);
+#endif
+  
+  if (pcdW) XDefineCursor(theDisp, pcdW, otherc);
 }
 
 
@@ -1066,6 +1080,16 @@
 }
 
 
+/***************************************************/
+void xv_mktemp(buf, fname)
+     char *buf, *fname;
+{
+#ifndef VMS
+  sprintf(buf, "%s/%s", tmpdir, fname);
+#else
+  sprintf(buf, "Sys$Disk:[]%s", fname);
+#endif
+}
 
 
 /*******/
diff -Nur xv-3.10a.clean/xvpcd.c xv-3.10a.darwin/xvpcd.c
--- xv-3.10a.clean/xvpcd.c	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/xvpcd.c	Mon Sep 15 21:37:24 2003
@@ -0,0 +1,1272 @@
+/*
+ * xvpcd.c - load routine for 'PhotoCD' format pictures
+ *
+ * LoadPCD(fname, pinfo, size)  -  loads a PhotoCD file
+ *
+ * This routine will popup a choice of which of the 5 available resolutions
+ * the user wants to choose, then load it as a 24 bit image.
+ *
+ * Copyright 1993 David Clunie, Melbourne, Australia.
+ *
+ * The outline of this is shamelessly derived from xvpbm.c to read the
+ * file, and xvtiffwr.c to handle the popup window and X stuff (X never
+ * has been my forte !), and the PhotoCD format information (though not
+ * the code) was found in Hadmut Danisch's (danisch@ira.uka.de) hpcdtoppm
+ * program in which he has reverse engineered the format by studying
+ * hex dumps of PhotoCDs ! After all who can afford the Kodak developer's
+ * kit, which none of us have seen yet ? Am I even allowed to mention these
+ * words (Kodak, PhotoCD) ? I presume they are registered trade marks.
+ *
+ * PS. I have no idea how Halmut worked out the YCC <-> RGB conversion
+ * factors, but I have calculated them from his tables and the results
+ * look good enough to me.
+ *
+ * Added size parameter to allow the schnautzer to create thumnails
+ * without requesting the size every time.
+ */
+#define	TRACE	0
+#if TRACE
+#define	trace fprintf
+#else
+#define trace (void)
+#endif
+
+#include "xv.h"
+#include <memory.h>
+#include <stdlib.h>
+
+/* comments on error handling:
+   a truncated file is not considered a Major Error.  The file is loaded, the
+   rest of the pic is filled with 0's.
+
+   not being able to malloc is a Fatal Error.  The program is aborted. */
+
+
+#ifdef __STDC__
+static void magnify(int, int, int, int, int, byte *);
+static int pcdError(char *, char *);
+static int gethuffdata(byte *, byte *, byte *,
+							int, int);
+#else
+static void magnify();
+static int pcdError();
+static int gethuffdata();
+#endif
+
+#define wcurfactor 16	/* Call WaitCursor() every n rows */
+
+static int	size;	  /* Set by window routines */
+static int	leaveitup;/* Cleared by docmd() when OK or CANCEL pressed */
+static int	goforit;  /* Set to 1 if OK or 0 if CANCEL */
+static FILE	*fp;
+static CBUTT  lutCB;
+
+/*
+ * this "beyond 100%" table is taken from ImageMagick (gamma 2.2)
+ * why there are 351 entries and not 346 as per Kodak documentation
+ * is a mystery.
+ */
+static	double	rscale = 1.00,
+		gscale = 1.00,
+		bscale = 1.00;
+
+static	byte	Y[351] = {
+	  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
+	 10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
+	 20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
+	 30,  32,  33,  34,  35,  36,  37,  38,  39,  40,
+	 41,  42,  43,  45,  46,  47,  48,  49,  50,  51,
+	 52,  53,  54,  56,  57,  58,  59,  60,  61,  62,
+	 63,  64,  66,  67,  68,  69,  70,  71,  72,  73,
+	 74,  76,  77,  78,  79,  80,  81,  82,  83,  84,
+	 86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
+	 97,  98,  99, 100, 101, 102, 103, 104, 105, 106,
+	107, 108, 110, 111, 112, 113, 114, 115, 116, 117,
+	118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+	129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
+	139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+	149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+	159, 160, 161, 162, 163, 164, 165, 166, 167, 168,
+	169, 170, 171, 172, 173, 174, 175, 176, 176, 177,
+	178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
+	188, 189, 190, 191, 192, 193, 193, 194, 195, 196,
+	197, 198, 199, 200, 201, 201, 202, 203, 204, 205,
+	206, 207, 207, 208, 209, 210, 211, 211, 212, 213,
+	214, 215, 215, 216, 217, 218, 218, 219, 220, 221,
+	221, 222, 223, 224, 224, 225, 226, 226, 227, 228,
+	228, 229, 230, 230, 231, 232, 232, 233, 234, 234,
+	235, 236, 236, 237, 237, 238, 238, 239, 240, 240,
+	241, 241, 242, 242, 243, 243, 244, 244, 245, 245,
+	245, 246, 246, 247, 247, 247, 248, 248, 248, 249,
+	249, 249, 249, 250, 250, 250, 250, 251, 251, 251,
+	251, 251, 252, 252, 252, 252, 252, 253, 253, 253,
+	253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
+	254, 254, 254, 254, 254, 254, 254, 254, 254, 254,
+	254, 254, 254, 254, 254, 254, 254, 254, 254, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+	255
+};
+
+/*******************************************/
+/* The size should be -1 for the popup to ask otherwise fast is assumed */
+/* returns '1' on success */
+/*******************************************/
+int
+LoadPCD(char *fname, PICINFO *pinfo, int theSize)
+{
+  int    c, c1;
+  int    rv;
+  long   offset;
+  int    mag;
+  int	 rotate;
+  byte	 header[3*0x800];
+  byte	*pic24, *luma, *chroma1, *chroma2, *ptr, *lptr, *c1ptr, *c2ptr;
+  int   w, h;
+  int   row, col;
+	int	huffplanes;
+	char	*bname;
+
+	bname		= BaseName(fname);
+	pinfo->pic	= NULL;
+	pinfo->comment	= NULL;
+
+
+	/*
+	 *  open the file
+	 */
+	if((fp=fopen(fname,"r")) == NULL)
+		return pcdError(bname, "can't open file");
+
+	/*
+	 * inspect the header
+	 */
+	if(fread(&header[0], 1, sizeof(header), fp) != sizeof(header))
+		return pcdError(bname, "could not load PCD header");
+	if(strncmp(&header[0x800], "PCD_", 4) != 0)
+		return pcdError(bname, "not a PCD file");
+	rotate = header[0x0E02] & 0x03;
+
+/* base/16
+	- plain data starts at sector 1+2+1=4
+	  (numbered from 0, ie. the 5th sector)
+	- luma 192*128 = 24576 bytes (12 sectors)
+	  + chroma1 96*64 = 6144 bytes (3 sectors)
+	  + chroma2 96*64 = 6144 bytes (3 sectors)
+	  = total 18 sectors
+
+	- NB. "Plain" data is interleaved - 2 luma rows 192 wide,
+	  then 1 of each of the chroma rows 96 wide !
+
+   base/4
+	- plain data starts at sector 1+2+1+18+1=23
+	- luma 384*256 = 98304 bytes (48 sectors)
+	  + chroma1 192*128 = 24576 bytes (12 sectors)
+	  + chroma2 192*128 = 24576 bytes (12 sectors)
+	  = total 72 sectors
+
+	- NB. "Plain" data is interleaved - 2 luma rows 384 wide,
+	  then 1 of each of the chroma rows 192 wide !
+
+   base
+	- plain data starts at sector 1+2+1+18+1+72+1=96
+
+	- luma 768*512 = 393216 bytes (192 sectors)
+	  + chroma1 384*256 = 98304 bytes (48 sectors)
+	  + chroma2 384*256 = 98304 bytes (48 sectors)
+	  = total 288 sectors
+
+	- NB. "Plain" data is interleaved - 2 luma rows 768 wide,
+	  then 1 of each of the chroma rows 384 wide !
+
+   4base
+	- plain data for base is read
+	- luma data interpolated *2
+	- chroma data interpolated *4
+
+	- cd_offset is 1+2+1+18+1+72+1+288=384
+	- at cd_offset+4 (388) is huffman table
+	- at cd_offset+5 (389) is 4base luma plane
+
+	(the sector at cd_offset+3 seems to contain 256 words each of
+	which is an offset presumably to the sector containing certain
+	rows ? rows/4 given 1024 possible rows. The rest of this sector
+	is filled with zeroes)
+
+
+   16base
+	- plain data for base is read
+	- luma data interpolated *2
+	- chroma data interpolated *4
+
+	- cd_offset is 1+2+1+18+1+72+1+288=384
+	- at cd_offset+4 (388) is huffman table for 4 base
+	- at cd_offset+5 (389) is 4base luma plane
+	- luma plane interpolated *2
+
+	- cd_offset is set to current position (should be start of sector)
+	- at cd_offset+12 is huffman table for 16 base
+	- at cd_offset+14 is 16 base luma & 2 chroma planes which are read
+          (note that the luma plane comes first, with a sync pattern
+           announcing each row from 0 to 2047, then the two chroma planes
+           are interleaved by row, the row # being even from 0 to 2046, with
+           each row containing 1536 values, the chroma1 row coming first,
+           finally followed by a sync pattern with a row of 2048 announcing
+           the end (its plane seems to be set to 3, ie. chroma2)
+	- chroma planes interpolated *2
+
+	(the sector at cd_offset+10 & 11 seem to contain 1024 pairs of words
+        the first for luma and the second for chroma, each of
+	which is an offset presumably to the sector containing certain
+	rows ? rows/2 given 2048 possible rows)
+
+Not yet implemented:
+
+In order to do overskip for base and 4base, one has to reach the chroma
+data for 16 base:
+
+	- for 4base, after reading the 4base luma plane (and presumably
+	  skipping the chroma planes) one sets cd_offset to the start of
+	  the "current" sector
+
+	- for base, one has to skip the 4base data first:
+	- cd_offset is set to 384
+	- at (cd_offset+3 sectors)[510] is a 16 bit word high byte 1st
+	  containing an offset to the beginning of the 16base stuff
+	  though there is then a loop until >30 0xff's start a sector !
+
+	- being now positioned after the end of the 4base stuff,
+	- at (cd_offset+10 sectors)[2] is a 16 bit word high byte 1st
+	  containing an offset to the chroma planes.
+	- at cd_offset+12 is the set of huffman tables
+
+	- for base, the 16base chroma planes are then halved
+*/
+
+  PCDSetParamOptions(bname);
+  if (theSize == -1)
+  {
+    PCDDialog(1);                   /* Open PCD Dialog box */
+    SetCursors(-1);                 /* Somebody has already set it to wait :( */
+    leaveitup=1;
+    goforit=0;
+	size = 1;
+    /* block until the popup window gets closed */
+    while (leaveitup) {
+      int i;
+      XEvent event;
+      XNextEvent(theDisp, &event);
+      HandleEvent(&event, &i);
+    }
+    /* At this point goforit and size will have been set */
+    if (!goforit) {
+      /* nothing allocated so nothing needs freeing */
+      return 0;
+    }
+    WaitCursor();
+  }
+  else 
+  {
+    size = theSize;
+    goforit = 1;
+  }
+
+	if(lutCB.val)
+		rscale = gscale = bscale = 255.0/346.0;
+	else
+		rscale = gscale = bscale = 1.0;
+
+	switch (size) {
+	case 0:
+		pinfo->w = 192;
+		pinfo->h = 128;
+		offset=4*0x800;
+		mag=1;
+		huffplanes=0;
+		sprintf(pinfo->fullInfo, "PhotoCD, base/16 resolution");
+		break;
+
+	case 1:
+		pinfo->w = 384;
+		pinfo->h = 256;
+		offset=23*0x800;
+		mag=1;
+		huffplanes=0;
+		sprintf(pinfo->fullInfo, "PhotoCD, base/4 resolution");
+		break;
+
+	case 2:
+	default:
+		pinfo->w = 768;
+		pinfo->h = 512;
+		offset=96*0x800;
+		mag=1;
+		huffplanes=0;
+		sprintf(pinfo->fullInfo, "PhotoCD, base resolution");
+		break;
+
+	case 3:
+		pinfo->w = 1536;
+		pinfo->h = 1024;
+		offset=96*0x800;
+		mag=2;
+		huffplanes=1;
+		sprintf(pinfo->fullInfo, "PhotoCD, 4base resolution");
+		break;
+
+	case 4:
+		pinfo->w=3072;
+		pinfo->h=2048;
+		offset=96*0x800;
+		mag=4;
+		huffplanes=2;
+		sprintf(pinfo->fullInfo, "PhotoCD, 16base resolution");
+		break;
+	}
+
+	/*
+	 * rotate?
+	 */
+	w = pinfo->w;
+	h = pinfo->h;
+	switch(rotate) {
+	case	0:
+		break;
+
+	case	1:
+	case	3:
+		pinfo->w = h;
+		pinfo->h = w;
+		break;
+
+	default:
+		fprintf(stderr, "unknown image rotate %d; assuming none\n",
+			rotate);
+		rotate = 0;
+	}
+
+	/*
+	 * allocate 24-bit image
+	 */
+	pinfo->pic = (byte *)malloc(pinfo->w*pinfo->h*3);
+	if(!pinfo->pic)
+		FatalError("couldn't malloc '24 bit rgb plane'");
+
+	pinfo->type = PIC24;
+	sprintf(pinfo->shrtInfo, "%dx%d PhotoCD.", pinfo->w, pinfo->h);
+	pinfo->colType = F_FULLCOLOR;
+	pinfo->frmType = -1;
+
+	if(fseek(fp, offset, SEEK_SET) == -1)
+		return pcdError(bname,"Can't find start of data.");
+
+	pic24 = pinfo->pic;
+
+	luma=(byte *)calloc(w*h,1);
+	if(!luma)
+		FatalError("couldn't malloc 'luma plane'");
+
+	chroma1=(byte *)calloc(w*h/4,1);
+	if(!chroma1)
+		FatalError("couldn't malloc 'chroma1 plane'");
+
+	chroma2=(byte *)calloc(w*h/4,1);
+	if(!chroma2)
+		FatalError("couldn't malloc 'chroma2 plane'");
+
+	/* Read 2 luma rows length w, then one of each chroma rows w/2 */
+	/* If a mag factor is active, the small image is read into the */
+	/* top right hand corner of the larger allocated image */
+
+	trace(stderr, "base image: start @ 0x%08lx (sector %d.%d)\n",
+				ftell(fp), ftell(fp)/0x800, ftell(fp) % 0x800);
+	for(row=0,lptr=luma,c1ptr=chroma1,c2ptr=chroma2; row <h/mag;
+				row+=2,lptr+=w*2,c1ptr+=w/2,c2ptr+=w/2) {
+		if(fread(lptr, 1, w/mag, fp) != w/mag) {
+			pcdError(bname, "Luma plane too short.");
+			break;
+		}
+		if(fread(lptr+w, 1, w/mag, fp) != w/mag) {
+			pcdError(bname, "Luma plane too short.");
+			break;
+		}
+		if(fread(c1ptr, 1, w/2/mag, fp) != w/2/mag) {
+			pcdError(bname, "Chroma1 plane too short.");
+			break;
+		}
+		if(fread(c2ptr, 1, w/2/mag, fp) != w/2/mag) {
+			pcdError(bname, "Chroma2 plane too short.");
+			break;
+		}
+		if(row%wcurfactor == 0)
+			WaitCursor();
+	}
+	trace(stderr, "base image: done @ 0x%08lx (sector %d.%d)\n",
+				ftell(fp), ftell(fp)/0x800, ftell(fp) % 0x800);
+
+	if(huffplanes) {
+		if(fseek(fp, 388*0x800, SEEK_SET) == -1)
+			return pcdError(bname,
+					"Can't find start of huffman tables.");
+
+		magnify(2, h/mag, w/mag, h, w, luma);
+		magnify(2, h/2/mag, w/2/mag, h/2, w/2, chroma1);
+		magnify(2, h/2/mag, w/2/mag, h/2, w/2, chroma2);
+
+		/*
+		 * doesn't really touch the chroma planes which aren't
+		 * present in 4base
+		 */
+		gethuffdata(luma, chroma1, chroma2, w, h/mag*2);
+
+		/*
+		 * if only doing 4base should probably fetch 16bases
+		 * chroma planes here
+		 */
+		if(huffplanes == 2) {
+			/*
+			 * This depends on gethuffdata() having grabbed
+			 * things in 0x800 sectors AND still being
+			 * positioned in the "last" sector of the data
+			 * (cf. Hadmut's code which is positioned at start
+			 * of the next sector)
+			 */
+			long	offset = ftell(fp)/0x800+12;
+
+			if(fseek(fp, offset*0x800, SEEK_SET) == 0) {
+				magnify(2,h/2,w/2,h,w,luma);
+				magnify(2,h/4,w/4,h/2,w/2,chroma1);
+				magnify(2,h/4,w/4,h/2,w/2,chroma2);
+				gethuffdata(luma,chroma1,chroma2,w,h);
+			} else
+				fprintf(stderr, "can't seek to 2nd huffman tables\n");
+		}
+	}
+	fclose(fp);
+
+	/*
+	 * YCC -> R'G'B' and image rotate
+	 */
+	ptr=pic24;
+	lptr=luma; c1ptr=chroma1; c2ptr=chroma2;
+	for(row = 0; row < h; ++row) {
+		byte	*rowc1ptr = c1ptr,
+			*rowc2ptr = c2ptr;
+		int	k = 0;
+
+		switch(rotate) {
+		case	1:
+			ptr = &pic24[row*3 + (w - 1)*h*3];
+			  k = -3*(h + 1);
+			break;
+
+		case	3:
+			ptr = &pic24[(h - 1 - row)*3];
+			  k =  3*(h - 1);
+			break;
+
+		default:
+			ptr = &pic24[row*w*3];
+			  k = 0;
+			break;
+		}
+		for(col = 0; col < w; ++col) {
+			double	L	= 1.3584*(double) *lptr++,
+				C1	= 2.2179*(double) (*c1ptr - 156),
+				C2	= 1.8215*(double) (*c2ptr - 137);
+			int	r	= rscale*(L + C2),
+				g	= gscale*(L - 0.194*C1 - 0.509*C2),
+				b	= bscale*(L + C1);
+
+			if(lutCB.val) {
+				if(r < 0) r = 0; else if(r >= 255) r = 255;
+				if(g < 0) g = 0; else if(g >= 255) g = 255;
+				if(b < 0) b = 0; else if(b >= 255) b = 255;
+			} else {
+				if(r < 0) r = 0; else if(r >= 351) r = 350;
+				if(g < 0) g = 0; else if(g >= 351) g = 350;
+				if(b < 0) b = 0; else if(b >= 351) b = 350;
+				r = Y[r]; g = Y[g]; b = Y[b];
+			}
+			*ptr++ = r;
+			*ptr++ = g;
+			*ptr++ = b;
+			ptr   += k;
+			if(col & 1) {
+				++c1ptr;
+				++c2ptr;
+			}
+		}
+		if((row & 1) == 0) {
+			c1ptr = rowc1ptr;
+			c2ptr = rowc2ptr;
+		}
+		if(row%wcurfactor == 0)
+			WaitCursor();
+	}
+	free(luma); free(chroma1); free(chroma2);
+	return 1;
+}  
+
+/*
+ * derived from Hadmut Danisch's interpolate()
+ */
+static void
+magnify(int mag,	/* power of 2 by which to magnify in place */
+	int h, int w,	/* the "start" unmag'd dimensions of the array */
+	int mh, int mw,	/* the real (maximum) dimensions of the array */
+	byte *p)	/* pointer to the data */
+{
+  int x,y,yi;
+  byte *optr,*nptr,*uptr;  /* MUST be unsigned, else averaging fails */
+
+  while (mag > 1) {
+
+    /* create every 2nd new row from 0 */
+    /*  even pixels being equal to the old, odd ones averaged with successor */
+    /*  special case being the last column which is just set equal to the */
+    /*  second last) ... */
+
+    for(y=0;y<h;y++) {
+      yi=h-1-y;
+      optr=p+  yi*mw + (w-1);	          /* last pixel of an old row */
+      nptr=p+2*yi*mw + (2*w - 2);         /* last pixel of a new row */
+
+      nptr[0]=nptr[1]=optr[0];            /* special cases */
+
+      for(x=1;x<w;x++) {
+        optr--; nptr-=2;                  /* next lower pixel(s) */
+        nptr[0]=optr[0];                  /* even pixels duped */
+        nptr[1]=(((int)optr[0])+
+                 ((int)optr[1])+1)>>1;    /* odd averaged */
+      }
+    }
+
+    /* Fill in odd rows, as average of prior & succeeding rows, with */
+    /* even pixels average of one column, odd pixels average of two */
+
+    for(y=0;y<h-1;y++) {                  /* all but the last old row */
+      optr=p + 2*y*mw;                    /* start of the new "even" rows */
+      nptr=optr+mw;                       /* start of the next empty row */
+      uptr=nptr+mw;                       /* start of the next again (even) */
+
+      for(x=0;x<w-1;x++) {                /* for all cols except the last */
+        nptr[0]=(((int)optr[0])+
+                 ((int)uptr[0])+1)>>1;    /* even pixels */
+        nptr[1]=(((int)optr[0])+
+                 ((int)optr[2])+
+                 ((int)uptr[0])+
+                 ((int)uptr[2])+2)>>2;    /* odd pixels */
+        nptr+=2; optr+=2; uptr+=2;
+      }
+      *(nptr++)=(((int)*(optr++))+
+                 ((int)*(uptr++))+1)>>1;  /* 2nd last pixel */
+      *(nptr++)=(((int)*(optr++))+
+                 ((int)*(uptr++))+1)>>1;  /* last pixel */
+    }
+
+    xvbcopy(p + (2*h-2)*mw,                 /* 2nd last row */
+          p + (2*h-1)*mw,                 /* the last row */
+          2*w);                           /* length of a new row */
+
+    h*=2; w*=2;
+    mag>>=1;	/* Obviously mag must be a power of 2 ! */
+  }
+}
+
+/*******************************************/
+static int
+pcdError(char *fname, char *st)
+{
+  SetISTR(ISTR_WARNING,"%s:  %s", fname, st);
+  return 0;
+}
+
+
+/**** Stuff for PCDDialog box ****/
+
+#define TWIDE 380
+#define THIGH 160
+#define T_NBUTTS 2
+#define T_BOK    0
+#define T_BCANC  1
+#define BUTTH    24
+
+static void drawTD    PARM((int, int, int, int));
+static void clickTD   PARM((int, int));
+static void doCmd     PARM((int));
+static void PCDSetParams PARM((void));
+
+/* local variables */
+static BUTT  tbut[T_NBUTTS];
+static RBUTT *resnRB;
+
+
+
+/***************************************************/
+void CreatePCDW()
+{
+  int	     y;
+
+  pcdW = CreateWindow("xv pcd", "XVpcd", NULL, 
+		       TWIDE, THIGH, infofg, infobg, 0);
+  if (!pcdW) FatalError("can't create pcd window!");
+
+  XSelectInput(theDisp, pcdW, ExposureMask | ButtonPressMask | KeyPressMask);
+
+  BTCreate(&tbut[T_BOK], pcdW, TWIDE-140-1, THIGH-10-BUTTH-1, 60, BUTTH, 
+	   "Ok", infofg, infobg, hicol, locol);
+
+  BTCreate(&tbut[T_BCANC], pcdW, TWIDE-70-1, THIGH-10-BUTTH-1, 60, BUTTH, 
+	   "Cancel", infofg, infobg, hicol, locol);
+
+  y = 55;
+  resnRB = RBCreate(NULL, pcdW, 36, y,   "192*128   Base/16",
+           infofg, infobg,hicol,locol);
+  RBCreate(resnRB, pcdW, 36, y+18,       "384*256   Base/4",
+           infofg, infobg,hicol,locol);
+  RBCreate(resnRB, pcdW, 36, y+36,       "768*512   Base",
+           infofg, infobg, hicol, locol);
+  RBCreate(resnRB, pcdW, TWIDE/2, y,     "1536*1024 4Base",
+           infofg, infobg, hicol, locol);
+  RBCreate(resnRB, pcdW, TWIDE/2, y+18,  "3072*2048 16Base",
+           infofg, infobg, hicol, locol);
+
+  CBCreate(&lutCB, pcdW, TWIDE/2, y+36,  "Linear LUT",
+           infofg, infobg, hicol, locol);
+
+  RBSelect(resnRB, 2);
+
+  XMapSubwindows(theDisp, pcdW);
+}
+  
+
+/***************************************************/
+void PCDDialog(vis)
+int vis;
+{
+  if (vis) {
+    CenterMapWindow(pcdW, tbut[T_BOK].x + tbut[T_BOK].w/2,
+		    tbut[T_BOK].y + tbut[T_BOK].h/2, TWIDE, THIGH);
+  }
+  else     XUnmapWindow(theDisp, pcdW);
+  pcdUp = vis;
+}
+
+
+/***************************************************/
+int PCDCheckEvent(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 (!pcdUp) 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;
+
+    if (e->window == pcdW)       drawTD(x, y, w, h);
+    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 == pcdW)     clickTD(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;  XComposeStatus status;  
+    int stlen;
+	
+    stlen = XLookupString(e,buf,128,&ks,&status);
+    buf[stlen] = '\0';
+
+    RemapKeyCheck(ks, buf, &stlen);
+
+    if (e->window == pcdW) {
+      if (stlen) {
+	if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
+	  FakeButtonPress(&tbut[T_BOK]);
+	}
+	else if (buf[0] == '\033') {            /* ESC */
+	  FakeButtonPress(&tbut[T_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
+PCDSetParamOptions(char *fname)
+{
+  int cur;
+  cur = RBWhich(resnRB);
+
+  RBSetActive(resnRB,0,1);
+  RBSetActive(resnRB,1,1);
+  RBSetActive(resnRB,2,1);
+  RBSetActive(resnRB,3,1);
+  RBSetActive(resnRB,4,1);
+  CBSetActive(&lutCB,1);
+}
+
+
+/***************************************************/
+static void
+drawTD(int x, int y, int w, int h)
+{
+  char *title  = "Load PhotoCD file...";
+  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<T_NBUTTS; i++) BTRedraw(&tbut[i]);
+
+  ULineString(pcdW, resnRB->x-16, resnRB->y-10-DESCENT, "Resolution");
+  RBRedraw(resnRB, -1);
+  CBRedraw(&lutCB);
+
+  XDrawString(theDisp, pcdW, theGC, 20, 19, title, strlen(title));
+
+  XSetClipMask(theDisp, theGC, None);
+}
+
+
+/***************************************************/
+static void clickTD(x,y)
+int x,y;
+{
+  int i;
+  BUTT *bp;
+
+  /* check BUTTs */
+
+  /* check the RBUTTS first, since they don't DO anything */
+  if ( (i=RBClick(resnRB, x,y)) >= 0) { 
+    (void) RBTrack(resnRB, i);
+    return;
+  }
+
+  if(CBClick(&lutCB, x, y)) {
+    (void) CBTrack(&lutCB);
+    return;
+  }
+
+  for (i=0; i<T_NBUTTS; i++) {
+    bp = &tbut[i];
+    if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
+  }
+
+  if (i<T_NBUTTS) {  /* found one */
+    if (BTTrack(bp)) doCmd(i);
+  }
+}
+
+
+
+/***************************************************/
+static void doCmd(cmd)
+int cmd;
+{
+  leaveitup=0;
+  goforit=0;
+  switch (cmd) {
+  case T_BOK:  	PCDSetParams();
+                goforit=1;
+  case T_BCANC:	PCDDialog(0);
+                break;
+
+  default:	break;
+  }
+}
+
+
+/*******************************************/
+static void PCDSetParams()
+{
+  switch (RBWhich(resnRB)) {
+  case 0: size = 0;      break;
+  case 1: size = 1;      break;
+  case 2: size = 2;      break;
+  case 3: size = 3;      break;
+  case 4: size = 4;      break;
+  case 5: size = 0;      break;
+  default: size = 0;     break;
+  }
+}
+
+/*
+ * Read the Huffman tables which consist of an unsigned byte # of entries
+ * (less 1) followed by up to 256 entries, each of which is a series of 4
+ * unsigned bytes - length, highseq, lowseq, and key.
+ *
+ * Store the huffman table into tree type structure:
+ *
+ * 	int int[n of entries*2]
+ *
+ * Each entry consists of two words (the 1st for zero and the 2nd for one).
+ *
+ * If the word is negative, then subtract it from the current pointer to
+ * get the next entry (ie. it is the negative offset from the current
+ * position*2 in order to skip entries not words) with which to
+ * make a decision.
+ *
+ * If the word is not negative, then the low 8 bits contain the value (which
+ * is supposed to be a signed char) and the rest of the word is zero.
+ */
+static void
+dumphufftab(int n, const byte *h, int m, const int *t)
+{
+	int	j;
+
+	for(j = 0; j < n || j < m; ++j) {
+		if(j < m)
+			fprintf(stderr, "%04x %04x ::", 0xffff & t[2*j + 0],
+							 0xffff & t[2*j + 1]);
+		else
+			fprintf(stderr, "%s %s ::", "    ", "    ");
+		if(j < n) {
+			int	 k;
+			unsigned l = (h[4*j + 1] << 8) | h[4*j + 2];
+
+			fprintf(stderr, " %02x %2d ", h[4*j + 3], h[4*j + 0]);
+			for(k = 0; k <= h[4*j + 0]; ++k, l *= 2)
+				fprintf(stderr, "%c", '0'+((l & 0x8000) != 0));
+		}
+		fprintf(stderr, "\n");
+	}
+}
+
+static int *
+gethufftable(void)
+{
+	int	*hufftab, *h, i, j, N, num, huffptr, hufftop;
+	byte	*huf;
+
+	/*
+	 * absorb the entirety of the table in one chunk (for better
+	 * dumps in case of error)
+	 */
+	trace(stderr, "hufftab 0x%08x ", ftell(fp));
+	num = 1 + fgetc(fp);
+	/* how to use alloca() on MacOS X/darwin??? */
+	huf = (byte *)malloc(4*num*sizeof(byte));
+	if((i = fread(huf, 1, 4*num, fp)) != 4*num) {
+		fprintf(stderr, "unexpected EOF: got %d bytes, wanted %d\n",
+								i, 4*num);
+		return NULL;
+	}
+
+	/*
+	 * guess an initial size and prepare the initial entry
+	 */
+	trace(stderr, "length %u\n", num);
+	if((hufftab = (int *)malloc(2*num*sizeof(int))) == NULL) {
+		fprintf(stderr, "gethufftab(%u): no core\n", num);
+		return NULL;
+	}
+	N = 2*num;
+	hufftab[0] = hufftab[1] = 0;
+
+	/*
+	 * we check the table for reasonableness;  there is a lack of detailed
+	 * documentation on this format.  in particular, for the base16,
+	 * the position of the huffman tables is uncertain to within one
+	 * "sector", and we have to detect his before trying to read
+	 * bogusness.
+	 */
+	hufftop = 0;
+	for(i = 0; i < num; ++i) {
+		unsigned length   =  huf[4*i + 0],
+			 codeword = (huf[4*i + 1] << 8) | huf[4*i + 2];
+
+		/*
+		 * some sanity checks
+		 */
+		if(length >= 16) {
+			fprintf(stderr,
+				"gethufftable: improbable length @ %d/%d\n", i);
+			dumphufftab(num, huf, hufftop/2, hufftab);
+			free(hufftab);
+			return NULL;
+		}
+
+		/*
+		 * walk the whole set of codes
+		 */
+		huffptr = 0;
+		for(j = 0; j < 16; ++j, codeword *= 2) {
+			/*
+			 * choose the child node
+			 */
+			if(codeword & 0x8000)
+				++huffptr;
+
+			/*
+			 * store value at end-of-code
+			 */
+			if(j == length) {
+				/*
+				 * more sanity
+				 */
+				if((codeword *= 2) & 0xffff) {
+					fprintf(stderr,
+						"gethufftable: "
+						":probable invalid code @ %d\n",
+							i);
+					dumphufftab(num, huf,
+							hufftop/2, hufftab);
+					free(hufftab);
+					return NULL;
+				}
+				hufftab[huffptr] = 1 + (int) huf[4*i + 3];
+				break;
+			}
+
+			/*
+			 * otherwise, follow the tree to date
+			 */
+			if(hufftab[huffptr] < 0) {
+				huffptr -= hufftab[huffptr];
+				continue;
+			} else if(hufftab[huffptr] > 0) {
+				fprintf(stderr, "duplicate code %d %d/%d\n",
+					huffptr, i, num);
+				dumphufftab(num, huf, hufftop/2, hufftab);
+				free(hufftab);
+				return NULL;
+			}
+
+			/*
+			 * and if necessary, make the tree bigger
+			 */
+			if((hufftop += 2) >= N) {
+#if TRACE
+				dumphufftab(num, huf, hufftop/2, hufftab);
+#endif
+				h = (int *)realloc(hufftab,
+						(N *= 2)*sizeof(int));
+				if(h == NULL) {
+					fprintf(stderr,
+						"Table overflow %d/%d\n",
+								 i, num);
+					dumphufftab(num, huf,
+							hufftop/2, hufftab);
+					free(hufftab);
+					return NULL;
+				}
+				hufftab = h;
+			}
+
+			/*
+			 * then add new ptr
+			 */
+			hufftab[huffptr] = huffptr - hufftop;
+			huffptr = hufftop;
+			hufftab[huffptr + 0] =
+			hufftab[huffptr + 1] = 0;
+		}
+	}
+	return hufftab;
+}
+
+/* WORDTYPE & char buffer must be unsigned else */
+/* fills with sign bit not 0 on right shifts */
+typedef unsigned int WORDTYPE;
+typedef int SWORDTYPE;
+#define WORDSIZE sizeof(WORDTYPE)
+#define NBYTESINBUF 0x800
+
+static byte buffer[NBYTESINBUF];
+static int bitsleft=0;
+static int bytesleft=0;
+static byte *bufptr;
+static WORDTYPE word;
+
+static void
+dumpbuffer(void)
+{
+  int i,left;
+  byte *ptr=buffer;
+
+  fprintf(stderr,"dumpbuffer: bytesleft=%d bitsleft= %d word=0x%08lx\n",
+    bytesleft,bitsleft,(unsigned long)word);
+  for (left=NBYTESINBUF; left>0; left-=16) {
+    fprintf(stderr,"%05d  ",left);
+    for (i=0; i<8; i++) {
+      fprintf(stderr,"%02x",*ptr++);
+      fprintf(stderr,"%02x ",*ptr++);
+    }
+    fprintf(stderr,"\n");
+  }
+}
+
+static void
+loadbuffer(void)
+{
+  if ((bytesleft=fread(buffer,1,NBYTESINBUF,fp)) == 0) {
+    fprintf(stderr,"Truncation error\n");
+    exit(1);
+  }
+  bufptr=buffer;
+  /* dumpbuffer(); */
+}
+
+static void
+loadbyte(void)
+{
+  if (bytesleft <= 0) loadbuffer();
+  --bytesleft;
+  word|=(WORDTYPE)(*bufptr++)<<(sizeof(WORDTYPE)*8-8-bitsleft);
+  bitsleft+=8;
+}
+
+static int
+getbit(void)
+{
+  int bit;
+
+  while (bitsleft <= 0) loadbyte();
+  --bitsleft;
+  bit=(SWORDTYPE)(word)<0;  /* assumes word is signed */
+  /* bit=word>>(sizeof(WORDTYPE)*8-1); */
+  word<<=1;
+  return bit;
+}
+
+static WORDTYPE
+getnn(int nn)
+{
+  WORDTYPE value;
+
+  while (bitsleft <= nn) loadbyte();
+  bitsleft-=nn;
+  value=word>>(sizeof(WORDTYPE)*8-nn);
+  word<<=nn;
+  return value;
+}
+
+static WORDTYPE
+isnn(int nn)
+{
+  WORDTYPE value;
+
+  while (bitsleft <= nn) loadbyte();
+  value=word>>(sizeof(WORDTYPE)*8-nn);
+  return value;
+}
+
+static void
+skipnn(int nn)
+{
+  while (bitsleft <= nn) loadbyte();
+  bitsleft-=nn;
+  word<<=nn;
+}
+
+#define get1()    (getbit())
+#define get2()    (getnn(2))
+#define get8()    (getnn(8))
+#define get13()    (getnn(13))
+#define get16()    (getnn(16))
+#define get24()    (getnn(24))
+
+#define is24()    (isnn(24))
+
+#define skip1()    (skipnn(1))
+#define skip24()  (skipnn(24))
+
+static int
+gethuffdata(	byte *luma,
+		byte *chroma1,
+		byte *chroma2,
+		int realrowwidth,
+		int maxrownumber)
+{
+static	byte	clip[3*256];
+	int	*hufftable[3], *huffstart = NULL, *huffptr = NULL,
+		hufflen, row, col, plane, i, d, result = 1,
+		uflow = 0, oflow = 0;
+	byte	*pixelptr = NULL;
+
+	trace(stderr,"gethuffdata: start @ 0x%08lx (sector %d.%d)\n",
+			ftell(fp), ftell(fp)/0x800, ftell(fp) % 0x800);
+
+	/*
+	 * correction clipping
+	 */
+	if(clip[256+255] == 0) {
+		for(i = 0; i < 256; ++i)
+			clip[i +   0] = 0x00,
+			clip[i + 256] = (byte) i,
+			clip[i + 512] = 0xff;
+	}
+
+	/*
+	 * should really only look for luma plane for 4base, but the
+	 * there are zeroes in the rest of the sector that give both
+	 * chroma tables 0 length
+	 */
+	for(i = 0; i < 3; ++i)
+		hufftable[i] = NULL;
+	for(i = 0; i < 3; ++i) {
+		if((hufftable[i] = gethufftable()) == NULL) {
+			result = 0;
+			break;
+		}
+	}
+	if(result == 0)
+		goto oops;
+
+	/*
+	 * skip remainder of current sector
+	 */
+	i = (ftell(fp) | 0x7ff) + 1;
+	if(fseek(fp, i, SEEK_SET) < 0) {
+		fprintf(stderr, "gethuffdata: sector skip failed\n");
+		return 0;
+	}
+
+	/*
+	 * skip remainder of "sector"
+	 */
+	i = 0;
+	while (is24() != 0xfffffe) {
+		(void)get24();
+		if(++i == 1)
+			trace(stderr,"gethuffdata: skipping for sync ...");
+	}
+	if(i != 0)
+		trace(stderr, " %d times\n", i);
+
+	while(result) {
+		if(is24() == 0xfffffe) {
+			skip24();
+			plane = get2();
+			row = get13(); col = 0;
+			skip1();
+			if(row >= maxrownumber) {
+				trace(stderr,
+					"gethuffdata: stopping at row %d\n",
+								row);
+				break;
+			}
+			switch (plane) {
+			case	0:
+				huffstart = hufftable[0];
+				pixelptr  = luma + row*realrowwidth;
+				break;
+
+			case	2:
+				huffstart = hufftable[1];
+				pixelptr  = chroma1 + row/2*realrowwidth/2;
+				break;
+
+			case	3:
+				huffstart = hufftable[2];
+				pixelptr  = chroma2 + row/2*realrowwidth/2;
+				break;
+
+			default:
+				fprintf(stderr, "gethuffdata: bad plane %d\n",
+									plane);
+				result = 0;
+				break;
+			}
+			WaitCursor();
+			continue;
+		}
+
+		/*
+		 * locate correction in huffman tree
+		 */
+		for(huffptr = huffstart;;) {
+			huffptr += get1();
+			if(*huffptr < 0) {
+				huffptr -= *huffptr;
+			} else if(*huffptr == 0) {
+				fprintf(stderr,
+					"gethuffdata: invalid code: "
+						"image quality reduced\n");
+				result = 0;
+				break;
+			} else
+				break;
+		}
+		if(!result)
+			break;
+
+		/*
+		 * apply correction to the pixel
+		 *
+		 * eeeek!!  the corrections can sometimes over or underflow!
+		 * this strongly suggested that the 'magnify' method was in
+		 * some way wrong.  however, experiments showed that the
+		 * over/under flows even occured for the pixels that are
+		 * copied through magnify without change (ie, the even
+		 * row/even column case).  curiously, though, the odd
+		 * column and odd row cases were about 3x more likely to have
+		 * the over/underflow, and the odd row/odd column case was
+		 * about 5x higher, so maybe the use of a bi-linear
+		 * interpolation is not correct -- just *close*?
+		 *
+		 * the other clue in this area is that the overflows are
+		 * by far most frequenct along edges of very bright
+		 * areas -- rarely in the interior of such regions.
+		 */
+		i = (int) *pixelptr + (signed char) (*huffptr - 1);
+#if TRACE
+		if(i > 255)
+			++oflow;
+/*			trace(stderr,
+				"gethuffdata: oflow %d %d %d\n", row, col, i);*/
+		else if(i < 0)
+			++uflow;
+/*			trace(stderr,
+				"gethuffdata: uflow %d %d %d\n", row, col, i);*/
+		++col;
+#endif
+		*pixelptr++ = clip[i + 256];
+	}
+
+oops:
+	for(i = 0; i < 3; ++i)
+		free(hufftable[i]);
+	trace(stderr, "gethuffdata: uflow=%d oflow=%d\n", uflow, oflow);
+	trace(stderr, "gethuffdata: done @ 0x%08lx (sector %d.%d)\n",
+				ftell(fp), ftell(fp)/0x800, 0x800 - bytesleft);
+	return result;
+}
+
diff -Nur xv-3.10a.clean/xvpds.c xv-3.10a.darwin/xvpds.c
--- xv-3.10a.clean/xvpds.c	Tue Jan  3 13:25:52 1995
+++ xv-3.10a.darwin/xvpds.c	Sun Apr 27 21:36:23 2003
@@ -689,11 +689,11 @@
 
 #ifndef VMS
     sprintf(pdsuncompfname,"%s/xvhuffXXXXXX", tmpdir);
-    mktemp(pdsuncompfname);
+    mkstemp(pdsuncompfname);
     sprintf(scanbuff,"%s %s - 4 >%s",PDSUNCOMP,fname,pdsuncompfname);
 #else
     strcpy(pdsuncompfname,"sys$disk:[]xvhuffXXXXXX");
-    mktemp(pdsuncompfname);
+    mkstemp(pdsuncompfname);
     sprintf(scanbuff,"%s %s %s 4",PDSUNCOMP,fname,pdsuncompfname);
 #endif
 
diff -Nur xv-3.10a.clean/xvpng.c xv-3.10a.darwin/xvpng.c
--- xv-3.10a.clean/xvpng.c	Wed Dec 31 16:00:00 1969
+++ xv-3.10a.darwin/xvpng.c	Sun Apr 27 17:09:29 2003
@@ -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
diff -Nur xv-3.10a.clean/xvpopup.c xv-3.10a.darwin/xvpopup.c
--- xv-3.10a.clean/xvpopup.c	Thu Jan 19 10:09:31 1995
+++ xv-3.10a.darwin/xvpopup.c	Sun Apr 27 17:09:29 2003
@@ -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;
@@ -560,6 +560,7 @@
 	nams[*lenp] = (char *) malloc((size_t) 32);
 	if (!nams[*lenp]) { free(vals[*lenp]); continue; }
 	strncpy(nams[*lenp], vals[*lenp], (size_t) 31);
+	nams[*lenp][31] = '\0';
       }
       
       if (strlen(nams[*lenp]) > (size_t) 20) {   /* fix long names */
@@ -972,8 +973,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);
       }
     }
 
diff -Nur xv-3.10a.clean/xvps.c xv-3.10a.darwin/xvps.c
--- xv-3.10a.clean/xvps.c	Thu Dec 22 14:34:42 1994
+++ xv-3.10a.darwin/xvps.c	Sun Apr 27 21:36:52 2003
@@ -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);  
@@ -1552,8 +1552,8 @@
   sprintf(tmpname, "Sys$Scratch:xvpgXXXXXX");
 #endif
 
-  mktemp(tmpname);
-  if (tmpname[0] == '\0') {   /* mktemp() blew up */
+  mkstemp(tmpname);
+  if (tmpname[0] == '\0') {   /* mkstemp() blew up */
     sprintf(str,"LoadPS: Unable to create temporary filename???");
     ErrPopUp(str, "\nHow unlikely!");
     return 0;
@@ -1577,10 +1577,19 @@
 #  ifndef VMS
      sprintf(tmp1, "-I%s ", GS_LIB);
 #  else
-     sprintf(tmp1, "\"-I%s\"", GS_LIB);
+     sprintf(tmp1, "\"-I%s\" ", GS_LIB);
 #  endif
    strcat(tmp, tmp1);
 #endif
+
+
+   /* prevent some potential naughtiness... */
+#ifndef VMS
+   strcat(tmp, "-dSAFER ");
+#else
+   strcat(tmp, "\"-dSAFER\" ");
+#endif
+
 
   if (gsGeomStr) {
     sprintf(tmp1, "-g%s ", gsGeomStr);
diff -Nur xv-3.10a.clean/xvroot.c xv-3.10a.darwin/xvroot.c
--- xv-3.10a.clean/xvroot.c	Thu Dec 22 14:34:42 1994
+++ xv-3.10a.darwin/xvroot.c	Sun Apr 27 17:09:29 2003
@@ -44,6 +44,7 @@
   case RM_MIRROR:
   case RM_IMIRROR: rpixw = 2*eWIDE;  rpixh = 2*eHIGH;  break;
   case RM_CSOLID:
+  case RM_UPLEFT:
   case RM_CWARP:
   case RM_CBRICK:  rpixw = dispWIDE; rpixh = dispHIGH; break;
 
@@ -101,7 +102,7 @@
 
 
   else if (rmode == RM_CENTER || rmode == RM_CENTILE || rmode == RM_CSOLID ||
-	   rmode == RM_CWARP || rmode == RM_CBRICK) {
+	   rmode == RM_CWARP || rmode == RM_CBRICK || rmode == RM_UPLEFT) {
     /* do some stuff to set up the border around the picture */
 
     if (rmode != RM_CENTILE) {
@@ -138,6 +139,12 @@
 
     else if (rmode == RM_CSOLID) { }
 
+    else if (rmode == RM_UPLEFT) {
+
+      XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 0,0,
+		(u_int) eWIDE, (u_int) eHIGH);
+    }
+
     else if (rmode == RM_CWARP) {          /* warp effect */
       XSetForeground(theDisp, theGC, rootfg);
       for (i=0; i<=dispWIDE; i+=8) 
@@ -157,7 +164,7 @@
 
 
     /* draw the image centered on top of the background */
-    if (rmode != RM_CENTILE) 
+    if ((rmode != RM_CENTILE) && (rmode != RM_UPLEFT))
       XPutImage(theDisp, tmpPix, theGC, theImage, 0,0, 
 		((int) dispWIDE-eWIDE)/2, ((int) dispHIGH-eHIGH)/2, 
 		(u_int) eWIDE, (u_int) eHIGH);
diff -Nur xv-3.10a.clean/xvtext.c xv-3.10a.darwin/xvtext.c
--- xv-3.10a.clean/xvtext.c	Fri Jan 13 15:46:28 1995
+++ xv-3.10a.darwin/xvtext.c	Sun Apr 27 17:09:29 2003
@@ -293,6 +293,7 @@
   tv->textlen     = len;
   tv->freeonclose = freeonclose;
   strncpy(tv->title, title, (size_t) TITLELEN-1);
+  tv->title[TITLELEN-1] = '\0';
 
   computeText(tv);      /* compute # lines and linestarts array */
 
diff -Nur xv-3.10a.clean/xvtiff.c xv-3.10a.darwin/xvtiff.c
--- xv-3.10a.clean/xvtiff.c	Fri Jan 13 11:53:34 1995
+++ xv-3.10a.darwin/xvtiff.c	Sun Apr 27 17:09:29 2003
@@ -1,7 +1,7 @@
 /*
  * xvtiff.c - load routine for 'TIFF' format pictures
  *
- * LoadTIFF(fname, numcols)  -  load a TIFF file
+ * LoadTIFF(fname, numcols, quick)  -  load a TIFF file
  */
 
 #ifndef va_start
@@ -15,6 +15,35 @@
 #include "tiffio.h"     /* has to be after xv.h, as it needs varargs/stdarg */
 
 
+/* Portions fall under the following copyright:
+ *
+ * Copyright (c) 1992, 1993, 1994 Sam Leffler
+ * Copyright (c) 1992, 1993, 1994 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and 
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
+ * 
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
+ * OF THIS SOFTWARE.
+ */
+
+
+static int   copyTiff    PARM((TIFF *, char *));
+static int   cpStrips    PARM((TIFF *, TIFF *));
+static int   cpTiles     PARM((TIFF *, TIFF *));
 static byte *loadPalette PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
 static byte *loadColor   PARM((TIFF *, uint32, uint32, int, int, PICINFO *));
 static int   loadImage   PARM((TIFF *, uint32, uint32, byte *, int));
@@ -28,19 +57,23 @@
 static int   error_occurred;
 
 /*******************************************/
-int LoadTIFF(fname, pinfo)
-     char *fname;
+int LoadTIFF(fname, pinfo, quick)
+     char    *fname;
      PICINFO *pinfo;
+     int      quick;
 /*******************************************/
 {
   /* returns '1' on success, '0' on failure */
 
   TIFF  *tif;
   uint32 w, h;
+  float  xres, yres;
   short	 bps, spp, photo, orient;
   FILE  *fp;
   byte  *pic8;
   char  *desc, oldpath[MAXPATHLEN+1], tmppath[MAXPATHLEN+1], *sp;
+  char   tmp[256], tmpname[256];
+  int    i, nump;
 
   error_occurred = 0;
 
@@ -60,6 +93,8 @@
   filesize = ftell(fp);
   fclose(fp);
 
+
+
   rmap = pinfo->r;  gmap = pinfo->g;  bmap = pinfo->b;
 
   /* a kludge:  temporarily cd to the directory that the file is in (if
@@ -81,9 +116,57 @@
     }
   }
       
+
+  nump = 1;
+
+  if (!quick) {
+    /* see if there's more than 1 image in tiff file, to determine if we 
+       should do multi-page thing... */
+    
+    tif = TIFFOpen(filename,"r");
+    if (!tif) return 0;
+    while (TIFFReadDirectory(tif)) nump++;
+    TIFFClose(tif);
+    if (DEBUG) 
+      fprintf(stderr,"LoadTIFF: %d page%s found\n", nump, nump==1 ? "" : "s");
+    
     
+    /* if there are multiple images, copy them out to multiple tmp files,
+       and load the first one... */
 
-  tif=TIFFOpen(filename,"r");
+    xv_mktemp(tmpname, "xvpgXXXXXX");
+
+    if (tmpname[0] == '\0') {   /* mktemp() blew up */
+      sprintf(str,"LoadTIFF: Unable to create temporary filename???");
+      ErrPopUp(str, "\nHow unlikely!");
+      return 0;
+    }
+    
+    if (nump>1) {
+      TIFF *in, *out;
+      
+      in = TIFFOpen(filename, "r");
+      if (!in) return 0;
+      for (i=1; i<=nump; i++) {
+	sprintf(tmp, "%s%d", tmpname, i);
+	if (!copyTiff(in, tmp)) {
+	  SetISTR(ISTR_WARNING, "LoadTIFF:  Error writing page files!");
+	  break;
+	}
+	
+	if (!TIFFReadDirectory(in)) break;
+      }
+      if (DEBUG)
+	fprintf(stderr,"LoadTIFF: %d page%s written\n", 
+		i-1, (i-1)==1 ? "" : "s");
+      
+      sprintf(tmp, "%s%d", tmpname, 1);           /* open page #1 */
+      filename = tmp;
+    }
+  }  /* if (!quick) ... */
+
+
+  tif = TIFFOpen(filename,"r");
   if (!tif) return 0;
 
   /* flip orientation so that image comes in X order */
@@ -107,6 +190,11 @@
   TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bps);
   TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo);
   TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
+  if ((TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) == 1) &&
+      (TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) == 1)) {
+    normaspect = yres / xres;
+    if (DEBUG) fprintf(stderr,"TIFF aspect = %f\n", normaspect);
+  }
 
   if (spp == 1) {
       pic8 = loadPalette(tif, w, h, photo, bps, pinfo);
@@ -139,6 +227,8 @@
     if (pic8) free(pic8);
     if (pinfo->comment) free(pinfo->comment);
     pinfo->comment = (char *) NULL;
+    if (!quick && nump>1) KillPageFiles(tmpname, nump);
+    SetCursors(-1);
     return 0;
   }
 
@@ -148,17 +238,167 @@
   pinfo->normw = pinfo->w;   pinfo->normh = pinfo->h;
   pinfo->frmType = F_TIFF;
 
+  if (nump>1) strcpy(pinfo->pagebname, tmpname);
+  pinfo->numpages = nump;
 
   if (pinfo->pic) return 1;
 
+
   /* failed.  if we malloc'd a comment, free it */
   if (pinfo->comment) free(pinfo->comment);
   pinfo->comment = (char *) NULL;
 
+  if (!quick && nump>1) KillPageFiles(tmpname, nump);
+  SetCursors(-1);
+
   return 0;
 }  
 
 
+
+
+/*******************************************/
+
+#define CopyField(tag, v) \
+  if (TIFFGetField(in, tag, &v))            TIFFSetField(out, tag, v)
+#define CopyField2(tag, v1, v2) \
+  if (TIFFGetField(in, tag, &v1, &v2))      TIFFSetField(out, tag, v1, v2)
+#define CopyField3(tag, v1, v2, v3) \
+  if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
+
+
+/*******************************************/
+static int copyTiff(in, fname)
+     TIFF *in;
+     char *fname;
+{
+  /* copies tiff image to given filename.  Returns 0 on error */
+
+  TIFF   *out;
+  short   bitspersample, samplesperpixel, shortv, *shortav;
+  uint32  w, l;
+  float   floatv;
+  char   *stringv;
+  uint32  longv;
+  uint16 *red, *green, *blue, shortv2;
+  int     rv;
+  
+  out = TIFFOpen(fname, "w");
+  if (!out) return 0;
+  
+  CopyField (TIFFTAG_SUBFILETYPE,     longv);
+  CopyField (TIFFTAG_TILEWIDTH,       w);
+  CopyField (TIFFTAG_TILELENGTH,      l);
+  CopyField (TIFFTAG_IMAGEWIDTH,      w);
+  CopyField (TIFFTAG_IMAGELENGTH,     l);
+  CopyField (TIFFTAG_BITSPERSAMPLE,   bitspersample);
+  CopyField (TIFFTAG_COMPRESSION,     shortv);
+  CopyField (TIFFTAG_PREDICTOR,       shortv);
+  CopyField (TIFFTAG_PHOTOMETRIC,     shortv);
+  CopyField (TIFFTAG_THRESHHOLDING,   shortv);
+  CopyField (TIFFTAG_FILLORDER,       shortv);
+  CopyField (TIFFTAG_ORIENTATION,     shortv);
+  CopyField (TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+  CopyField (TIFFTAG_MINSAMPLEVALUE,  shortv);
+  CopyField (TIFFTAG_MAXSAMPLEVALUE,  shortv);
+  CopyField (TIFFTAG_XRESOLUTION,     floatv);
+  CopyField (TIFFTAG_YRESOLUTION,     floatv);
+  CopyField (TIFFTAG_GROUP3OPTIONS,   longv);
+  CopyField (TIFFTAG_GROUP4OPTIONS,   longv);
+  CopyField (TIFFTAG_RESOLUTIONUNIT,  shortv);
+  CopyField (TIFFTAG_PLANARCONFIG,    shortv);
+  CopyField (TIFFTAG_ROWSPERSTRIP,    longv);
+  CopyField (TIFFTAG_XPOSITION,       floatv);
+  CopyField (TIFFTAG_YPOSITION,       floatv);
+  CopyField (TIFFTAG_IMAGEDEPTH,      longv);
+  CopyField (TIFFTAG_TILEDEPTH,       longv);
+  CopyField2(TIFFTAG_EXTRASAMPLES,    shortv, shortav);
+  CopyField3(TIFFTAG_COLORMAP,        red, green, blue);
+  CopyField2(TIFFTAG_PAGENUMBER,      shortv, shortv2);
+  CopyField (TIFFTAG_ARTIST,          stringv);
+  CopyField (TIFFTAG_IMAGEDESCRIPTION,stringv);
+  CopyField (TIFFTAG_MAKE,            stringv);
+  CopyField (TIFFTAG_MODEL,           stringv);
+  CopyField (TIFFTAG_SOFTWARE,        stringv);
+  CopyField (TIFFTAG_DATETIME,        stringv);
+  CopyField (TIFFTAG_HOSTCOMPUTER,    stringv);
+  CopyField (TIFFTAG_PAGENAME,        stringv);
+  CopyField (TIFFTAG_DOCUMENTNAME,    stringv);
+
+  if (TIFFIsTiled(in)) rv = cpTiles (in, out);
+                  else rv = cpStrips(in, out);
+
+  TIFFClose(out);
+  return rv;
+}
+
+
+/*******************************************/
+static int cpStrips(in, out)
+     TIFF *in, *out;
+{
+  tsize_t bufsize;
+  byte *buf;
+
+  bufsize = TIFFStripSize(in);  
+  buf = (byte *) malloc((size_t) bufsize);
+  if (buf) {
+    tstrip_t s, ns = TIFFNumberOfStrips(in);
+    uint32 *bytecounts;
+    
+    TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts);
+    for (s = 0; s < ns; s++) {
+      if (bytecounts[s] > bufsize) {
+	buf = (unsigned char *) realloc(buf, (size_t) bytecounts[s]);
+	if (!buf) return (0);
+	bufsize = bytecounts[s];
+      }
+      if (TIFFReadRawStrip (in,  s, buf, (tsize_t) bytecounts[s]) < 0 ||
+	  TIFFWriteRawStrip(out, s, buf, (tsize_t) bytecounts[s]) < 0) {
+	free(buf);
+	return 0;
+      }
+    }
+    free(buf);
+    return 1;
+  }
+  return 0;
+}
+
+
+/*******************************/
+static int cpTiles(in, out)
+     TIFF *in, *out;
+{
+  tsize_t bufsize;
+  byte   *buf;
+
+  bufsize = TIFFTileSize(in);  
+  buf = (unsigned char *) malloc((size_t) bufsize);
+  if (buf) {
+    ttile_t t, nt = TIFFNumberOfTiles(in);
+    uint32 *bytecounts;
+    
+    TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts);
+    for (t = 0; t < nt; t++) {
+      if (bytecounts[t] > bufsize) {
+	buf = (unsigned char *)realloc(buf, (size_t) bytecounts[t]);
+	if (!buf) return (0);
+	bufsize = bytecounts[t];
+      }
+      if (TIFFReadRawTile (in,  t, buf, (tsize_t) bytecounts[t]) < 0 ||
+	  TIFFWriteRawTile(out, t, buf, (tsize_t) bytecounts[t]) < 0) {
+	free(buf);
+	return 0;
+      }
+    }
+    free(buf);
+    return 1;
+  }
+  return 0;
+}
+
+
 /*******************************************/
 static byte *loadPalette(tif, w, h, photo, bps, pinfo)
      TIFF *tif;
@@ -186,7 +426,7 @@
     break;
   }
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
 
   pic8 = (byte *) malloc((size_t) w*h);
   if (!pic8) FatalError("loadPalette() - couldn't malloc 'pic8'");
@@ -214,7 +454,7 @@
 	   "???"),
 	  filesize);
 
-  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",w,h);
+  sprintf(pinfo->shrtInfo, "%ux%u TIFF.",(u_int) w, (u_int) h);
 
   /* allocate 24-bit image */
   pic24 = (byte *) malloc((size_t) w*h*3);
@@ -301,6 +541,10 @@
 static	byte **BWmap;
 static	byte **PALmap;
 
+/* XXXX Work around some collisions with the new library. */
+#define tileContigRoutine _tileContigRoutine
+#define tileSeparateRoutine _tileSeparateRoutine
+
 typedef void (*tileContigRoutine)   PARM((byte*, u_char*, RGBvalue*, 
 					  uint32, uint32, int, int));
 
@@ -340,7 +584,7 @@
 					     uint32, uint32, int, int));
 static void   put4bitbwtile            PARM((byte *, u_char *, RGBvalue *,
 					     uint32, uint32, int, int));
-static void   put16bitbwtile           PARM((byte *, u_char *, RGBvalue *,
+static void   put16bitbwtile           PARM((byte *, u_short *, RGBvalue *,
 					     uint32, uint32, int, int));
 
 static void   putRGBcontig8bittile     PARM((byte *, u_char *, RGBvalue *,
@@ -1014,7 +1258,7 @@
 #define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
 
 #define	UNROLL8(w, op1, op2) {		\
-	uint32 x;		        \
+	uint32 x;	                \
 	for (x = w; x >= 8; x -= 8) {	\
 		op1;			\
 		REPEAT8(op2);		\
@@ -1026,7 +1270,7 @@
 }
 
 #define	UNROLL4(w, op1, op2) {		\
-	register uint32 x;		\
+	uint32 x;		        \
 	for (x = w; x >= 4; x -= 4) {	\
 		op1;			\
 		REPEAT4(op2);		\
@@ -1038,7 +1282,7 @@
 }
 
 #define	UNROLL2(w, op1, op2) {		\
-	register uint32 x;		\
+	uint32 x;		        \
 	for (x = w; x >= 2; x -= 2) {	\
 		op1;			\
 		REPEAT2(op2);		\
@@ -1218,7 +1462,7 @@
  */
 static void put16bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
      byte  *cp;
-     u_char *pp;
+     u_short *pp;
      RGBvalue *Map;
      uint32 w, h;
      int fromskew, toskew;
@@ -1227,8 +1471,7 @@
   
   while (h-- > 0) {
     for (x=w; x>0; x--) {
-      *cp++ = Map[(pp[0] << 8) + pp[1]];
-      pp += 2;
+      *cp++ = Map[*pp++];
     }
     cp += toskew;
     pp += fromskew;
@@ -1381,7 +1624,7 @@
   }
 }
 
-#define Code2V(c, RB, RW, CR)  ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))
+#define Code2V(c, RB, RW, CR)  (((((int)c)-(int)RB)*(float)CR)/(float)(RW-RB))
 
 #define	CLAMP(f,min,max) \
     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
@@ -1514,7 +1757,7 @@
   case PHOTOMETRIC_MINISWHITE:
   case PHOTOMETRIC_MINISBLACK:
     switch (bitspersample) {
-    case 16: put = put16bitbwtile; break;
+    case 16: put = (tileContigRoutine) put16bitbwtile; break;
     case 8:  put = putgreytile;    break;
     case 4:  put = put4bitbwtile;  break;
     case 2:  put = put2bitbwtile;  break;
diff -Nur xv-3.10a.clean/xvtiffwr.c xv-3.10a.darwin/xvtiffwr.c
--- xv-3.10a.clean/xvtiffwr.c	Tue Jan  3 13:28:13 1995
+++ xv-3.10a.darwin/xvtiffwr.c	Sun Apr 27 17:09:29 2003
@@ -84,8 +84,8 @@
   TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, h);
 
   TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, (int)2);
-  TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float)1200.0);
-  TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float)1200.0);
+  TIFFSetField(tif, TIFFTAG_XRESOLUTION, (float) 72.0);
+  TIFFSetField(tif, TIFFTAG_YRESOLUTION, (float) 72.0);
 
 
   /* write the image data */
diff -Nur xv-3.10a.clean/xvxwd.c xv-3.10a.darwin/xvxwd.c
--- xv-3.10a.clean/xvxwd.c	Thu Dec 22 14:34:40 1994
+++ xv-3.10a.darwin/xvxwd.c	Sun Apr 27 17:09:28 2003
@@ -396,11 +396,30 @@
     h11P->pixmap_width;
   
   bits_per_item  = h11P->bitmap_unit;
-  bits_used      = bits_per_item;
   bits_per_pixel = h11P->bits_per_pixel;
   byte_order     = h11P->byte_order;
   bit_order      = h11P->bitmap_bit_order;
   
+ 
+  /* add sanity-code for freako 'exceed' server, where bitmapunit = 8
+     and bitsperpix = 32 (and depth=24)... */
+ 
+  if (bits_per_item < bits_per_pixel) {
+    bits_per_item = bits_per_pixel;
+   
+    /* round bits_per_item up to next legal value, if necc */
+    if      (bits_per_item <  8) bits_per_item = 8;
+    else if (bits_per_item < 16) bits_per_item = 16;
+    else                         bits_per_item = 32;
+  }
+ 
+ 
+  /* which raises the question:  how (can?) you ever have a 24 bits per pix,
+     (ie, 3 bytes, no alpha/padding) */
+ 
+ 
+  bits_used      = bits_per_item;
+
   if (bits_per_pixel == sizeof(pixel_mask) * 8)  pixel_mask = (CARD32) -1;
   else pixel_mask = (1 << bits_per_pixel) - 1;
   
