diff options
Diffstat (limited to 'source/xap/xv/xv-3.10a-jumbo-enh-patch-20050501.txt')
-rw-r--r-- | source/xap/xv/xv-3.10a-jumbo-enh-patch-20050501.txt | 28167 |
1 files changed, 0 insertions, 28167 deletions
diff --git a/source/xap/xv/xv-3.10a-jumbo-enh-patch-20050501.txt b/source/xap/xv/xv-3.10a-jumbo-enh-patch-20050501.txt deleted file mode 100644 index d78b601a..00000000 --- a/source/xap/xv/xv-3.10a-jumbo-enh-patch-20050501.txt +++ /dev/null @@ -1,28167 +0,0 @@ -diff : xv-3.10a-jumbo-enh-patch-20050501.txt - -This is a unified diff. It should be applied (using Larry Wall's "patch" -program) to the XV 3.10a sources AFTER the jumbo-fixes patch has already -been applied. - -diffs below: - Imakefile - Makefile - Makefile.std - README.jumbo - README.pcd - bggen.c - bits/br_bzip2 - bits/br_mag - bits/br_maki - bits/br_mgcsfx - bits/br_pcd - bits/br_pi - bits/br_pic - bits/br_pic2 - bits/br_png - bits/br_zx - config.h - tiff/Makefile - vdcomp.c - xcmap.c - xv.c - xv.h - xv_mgcsfx.sample - xvbmp.c - xvbrowse.c - xvctrl.c - xvdial.c - xvdir.c - xvevent.c - xvfits.c - xvgam.c - xvgif.c - xvgrab.c - xvhips.c - xvhips.h - xvimage.c - xvinfo.c - xvjpeg.c - xvmag.c - xvmaki.c - xvmgcsfx.c - xvmisc.c - xvml.c - xvml.h - xvpbm.c - xvpcd.c - xvpds.c - xvpi.c - xvpic.c - xvpic2.c - xvpng.c - xvpopup.c - xvps.c - xvrle.c - xvroot.c - xvsmooth.c - xvtext.c - xvtiff.c - xvtiffwr.c - xvvd.c - xvwbmp.c - xvxpm.c - xvzx.c - - -diff -ruN xv-3.10a-bugfixes/Imakefile xv-3.10a-enhancements/Imakefile ---- xv-3.10a-bugfixes/Imakefile 1995-01-13 12:24:01.000000000 -0800 -+++ xv-3.10a-enhancements/Imakefile 2005-04-17 14:04:22.000000000 -0700 -@@ -104,6 +104,11 @@ - SGI = -Dsgi - #endif - -+/* install directory of xv_mgcsfx.sample. */ -+MGCSFXDIR = $(LIBDIR) -+/* Directory of default configuration file. */ -+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\" -+ - - - -@@ -137,6 +142,8 @@ - #if defined(SCOArchitecture) - SCO= -Dsco -DPOSIX -DNO_RANDOM - SYS_LIBRARIES= -lm -lc -lx -+#elif defined(HPArchitecture) -+SYS_LIBRARIES= -lm -lV3 - #else - SYS_LIBRARIES= -lm - #endif -@@ -147,7 +154,7 @@ - - DEFINES= $(SCO) $(UNIX) $(NODIRENT) $(VPRINTF) $(TIMERS) \ - $(HPUX7) $(JPEG) $(TIFF) $(PDS) $(DXWM) $(RAND) \ -- $(BACKING_STORE) $(BSDTYPES) $(SGI) -+ $(BACKING_STORE) $(BSDTYPES) $(SGI) $(MGCSFX) - - INCLUDES = $(JPEGINCLUDE) $(TIFFINCLUDE) - -@@ -157,7 +164,9 @@ - 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 xvpng.c xvzx.c xvwbmp.c xvpcd.c \ -+ xvmag.c xvpic.c xvmaki.c xvpi.c xvpic2.c xvvd.c xvmgcsfx.c \ -+ xvml.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 +174,9 @@ - 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 xvzx.o xvwbmp.o xvpcd.o \ -+ xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \ -+ xvml.o - - SRCS2= bggen.c - OBJS2= bggen.o -@@ -266,6 +277,8 @@ - InstallManPageLong(docs/xvp2p,$(MANDIR),xvpictoppm) - InstallManPageLong(docs/vdcomp,$(MANDIR),vdcomp) - -+InstallNonExecFile(xv_mgcsfx.sample,$(MGCSFXDIR)) -+ - tar: - tar cf xv.tar Makefile* Imakefile *.c *.h bits docs \ - docs unsupt vms $(JPEGDIR) $(TIFFDIR) $(MISC) -diff -ruN xv-3.10a-bugfixes/Makefile xv-3.10a-enhancements/Makefile ---- xv-3.10a-bugfixes/Makefile 2005-04-06 08:17:13.000000000 -0700 -+++ xv-3.10a-enhancements/Makefile 2005-05-01 10:23:32.000000000 -0700 -@@ -41,10 +41,14 @@ - - - ### Installation locations --BINDIR = /usr/local/bin --MANDIR = /usr/local/man/man1 -+PREFIX = /usr/local -+BINDIR = $(PREFIX)/bin -+MANDIR = $(PREFIX)/man/man1 - MANSUF = 1 --LIBDIR = /usr/local/lib -+DOCDIR = $(PREFIX)/doc/xv-3.10a -+LIBDIR = $(PREFIX)/lib/xv -+SYSCONFDIR = $(PREFIX)/etc -+DESTDIR = - - - buildit: all -@@ -59,13 +63,59 @@ - ### 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 -+#JPEGDIR = jpeg -+JPEGDIR = /usr -+#JPEGDIR = /usr/local -+#JPEGDIR = ../../libjpeg -+### -+JPEGINC = -I$(JPEGDIR)/include -+#JPEGINC = -I$(JPEGDIR) -+### -+JPEGLIB = -L$(JPEGDIR)/lib -ljpeg -+#JPEGLIB = -L$(JPEGDIR) -ljpeg -+#JPEGLIB = $(JPEGDIR)/libjpeg.a -+### -+### this is intended to build the ancient version (5a) that's included in the -+### "jpeg" subdir of XV, not an arbitrary copy of libjpeg: -+### -+#$(JPEGDIR)/jconfig.h: -+# cd $(JPEGDIR) ; ./configure CC='$(CC)' -+#$(JPEGLIB): $(JPEGDIR)/jconfig.h -+# cd $(JPEGDIR) ; make -+ -+ -+### -+### if, for whatever reason, you're unable to get the PNG library to compile -+### on your machine, *COMMENT OUT* the following lines -+### -+PNG = -DDOPNG -+PNGDIR = /usr -+#PNGDIR = /usr/local -+#PNGDIR = ../../libpng -+### -+PNGINC = -I$(PNGDIR)/include -+#PNGINC = -I$(PNGDIR) -+### -+PNGLIB = -L$(PNGDIR)/lib -lpng -+#PNGLIB = -L$(PNGDIR) -lpng -+#PNGLIB = $(PNGDIR)/libpng.a -+ -+ -+### -+### if, for whatever reason, you're unable to get both the PNG library and -+### (newer versions of) the TIFF library to compile on your machine, *COMMENT -+### OUT* the following lines -+### -+ZLIBDIR = /usr -+#ZLIBDIR = /usr/local -+#ZLIBDIR = ../../zlib -+### -+ZLIBINC = -I$(ZLIBDIR)/include -+#ZLIBINC = -I$(ZLIBDIR) -+### -+ZLIBLIB = -L$(ZLIBDIR)/lib -lz -+#ZLIBLIB = -L$(ZLIBDIR) -lz -+#ZLIBLIB = $(ZLIBDIR)/libz.a - - - ### -@@ -80,17 +130,32 @@ - ### - #TIFF = -DDOTIFF - TIFF = -DDOTIFF -DUSE_TILED_TIFF_BOTLEFT_FIX --TIFFDIR = tiff --TIFFINC = -I$(TIFFDIR) --TIFFLIB = $(TIFFDIR)/libtiff.a --$(TIFFLIB): -- ( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' ) -+#TIFFDIR = tiff -+TIFFDIR = /usr -+#TIFFDIR = /usr/local -+#TIFFDIR = ../../libtiff -+### -+TIFFINC = -I$(TIFFDIR)/include -+#TIFFINC = -I$(TIFFDIR) -+### -+### libtiff 3.5 and up may be compiled with zlib and libjpeg, but dependency -+### is properly handled in LIBS line ~143 lines below -+### -+TIFFLIB = -L$(TIFFDIR)/lib -ltiff -+#TIFFLIB = -L$(TIFFDIR) -ltiff -+#TIFFLIB = $(TIFFDIR)/libtiff.a -+### -+### this is intended to build the ancient version (3.3.016 beta) that's included -+### in the "tiff" subdir of XV, not an arbitrary copy of libtiff: -+### -+#$(TIFFLIB): -+# ( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' ) - - - ### - ### if, for whatever reason, you're unable to get the PDS/VICAR support - ### to compile (xvpds.c, and vdcomp.c), *COMMENT OUT* the following line, --### and also remove 'vdcomp' from the 'all:' dependancy -+### and also remove 'vdcomp' from the 'all:' dependency - ### - PDS = -DDOPDS - -@@ -98,8 +163,10 @@ - #----------System V---------- - - # if you are running on a SysV-based machine, such as HP, Silicon Graphics, --# Solaris, etc., uncomment the following line to get mostly there. --#UNIX = -DSVR4 -+# Solaris, etc.; uncomment one of the following lines to get you *most* of -+# the way there. SYSV means System V R3. -+# UNIX = -DSVR4 -+# UNIX = -DSYSV - - - #----------Machine-Specific Configurations---------- -@@ -121,12 +188,15 @@ - # To use old HP compilers (HPUX 7.0 or so), you may need - #MCHN= -Dhpux -D_HPUX_SOURCE +Ns4000 - # --# also, if you're using HP's compiler, add '-Aa' to whichever of those -+# Also, if you're using HP's compiler, add '-Aa' to whichever of those - # two lines you're using, to turn on ANSI C mode. Or so I'm told. - # --# note: You may need to add '-I/usr/include/X11R5' (or R6, or whatever) -+# Note: You may need to add '-I/usr/include/X11R5' (or R6, or whatever) - # to whichever of those lines you used, as HP tends to store their X11 - # include files in a non-standard place... -+# -+# And you probably have to add '-lV3' to the end of the LIBS def when -+# using XV's AUTO_EXPAND option. - - - ### for LINUX, uncomment the following line -@@ -205,6 +275,16 @@ - #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS - - -+# if your X Window System compiled with -DX_LOCALE, -+# uncomment the following line: -+# TVL10N = -DX_LOCALE -+ -+# Install directory of xv_mgcsfx.sample. -+MGCSFXDIR = $(LIBDIR) -+# Directory of default configuration file. -+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\" -+ -+ - - - ################ END OF CONFIGURATION OPTIONS ################# -@@ -212,13 +292,14 @@ - - - --CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \ -- $(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \ -- $(DXWM) $(MCHN) -+CFLAGS = $(CCOPTS) $(PNG) $(PNGINC) $(ZLIBINC) $(JPEG) $(JPEGINC) \ -+ $(TIFF) $(TIFFINC) $(PDS) $(NODIRENT) $(VPRINTF) $(TIMERS) \ -+ $(UNIX) $(BSDTYPES) $(RAND) $(DXWM) $(MCHN) $(TVL10N) $(MGCSFX) \ -+ -DSYSCONFDIR=\"$(SYSCONFDIR)\" -DXVEXECPATH=\"$(LIBDIR)\" - - ### remove -lm for BeOS: --LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm --#LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -+LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) -L/usr/X11R6/lib -lX11 -lm -+#LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) -lX11 - - 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 \ -@@ -226,7 +307,9 @@ - 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 xvzx.o xvwbmp.o xvpcd.o xvhips.o \ -+ xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \ -+ xvml.o - - MISC = README INSTALL CHANGELOG IDEAS - -@@ -236,10 +319,12 @@ - - - --all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm -+#all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm -+all: xv bggen vdcomp xcmap xvpictoppm - - --xv: $(OBJS) $(JPEGLIB) $(TIFFLIB) -+#xv: $(OBJS) $(JPEGLIB) $(TIFFLIB) -+xv: $(OBJS) - $(CC) -o xv $(CFLAGS) $(OBJS) $(LIBS) - - bggen: bggen.c -@@ -268,13 +353,14 @@ - - - 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) -+ cp xv bggen vdcomp xcmap xvpictoppm $(DESTDIR)$(BINDIR) -+ cp docs/xv.man $(DESTDIR)$(MANDIR)/xv.$(MANSUF) -+ cp docs/bggen.man $(DESTDIR)$(MANDIR)/bggen.$(MANSUF) -+ cp docs/xcmap.man $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF) -+ cp docs/xvp2p.man $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF) -+ cp docs/vdcomp.man $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF) -+ cp docs/xvdocs.ps* $(DESTDIR)$(LIBDIR) # or $(DESTDIR)$(DOCDIR) -+ #cp xv_mgcsfx.sample $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx - - tar: - # tar only local jpeg and tiff dirs, not user's or system's copies: -@@ -299,7 +385,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 bits/br_zx bits/br_pcd bits/br_bzip2 - - 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 -ruN xv-3.10a-bugfixes/Makefile.std xv-3.10a-enhancements/Makefile.std ---- xv-3.10a-bugfixes/Makefile.std 2005-04-06 08:17:13.000000000 -0700 -+++ xv-3.10a-enhancements/Makefile.std 2005-05-01 10:23:32.000000000 -0700 -@@ -41,10 +41,14 @@ - - - ### Installation locations --BINDIR = /usr/local/bin --MANDIR = /usr/local/man/man1 -+PREFIX = /usr/local -+BINDIR = $(PREFIX)/bin -+MANDIR = $(PREFIX)/man/man1 - MANSUF = 1 --LIBDIR = /usr/local/lib -+DOCDIR = $(PREFIX)/doc/xv-3.10a -+LIBDIR = $(PREFIX)/lib/xv -+SYSCONFDIR = $(PREFIX)/etc -+DESTDIR = - - - buildit: all -@@ -59,13 +63,59 @@ - ### 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 -+#JPEGDIR = jpeg -+JPEGDIR = /usr -+#JPEGDIR = /usr/local -+#JPEGDIR = ../../libjpeg -+### -+JPEGINC = -I$(JPEGDIR)/include -+#JPEGINC = -I$(JPEGDIR) -+### -+JPEGLIB = -L$(JPEGDIR)/lib -ljpeg -+#JPEGLIB = -L$(JPEGDIR) -ljpeg -+#JPEGLIB = $(JPEGDIR)/libjpeg.a -+### -+### this is intended to build the ancient version (5a) that's included in the -+### "jpeg" subdir of XV, not an arbitrary copy of libjpeg: -+### -+#$(JPEGDIR)/jconfig.h: -+# cd $(JPEGDIR) ; ./configure CC='$(CC)' -+#$(JPEGLIB): $(JPEGDIR)/jconfig.h -+# cd $(JPEGDIR) ; make -+ -+ -+### -+### if, for whatever reason, you're unable to get the PNG library to compile -+### on your machine, *COMMENT OUT* the following lines -+### -+PNG = -DDOPNG -+PNGDIR = /usr -+#PNGDIR = /usr/local -+#PNGDIR = ../../libpng -+### -+PNGINC = -I$(PNGDIR)/include -+#PNGINC = -I$(PNGDIR) -+### -+PNGLIB = -L$(PNGDIR)/lib -lpng -+#PNGLIB = -L$(PNGDIR) -lpng -+#PNGLIB = $(PNGDIR)/libpng.a -+ -+ -+### -+### if, for whatever reason, you're unable to get both the PNG library and -+### (newer versions of) the TIFF library to compile on your machine, *COMMENT -+### OUT* the following lines -+### -+ZLIBDIR = /usr -+#ZLIBDIR = /usr/local -+#ZLIBDIR = ../../zlib -+### -+ZLIBINC = -I$(ZLIBDIR)/include -+#ZLIBINC = -I$(ZLIBDIR) -+### -+ZLIBLIB = -L$(ZLIBDIR)/lib -lz -+#ZLIBLIB = -L$(ZLIBDIR) -lz -+#ZLIBLIB = $(ZLIBDIR)/libz.a - - - ### -@@ -80,17 +130,32 @@ - ### - #TIFF = -DDOTIFF - TIFF = -DDOTIFF -DUSE_TILED_TIFF_BOTLEFT_FIX --TIFFDIR = tiff --TIFFINC = -I$(TIFFDIR) --TIFFLIB = $(TIFFDIR)/libtiff.a --$(TIFFLIB): -- ( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' ) -+#TIFFDIR = tiff -+TIFFDIR = /usr -+#TIFFDIR = /usr/local -+#TIFFDIR = ../../libtiff -+### -+TIFFINC = -I$(TIFFDIR)/include -+#TIFFINC = -I$(TIFFDIR) -+### -+### libtiff 3.5 and up may be compiled with zlib and libjpeg, but dependency -+### is properly handled in LIBS line ~143 lines below -+### -+TIFFLIB = -L$(TIFFDIR)/lib -ltiff -+#TIFFLIB = -L$(TIFFDIR) -ltiff -+#TIFFLIB = $(TIFFDIR)/libtiff.a -+### -+### this is intended to build the ancient version (3.3.016 beta) that's included -+### in the "tiff" subdir of XV, not an arbitrary copy of libtiff: -+### -+#$(TIFFLIB): -+# ( cd $(TIFFDIR) ; make CC='$(CC)' COPTS='$(CCOPTS) $(MCHN)' ) - - - ### - ### if, for whatever reason, you're unable to get the PDS/VICAR support - ### to compile (xvpds.c, and vdcomp.c), *COMMENT OUT* the following line, --### and also remove 'vdcomp' from the 'all:' dependancy -+### and also remove 'vdcomp' from the 'all:' dependency - ### - PDS = -DDOPDS - -@@ -98,8 +163,10 @@ - #----------System V---------- - - # if you are running on a SysV-based machine, such as HP, Silicon Graphics, --# Solaris, etc., uncomment the following line to get mostly there. --#UNIX = -DSVR4 -+# Solaris, etc.; uncomment one of the following lines to get you *most* of -+# the way there. SYSV means System V R3. -+# UNIX = -DSVR4 -+# UNIX = -DSYSV - - - #----------Machine-Specific Configurations---------- -@@ -121,12 +188,15 @@ - # To use old HP compilers (HPUX 7.0 or so), you may need - #MCHN= -Dhpux -D_HPUX_SOURCE +Ns4000 - # --# also, if you're using HP's compiler, add '-Aa' to whichever of those -+# Also, if you're using HP's compiler, add '-Aa' to whichever of those - # two lines you're using, to turn on ANSI C mode. Or so I'm told. - # --# note: You may need to add '-I/usr/include/X11R5' (or R6, or whatever) -+# Note: You may need to add '-I/usr/include/X11R5' (or R6, or whatever) - # to whichever of those lines you used, as HP tends to store their X11 - # include files in a non-standard place... -+# -+# And you probably have to add '-lV3' to the end of the LIBS def when -+# using XV's AUTO_EXPAND option. - - - ### for LINUX, uncomment the following line -@@ -205,6 +275,16 @@ - #VPRINTF = -DNEED_VPRINTF -DLONGINT -DNOSTDHDRS - - -+# if your X Window System compiled with -DX_LOCALE, -+# uncomment the following line: -+# TVL10N = -DX_LOCALE -+ -+# Install directory of xv_mgcsfx.sample. -+MGCSFXDIR = $(LIBDIR) -+# Directory of default configuration file. -+MGCSFX = -DMGCSFXDIR=\"$(MGCSFXDIR)\" -+ -+ - - - ################ END OF CONFIGURATION OPTIONS ################# -@@ -212,13 +292,14 @@ - - - --CFLAGS = $(CCOPTS) $(JPEG) $(JPEGINC) $(TIFF) $(TIFFINC) $(PDS) \ -- $(NODIRENT) $(VPRINTF) $(TIMERS) $(UNIX) $(BSDTYPES) $(RAND) \ -- $(DXWM) $(MCHN) -+CFLAGS = $(CCOPTS) $(PNG) $(PNGINC) $(ZLIBINC) $(JPEG) $(JPEGINC) \ -+ $(TIFF) $(TIFFINC) $(PDS) $(NODIRENT) $(VPRINTF) $(TIMERS) \ -+ $(UNIX) $(BSDTYPES) $(RAND) $(DXWM) $(MCHN) $(TVL10N) $(MGCSFX) \ -+ -DSYSCONFDIR=\"$(SYSCONFDIR)\" -DXVEXECPATH=\"$(LIBDIR)\" - - ### remove -lm for BeOS: --LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -lm --#LIBS = -lX11 $(JPEGLIB) $(TIFFLIB) -+LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) -L/usr/X11R6/lib -lX11 -lm -+#LIBS = $(TIFFLIB) $(JPEGLIB) $(PNGLIB) $(ZLIBLIB) -lX11 - - 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 \ -@@ -226,7 +307,9 @@ - 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 xvzx.o xvwbmp.o xvpcd.o xvhips.o \ -+ xvmag.o xvpic.o xvmaki.o xvpi.o xvpic2.o xvvd.o xvmgcsfx.o \ -+ xvml.o - - MISC = README INSTALL CHANGELOG IDEAS - -@@ -236,10 +319,12 @@ - - - --all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm -+#all: $(JPEGLIB) $(TIFFLIB) xv bggen vdcomp xcmap xvpictoppm -+all: xv bggen vdcomp xcmap xvpictoppm - - --xv: $(OBJS) $(JPEGLIB) $(TIFFLIB) -+#xv: $(OBJS) $(JPEGLIB) $(TIFFLIB) -+xv: $(OBJS) - $(CC) -o xv $(CFLAGS) $(OBJS) $(LIBS) - - bggen: bggen.c -@@ -268,13 +353,14 @@ - - - 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) -+ cp xv bggen vdcomp xcmap xvpictoppm $(DESTDIR)$(BINDIR) -+ cp docs/xv.man $(DESTDIR)$(MANDIR)/xv.$(MANSUF) -+ cp docs/bggen.man $(DESTDIR)$(MANDIR)/bggen.$(MANSUF) -+ cp docs/xcmap.man $(DESTDIR)$(MANDIR)/xcmap.$(MANSUF) -+ cp docs/xvp2p.man $(DESTDIR)$(MANDIR)/xvpictoppm.$(MANSUF) -+ cp docs/vdcomp.man $(DESTDIR)$(MANDIR)/vdcomp.$(MANSUF) -+ cp docs/xvdocs.ps* $(DESTDIR)$(LIBDIR) # or $(DESTDIR)$(DOCDIR) -+ #cp xv_mgcsfx.sample $(DESTDIR)$(SYSCONFDIR)/xv_mgcsfx - - tar: - # tar only local jpeg and tiff dirs, not user's or system's copies: -@@ -299,7 +385,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 bits/br_zx bits/br_pcd bits/br_bzip2 - - 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 -ruN xv-3.10a-bugfixes/README.jumbo xv-3.10a-enhancements/README.jumbo ---- xv-3.10a-bugfixes/README.jumbo 2005-04-10 19:55:23.000000000 -0700 -+++ xv-3.10a-enhancements/README.jumbo 2005-05-01 13:45:58.000000000 -0700 -@@ -14,10 +14,10 @@ - available from John's XV site (http://www.trilon.com/xv/downloads.html - and ftp://ftp.trilon.com/pub/xv/patches/), plus a number of my own fixes - and additions, plus quite a few from other people--though not all of the --ones I'd intended to (sorry, SJT, AT, and JPD!) due to lack of time after --dealing with the latest security issue (which I discovered, sigh). They're --still not fully complete, and it's possible they never will be, but I do --plan to continue working on them whenever the mood strikes--and I may even -+ones I'd intended to, due to lack of time after dealing with the latest -+set of security issues (one of which I discovered, sigh). They're still -+not fully complete, and it's possible they never will be, but I do plan -+to continue tinkering with them whenever the mood strikes--and I may even - release them publicly on rare occasions. (At the current rate, it looks - like once a year may be the best we can hope for...we'll see.) - -@@ -26,91 +26,86 @@ - - - Landon Curt "chongo" Noll (http://www.isthe.com/chongo/) - http://www.isthe.com/chongo/src/xv-patch/ -- - Mark Ashley <mark@ibiblio.org> -+ - Mark Ashley <mark ibiblio.org> - http://www.ibiblio.org/pub/packages/solaris/sparc/html/xv.3.10a.p19.html -- - Peter Jordan <pete@dc.seflin.org> -+ - Peter Jordan <pete dc.seflin.org> - http://www.ibiblio.org/pub/Linux/apps/graphics/viewers/X/xv-3.10a.patch.* - - Uwe F. Mayer (http://www.tux.org/~mayer/) - http://www.tux.org/~mayer/linux/book/node311.html -- - Kurt Wall <kwall@kurtwerks.com> -+ - Kurt Wall <kwall kurtwerks.com> - http://www.kurtwerks.com/software/xv.html - - Chisato Yamauchi (http://phe.phyas.aichi-edu.ac.jp/~cyamauch/index_en.html) - http://phe.phyas.aichi-edu.ac.jp/~cyamauch/xv.html -- - Daisuke Yabuki <dxy@optix.org> -+ - Daisuke Yabuki <dxy optix.org> - http://www.optix.org/~dxy/solaris/xv/ - - Pekoe (http://pekoe.lair.net/) - http://pekoe.lair.net/diary/xv.html - - FreeBSD FreshPorts - http://www.freshports.org/graphics/xv/ -- - <sudakyo@fat.coara.or.jp> -+ - Kyoichiro Suda <sudakyo fat.coara.or.jp> - http://www.coara.or.jp/~sudakyo/XV_jp.html - --I very much doubt that this is an exhaustive list. So far, most of the other --patch-sets appear not to be quite as extensive or as up-to-date as my own, --although the last three or four do include the [large] Japanese extension --patches that I omitted--not because they're unworthy, but simply because I --didn't find them until collisions between the two sets of patches had become --a large problem. (Maybe for the next release... I'd intended to try for --this release, but the security issues ended up taking almost all of my --available time. And, to be honest, from my perspective, inclusion of the --jp-extension patches is more for completeness' sake than personal interest, --so their priority is fairly low.) -+I very much doubt that this is an exhaustive list. So far, most of the -+other patch-sets appear not to be as extensive or as up-to-date as my own, -+particularly now that the (very large) "Japanese extension" patches are -+incorporated--big thanks to Werner Fink of SuSE for that! - - Below I summarize the component patches that are encompassed by my jumbo - bugfixes and jumbo enhancements patches. Unfortunately, some of my own - additions never saw the light of day as standalone patches, but considering - the number of overlaps (collisions) already implicit in this list, it would --have been difficult to accomplish even if I'd had the time. In any case, --they're present in these jumbo patches but not chongo's, so those who _really_ --care can "subtract" the two sets of patches to see what I did. -+have been difficult to accomplish even if I'd had the time. - - Here's a quick guide to the "third-party" credits in the lists below: - - AAC = Andrey A. Chernov [ache] - (http://cvsweb.freebsd.org/ports/graphics/xv/files/patch-ab) -- AD = Andreas Dilger (adilger@clusterfs.com) -- AL = Alexander Lehmann (lehmann@usa.net) -+ AD = Andreas Dilger (adilger clusterfs.com) -+ AL = Alexander Lehmann (lehmann usa.net) - AT = Anthony Thyssen (http://www.cit.gu.edu.au/~anthony/) - DAC = David A. Clunie (http://www.dclunie.com/xv-pcd.html) -- EK = Egmont Koblinger (egmont@users.sourceforge.net) -+ EK = Egmont Koblinger (egmont users.sourceforge.net) - GRR = Greg Roelofs (http://pobox.com/~newt/) - GV = Guido Vollbeding (http://sylvana.net/guido/) -+ IM = IKEMOTO Masahiro (ikeyan airlab.cs.ritsumei.ac.jp) - JCE = John C. Elliott (http://www.seasip.demon.co.uk/ZX/zxdload.html) - JHB = John H. Bradley, of course (http://www.trilon.com/xv/) - JPD = Jean-Pierre Demailly (http://www-fourier.ujf-grenoble.fr/~demailly/) - JR = John Rochester (http://www.freebsd.org/cgi/query-pr.cgi?pr=2920) - (also http://cvsweb.freebsd.org/ports/graphics/xv/files/patch-af, -ag) - JZ = Joe Zbiciak (http://spatula-city.org/~im14u2c/) -+ KS = Kyoichiro Suda (http://www.coara.or.jp/~sudakyo/XV_jp.html) - LCN = Landon Curt "chongo" Noll (http://www.isthe.com/chongo/) -+ LJ = Larry Jones (lawrence.jones ugs.com) - PBJ = Peter Jordan (http://www.ibiblio.org/pub/Linux/apps/graphics/viewers/X/) - PSV = Pawel S. Veselov (http://manticore.2y.net/wbmp.html) - SB = Sean Borman (http://www.nd.edu/~sborman/software/xvwheelmouse.html) -- SJT = TenThumbs (tenthumbs@cybernex.net) -+ SJT = TenThumbs (tenthumbs cybernex.net) - TA = Tim Adye (http://hepwww.rl.ac.uk/Adye/xv-psnewstyle.html) -+ TI = Tetsuya INOUE (tin329 chino.it.okayama-u.ac.jp) -+ TO = Tavis Ormandy (taviso gentoo.org) -+ WF = Werner Fink (http://www.suse.de/~werner/) - - Other credits are as listed on the XV Downloads page or in the respective - patches (e.g., the jp-extension patches or within the PNG patch). - - Finally, please note that these patches have not been blessed by John Bradley --in any way (although I copied him on the May 2004 announcement--no response). --Nor have I personally tested every change and feature! (See the BIG SCARY --WARNING below for further caveats.) In other words, they're both completely --unofficial and completely unguaranteed. But they seem to work for me. (And --when they don't, I fix 'em. Eventually, anyway... ;-) ) -- --One further "final" note: this may well be the last release to include --separate fix- and enhancements-patches. It is too much of a timesink to --maintain parallel trees--not to mention parallel makefiles (generic/public --vs. local/personal, old vs. new libjpeg/libtiff) and xv.h (unregistered/ --public vs. registered/personal), particularly when some fixes come about --while working on an enhancement. Henceforth--assuming, of course, that --there _is_ a "henceforth"--I expect to merge the patches into a single --jumbo patch. (Alternatively, I may simply freeze the current fix-patch --and continue to evolve only the enhancements patch; in particular, new --fixes would appear only in it. Either approach would be simple enough; --feedback as to which would be preferable is welcomed.) -+in any way (although I copied him on the May 2004 announcement--no response -+at that time). Nor have I personally tested every change and feature! (See -+the BIG SCARY WARNING below for further caveats.) In other words, they're -+both completely unofficial and completely unguaranteed. But they seem to -+work for me. (And when they don't, I fix 'em. Eventually, anyway... ;-) ) -+ -+One further "final" note: as of this release, I am no longer updating the -+fixes patch; new stuff (including fixes) now appears only in the enhancements -+one. It simply became too much of a timesink to maintain parallel trees--not -+to mention parallel makefiles (generic/public vs. local/personal, old vs. -+new libjpeg/libtiff) and xv.h (unregistered/public vs. registered/personal), -+particularly when some fixes came about while working on an enhancement and -+others were provided by third parties relative to the previous fix+enh state. -+Hence the mismatched "20050410" date on the fixes patch. - --GRR 20050410 -+GRR 20050501 - - - How to build -@@ -158,8 +153,8 @@ - Assuming you have the prerequisites out of the way and aren't scared - off by the Big Scary Warning, here's the build procedure: - -- bzip2 -dc xv-3.10a-jumbo-patches-20050410.tar.bz2 | tar xvf - -- (or tar xvzf xv-3.10a-jumbo-patches-20050410.tar.gz) -+ bzip2 -dc xv-3.10a-jumbo-patches-20050501.tar.bz2 | tar xvf - -+ (or tar xvzf xv-3.10a-jumbo-patches-20050501.tar.gz) - - tar xvzf xv-3.10a.tar.gz - -@@ -167,7 +162,7 @@ - - patch -p1 < ../xv-3.10a-jumbo-fix-patch-20050410.txt - -- [optional] patch -p1 < ../xv-3.10a-jumbo-enh-patch-20050410.txt -+ [optional] patch -p1 < ../xv-3.10a-jumbo-enh-patch-20050501.txt - - edit Makefile and config.h as directed in INSTALL file (in particular, - ensure paths to external libraries and header files are correct) -@@ -221,6 +216,8 @@ - - freebsd-vdcomp-newline.patch (AAC) - - xv-3.10a.patch.linux (PBJ) [/bin/sh versions of cleandir, RANLIB.sh only] - - removed trailing white space (GRR) [purely cosmetic] -+20040523: -+ - fixed compilation error in registered versions (GRR) - 20050410: - - fix for YCbCr oversaturated-green bug(s) in TIFF decoder (GRR) - - provisional fix for contiguous tiled TIFFs with bottom-* orientation (GRR) -@@ -265,12 +262,50 @@ - - boosted maximum number of files from 4096 to 32768 (GRR) - (note that OS kernel limits may also apply; for example, in Linux see - MAX_ARG_PAGES in linux-<version>/include/linux/binfmts.h) -- - xv-3.10a-bmp16.patch -- (from http://www.coara.or.jp/~sudakyo/XV_jp.html) -+ - xv-3.10a-bmp16.patch (KS) - - final-image delay (e.g., "-wait 0.2,3" : pause 3 secs on final image) (GRR) - - xv-numpad.patch (EK) - - xv-delete-is-not-backspace.patch (EK) - - made browser window (schnauzer) and icons configurable (AT, GRR) -+20050501: -+ - xv-3.10a-bmpfix.patch (WF) [*SECURITY*] -+ - xv310a-jp-extension-rev5.3.3.tar.gz (TI, IM, ..., WF) -+ (adds support for MAG, MAKI, Pi, PIC, and PIC2 formats[*]; "magic suffix" -+ detection/conversion; MacBinary prefixes; archives as virtual filesystems; -+ multilingual text viewer [though not Unicode]; etc.) -+ - xv-3.10a-yaos.dif (WF, TO) [*SECURITY*] -+ (fixes a number of format-string issues and system() calls) -+ - xv-3.10a.dif (WF) [*SECURITY*] -+ (fixes more format-string issues, mktemp() and open() calls, and compilation -+ warnings [mostly from jp-extension patch]) -+ - xv-3.10a-jumbo-jpd_startgrab-patch-20050420.txt (JPD) -+ - PATCH.alwaysnever (LJ) -+ - PATCH.bsd (LJ) -+ - PATCH.linedraw (LJ) -+ - PATCH.multipage (LJ) -+ - PATCH.multipageGIF (LJ) -+ - PATCH.random (LJ) -+ - PATCH.stat (LJ) -+ - PATCH.thumbs (LJ) -+ - xv-startgrab-imake-hips.patch (JPD) -+ ("hips" portion only; adds support for HIPS image format[*]) -+ - xv-3.10a-formatstr.patch (KS) -+ - xv-3.10a-shortsleep.patch (KS) -+ - xv-3.10a-locale-linux.patch (KS) -+ - xv-3.10a-printkey.patch (KS) -+ - xv-3.10a-sysconfdir.patch (KS) -+ - added PREFIX and DESTDIR support to Makefile (KS, GRR) -+ - xv-3.10a-xvexecpath.patch (but disabled pending fixes) (KS) -+ - xv-3.10a-zeroquit.patch (KS, GRR) -+ -+ -+[*] Note that all six of these formats may still suffer from exploitable heap -+ overflows [*SECURITY*] when decoding images with large (possibly invalid) -+ dimensions; as a result, they are DISABLED by default. (Search for "GRR -+ POSSIBLE OVERFLOW / FIXME" comments in xvmag.c, xvmaki.c, xvpi.c, xvpic.c, -+ xvpic2.c, and xvhips.c, but keep in mind that these may not be exhaustive.) -+ Users who choose to overlook these security issues can enable any or all -+ of them by editing config.h. - - - not (yet?) included: -@@ -284,31 +319,21 @@ - -rw-r--r-- 42397 Mar 11 2004 xv-3.10a-download-test2.patch - -rw-r--r-- 47679 Mar 11 2004 xv-3.10a-download-test3.patch - -rw-r--r-- 52745 Mar 11 2004 xv-3.10a-download-test4.patch -- -rw-r--r-- 415 Mar 11 2004 xv-3.10a-formatstr.patch - -rw-r--r-- 3423 Apr 24 2004 xv-3.10a-keyzoom.patch -- -rw-r--r-- 1461 Mar 11 2004 xv-3.10a-locale-linux.patch - -rw-r--r-- 12387 Mar 15 2004 xv-3.10a-menubutton.patch - -rw-r--r-- 1178 Apr 24 2004 xv-3.10a-noblink.patch -- -rw-r--r-- 484 Mar 11 2004 xv-3.10a-printkey.patch - -rw-r--r-- 57092 Jul 9 2004 xv-3.10a-resolution.patch - -rw-r--r-- 4645 Apr 24 2004 xv-3.10a-selall.patch -- -rw-r--r-- 360 Mar 11 2004 xv-3.10a-shortsleep.patch - -rw-r--r-- 702 Apr 24 2004 xv-3.10a-showlongname.patch - -rw-r--r-- 1205 Apr 24 2004 xv-3.10a-staytoppdir.patch -- -rw-r--r-- 1591 Mar 15 2004 xv-3.10a-sysconfdir.patch - -rw-r--r-- 4228 Apr 24 2004 xv-3.10a-wheelmouse.patch - -rw-r--r-- 744 Apr 24 2004 xv-3.10a-xvbutt_wait.patch -- -rw-r--r-- 712 Mar 11 2004 xv-3.10a-xvexecpath.patch - -rw-r--r-- 3757 Jul 9 2004 xv-3.10a-xvscrl_button2.patch - -rw-r--r-- 1494 Jul 9 2004 xv-3.10a-xvscrl_wait.patch - -rw-r--r-- 19352 Jul 9 2004 xv-3.10a-xvzoom.patch -- -rw-r--r-- 1827 Apr 24 2004 xv-3.10a-zeroquit.patch - -- - xv310a-jp-extension-rev5.3.3.tar.gz [extensive] -- - xv-3.10a-jp-extension-5.3.3-png-1.2d.patch [PNG patch relative to jp-ext] -- - xv-3.10a+jp-extension-rev5.3.3+FLmask.v2.1+png+misc.patch [??] -+ - xv-3.10a+jp-extension-rev5.3.3+FLmask.v2.1+png+misc.patch ["mask" support] - -- - xv-grab-imake-hips.patch (JPD) [HIPS format, -startgrab option] - - xv-psnewstyle.patch (TA) [coming later in 2005?] - - xv-3.10a.patch.linux (PBJ) [maybe use vdcomp.c changes?] - - xvxpm-anthony-thyssen.c (AT) ["slate grey" bug already gone?] -@@ -332,8 +357,8 @@ - not finished (and/or even started ;-) ): - - - fix xvpng.c not to use direct struct access -- - fix for never-ending pile of SLOW popups when viewing TIFFs with unknown tags -- (or truncated/corrupted images) -+ - (better) fix for never-ending pile of SLOW popups when viewing TIFFs with -+ unknown tags (or truncated/corrupted images) - - fix for minor .Z inefficiency in xv.c ("FIXME") - - fix for filename entry-field mouse/cursor bogosity - (want at least positioning to work; preferably also select/cut/paste) -@@ -344,6 +369,7 @@ - - transparency support for TIFF, XPM and TGA images - - support for tiled background image (with transparent foreground image) - - MNG/JNG support -+ - SVG support - - - ChangeLog -@@ -364,7 +390,7 @@ - 20040531 - fixed undefined CLK_TCK with gcc -ansi (enh/USE_TICKS option); made - libjpeg, libtiff, libpng and zlib sections of makefile more consistent -- (enh); -+ (enh) - - 20040606 - added freshmeat link, build instructions, and changelog to jumbo README -@@ -385,3 +411,32 @@ - sex bug in 24-bit FixPix display code (enh/USE_24BIT_ENDIAN_FIX option); - fixed numerical-keypad NumLock behavior and delete-key behavior in file- - load/save window (enh); made schnauzer window and icons configurable (enh) -+ -+ 20050417 -+ incorporated "Japanese extension" patches, revision 5.3.3 (enh); fixed -+ additional *SECURITY* issues (format-string vulnerabilities, system() -+ and mktemp() calls, etc., but NOT heap overflows in new decoders) both -+ in existing code and in jp-extension additions (enh) -+ -+ 20050425 -+ added support for -startgrab option (enh); added support for a "Never" -+ button to file-overwrite popups (enh); added NetBSD and BSDI to list of -+ mkstemp()-supporting systems (enh); improved line-drawing code to set the -+ correct pixels for lines of all slopes (enh); added "Page n of m" to Info -+ window for multipage images (enh); added support for multipage (animated) -+ GIFs (enh); fixed -random support so randomized file list can be traversed -+ normally in forward or backward direction (enh); added typecasts to stat() -+ printfs for portability (enh); fixed erroneous use of "creation" time and -+ forced unlink prior to overwrite in schnauzer thumbnail code (enh); added -+ HIPS support (enh/HAVE_HIPS option) -+ -+ 20050501 -+ extended multipage keyboard support (PgUp/PgDn) to all windows except -+ control ("console") and directory (enh); fixed minor (non-security) -+ format-string issue in xv.c (enh); shortened delay on popup error windows -+ from 3 seconds to 1 second (enh); tweaked text-viewer localization support -+ (TV_L10N) for Linux (enh); added keyboard short cuts for Color and -+ Grayscale buttons in print dialog (enh); added support for separate "magic -+ suffix" (xv_mgcsfx) config dir (enh); added PREFIX and DESTDIR support to -+ Makefile (enh); fixed handling of zero-length files and other text-viewer -+ failures (enh) -diff -ruN xv-3.10a-bugfixes/README.pcd xv-3.10a-enhancements/README.pcd ---- xv-3.10a-bugfixes/README.pcd 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/README.pcd 2001-07-08 11:21:19.000000000 -0700 -@@ -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 -+extensively 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 -ruN xv-3.10a-bugfixes/bggen.c xv-3.10a-enhancements/bggen.c ---- xv-3.10a-bugfixes/bggen.c 2004-05-16 17:50:52.000000000 -0700 -+++ xv-3.10a-enhancements/bggen.c 2005-04-17 14:04:22.000000000 -0700 -@@ -34,7 +34,7 @@ - #define MAXCOLS 128 - - /* some VMS thing... */ --#ifdef vax11c -+#if defined(vax11c) || (defined(__sony_news) && (defined(bsd43) || defined(__bsd43) || defined(SYSTYPE_BSD) || defined(__SYSTYPE_BSD))) - #include <ctype.h> - #endif - -diff -ruN xv-3.10a-bugfixes/bits/br_bzip2 xv-3.10a-enhancements/bits/br_bzip2 ---- xv-3.10a-bugfixes/bits/br_bzip2 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_bzip2 1998-04-12 19:23:39.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_bzip2_width 48 -+#define br_bzip2_height 48 -+static unsigned char br_bzip2_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, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x7c, 0xbe, 0x3d, 0x0e, 0x02, 0x20, 0xfc, 0xbe, 0x7d, 0x1f, 0x02, -+ 0x20, 0xcc, 0xb0, 0x6d, 0x1b, 0x02, 0x20, 0xcc, 0x98, 0x6d, 0x1b, 0x02, -+ 0x20, 0xfc, 0x98, 0x6d, 0x18, 0x02, 0x20, 0x7c, 0x8c, 0x7d, 0x0c, 0x02, -+ 0x20, 0xcc, 0x8c, 0x3d, 0x0e, 0x02, 0x20, 0xcc, 0x84, 0x0d, 0x06, 0x02, -+ 0x20, 0xcc, 0x86, 0x0d, 0x03, 0x02, 0x20, 0xfc, 0xbe, 0x0d, 0x1f, 0x02, -+ 0x20, 0x7c, 0xbe, 0x0d, 0x1f, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 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 -ruN xv-3.10a-bugfixes/bits/br_mag xv-3.10a-enhancements/bits/br_mag ---- xv-3.10a-bugfixes/bits/br_mag 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_mag 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_mag_width 48 -+#define br_mag_height 48 -+static unsigned char br_mag_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, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x0c, 0x86, 0xc1, 0x0f, 0x02, -+ 0x20, 0x0c, 0xc6, 0xe3, 0x1f, 0x02, 0x20, 0x1c, 0xe7, 0x67, 0x18, 0x02, -+ 0x20, 0x1c, 0x77, 0x6e, 0x18, 0x02, 0x20, 0xbc, 0x37, 0x6c, 0x00, 0x02, -+ 0x20, 0xbc, 0x37, 0x6c, 0x00, 0x02, 0x20, 0xec, 0x36, 0x6c, 0x1e, 0x02, -+ 0x20, 0xec, 0xf6, 0x6f, 0x1e, 0x02, 0x20, 0x4c, 0xf6, 0x6f, 0x18, 0x02, -+ 0x20, 0x4c, 0x36, 0x6c, 0x18, 0x02, 0x20, 0x0c, 0x36, 0x6c, 0x18, 0x02, -+ 0x20, 0x0c, 0x36, 0xec, 0x1f, 0x02, 0x20, 0x0c, 0x36, 0xcc, 0x0f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 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 -ruN xv-3.10a-bugfixes/bits/br_maki xv-3.10a-enhancements/bits/br_maki ---- xv-3.10a-bugfixes/bits/br_maki 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_maki 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_maki_width 48 -+#define br_maki_height 48 -+static unsigned char br_maki_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, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x83, 0x61, 0x18, 0x33, 0x02, -+ 0x20, 0x83, 0xf1, 0x98, 0x33, 0x02, 0x20, 0xc7, 0xf9, 0x99, 0x31, 0x02, -+ 0x20, 0xc7, 0x9d, 0xdb, 0x30, 0x02, 0x20, 0xef, 0x0d, 0xfb, 0x30, 0x02, -+ 0x20, 0xef, 0x0d, 0x7b, 0x30, 0x02, 0x20, 0xbb, 0x0d, 0x7b, 0x30, 0x02, -+ 0x20, 0xbb, 0xfd, 0xdb, 0x30, 0x02, 0x20, 0x93, 0xfd, 0xdb, 0x30, 0x02, -+ 0x20, 0x93, 0x0d, 0x9b, 0x31, 0x02, 0x20, 0x83, 0x0d, 0x9b, 0x31, 0x02, -+ 0x20, 0x83, 0x0d, 0x1b, 0x33, 0x02, 0x20, 0x83, 0x0d, 0x1b, 0x33, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 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 -ruN xv-3.10a-bugfixes/bits/br_mgcsfx xv-3.10a-enhancements/bits/br_mgcsfx ---- xv-3.10a-bugfixes/bits/br_mgcsfx 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_mgcsfx 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_mgcsfx_width 48 -+#define br_mgcsfx_height 48 -+static unsigned char br_mgcsfx_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, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x3c, 0xcf, 0x71, 0x00, 0x02, -+ 0x20, 0x6c, 0x61, 0xda, 0x00, 0x02, 0x20, 0x6c, 0x67, 0xd8, 0x1e, 0x02, -+ 0x20, 0x3c, 0x61, 0xd8, 0x1e, 0x02, 0x20, 0x6c, 0x61, 0xda, 0x00, 0x02, -+ 0x20, 0x6c, 0xcf, 0x71, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x4e, 0x7a, 0xef, 0x3d, 0x02, 0x20, 0xd3, 0x32, 0x68, 0x6c, 0x02, -+ 0x20, 0xc3, 0x32, 0xe4, 0x6c, 0x02, 0x20, 0x5b, 0x33, 0x62, 0x6c, 0x02, -+ 0x20, 0x53, 0x33, 0x61, 0x6c, 0x02, 0x20, 0x4e, 0x7a, 0xef, 0x3d, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 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 -ruN xv-3.10a-bugfixes/bits/br_pcd xv-3.10a-enhancements/bits/br_pcd ---- xv-3.10a-bugfixes/bits/br_pcd 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_pcd 1995-06-15 21:31:53.000000000 -0700 -@@ -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 -ruN xv-3.10a-bugfixes/bits/br_pi xv-3.10a-enhancements/bits/br_pi ---- xv-3.10a-bugfixes/bits/br_pi 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_pi 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_pi_width 48 -+#define br_pi_height 48 -+static unsigned char br_pi_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, 0x80, 0x1f, 0x7e, 0x00, 0x02, -+ 0x20, 0x80, 0x3f, 0x7e, 0x00, 0x02, 0x20, 0x80, 0x31, 0x18, 0x00, 0x02, -+ 0x20, 0x80, 0x31, 0x18, 0x00, 0x02, 0x20, 0x80, 0x31, 0x18, 0x00, 0x02, -+ 0x20, 0x80, 0x39, 0x18, 0x00, 0x02, 0x20, 0x80, 0x1f, 0x18, 0x00, 0x02, -+ 0x20, 0x80, 0x0f, 0x18, 0x00, 0x02, 0x20, 0x80, 0x01, 0x18, 0x00, 0x02, -+ 0x20, 0x80, 0x01, 0x18, 0x00, 0x02, 0x20, 0x80, 0x01, 0x18, 0x00, 0x02, -+ 0x20, 0x80, 0x01, 0x7e, 0x00, 0x02, 0x20, 0x80, 0x01, 0x7e, 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 -ruN xv-3.10a-bugfixes/bits/br_pic xv-3.10a-enhancements/bits/br_pic ---- xv-3.10a-bugfixes/bits/br_pic 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_pic 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_pic_width 48 -+#define br_pic_height 48 -+static unsigned char br_pic_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, 0xf0, 0xf3, 0xf3, 0x01, 0x02, -+ 0x20, 0xf0, 0xf7, 0xfb, 0x03, 0x02, 0x20, 0x30, 0xc6, 0x18, 0x03, 0x02, -+ 0x20, 0x30, 0xc6, 0x18, 0x00, 0x02, 0x20, 0x30, 0xc6, 0x18, 0x00, 0x02, -+ 0x20, 0x30, 0xc7, 0x18, 0x00, 0x02, 0x20, 0xf0, 0xc3, 0x18, 0x00, 0x02, -+ 0x20, 0xf0, 0xc1, 0x18, 0x00, 0x02, 0x20, 0x30, 0xc0, 0x18, 0x00, 0x02, -+ 0x20, 0x30, 0xc0, 0x18, 0x00, 0x02, 0x20, 0x30, 0xc0, 0x18, 0x03, 0x02, -+ 0x20, 0x30, 0xf0, 0xfb, 0x03, 0x02, 0x20, 0x30, 0xf0, 0xf3, 0x01, 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 -ruN xv-3.10a-bugfixes/bits/br_pic2 xv-3.10a-enhancements/bits/br_pic2 ---- xv-3.10a-bugfixes/bits/br_pic2 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_pic2 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,27 @@ -+#define br_pic2_width 48 -+#define br_pic2_height 48 -+static unsigned char br_pic2_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, 0x3f, 0x3f, 0x1f, 0x1f, 0x02, -+ 0x20, 0x7f, 0xbf, 0xbf, 0x3f, 0x02, 0x20, 0x63, 0x8c, 0xb1, 0x31, 0x02, -+ 0x20, 0x63, 0x8c, 0x01, 0x30, 0x02, 0x20, 0x63, 0x8c, 0x01, 0x30, 0x02, -+ 0x20, 0x73, 0x8c, 0x01, 0x30, 0x02, 0x20, 0x3f, 0x8c, 0x01, 0x18, 0x02, -+ 0x20, 0x1f, 0x8c, 0x01, 0x0c, 0x02, 0x20, 0x03, 0x8c, 0x01, 0x06, 0x02, -+ 0x20, 0x03, 0x8c, 0x01, 0x03, 0x02, 0x20, 0x03, 0x8c, 0xb1, 0x01, 0x02, -+ 0x20, 0x03, 0xbf, 0xbf, 0x3f, 0x02, 0x20, 0x03, 0x3f, 0x9f, 0x3f, 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 -ruN xv-3.10a-bugfixes/bits/br_png xv-3.10a-enhancements/bits/br_png ---- xv-3.10a-bugfixes/bits/br_png 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_png 1996-06-13 14:32:08.000000000 -0700 -@@ -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 -ruN xv-3.10a-bugfixes/bits/br_zx xv-3.10a-enhancements/bits/br_zx ---- xv-3.10a-bugfixes/bits/br_zx 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/bits/br_zx 1998-08-06 13:00:03.000000000 -0700 -@@ -0,0 +1,28 @@ -+#define br_zx_width 48 -+#define br_zx_height 48 -+static unsigned char br_zx_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, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0xff, 0xff, 0xff, 0x7f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x7f, 0xce, 0x01, 0x0e, 0x02, 0x20, 0x61, 0x84, 0x00, 0x11, 0x02, -+ 0x20, 0x30, 0x48, 0x00, 0x10, 0x02, 0x20, 0x18, 0x38, 0x10, 0x08, 0x02, -+ 0x20, 0x0c, 0x30, 0x10, 0x0e, 0x02, 0x20, 0x06, 0x68, 0x7c, 0x10, 0x02, -+ 0x20, 0x03, 0x48, 0x10, 0x10, 0x02, 0x20, 0x41, 0x84, 0x10, 0x11, 0x02, -+ 0x20, 0x7f, 0xce, 0x01, 0x0e, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xff, 0xff, 0xff, 0xff, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x40, 0x02, 0x20, 0xff, 0xff, 0xff, 0x3f, 0x02, -+ 0x20, 0x00, 0x00, 0x00, 0x10, 0x02, 0x20, 0x00, 0x00, 0x00, 0x08, 0x03, -+ 0x20, 0x00, 0x00, 0x00, 0x84, 0x03, 0x20, 0x00, 0x00, 0x00, 0xc2, 0x03, -+ 0x20, 0x00, 0x00, 0x00, 0xe1, 0x03, 0x20, 0x00, 0x00, 0x80, 0xf0, 0x02, -+ 0x20, 0x00, 0x00, 0x40, 0x78, 0x02, 0x20, 0x00, 0x00, 0x20, 0x3c, 0x02, -+ 0x20, 0x00, 0x00, 0x10, 0x1e, 0x02, 0x20, 0x00, 0x00, 0x08, 0x0f, 0x03, -+ 0x20, 0x00, 0x00, 0x84, 0x87, 0x03, 0x20, 0x00, 0x00, 0xc2, 0xc3, 0x03, -+ 0x20, 0x00, 0x00, 0xe1, 0xe1, 0x03, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x03, -+ }; -diff -ruN xv-3.10a-bugfixes/config.h xv-3.10a-enhancements/config.h ---- xv-3.10a-bugfixes/config.h 2005-03-21 23:21:31.000000000 -0800 -+++ xv-3.10a-enhancements/config.h 2005-04-30 23:52:42.000000000 -0700 -@@ -6,26 +6,46 @@ - /*************************************************************************** - * GZIP'd file support - * -- * if you have the gnu uncompression utility 'gunzip', XV can use it to -- * automatically 'unzip' any gzip'd files. To enable this feature, -- * change 'undef' to 'define' in the following line. Needless to say, if -- * your gunzip is installed elsewhere on your machine, change the 'GUNZIP' -- * definition appropriately. (use 'which gunzip' to find if you have gunzip, -- * and where it lives) -+ * if you have the GNU uncompression utility 'gunzip' (or 'gzip' itself, -+ * which is just a link to gunzip), XV can use it to automatically 'unzip' -+ * any gzip'd files. To enable this feature, change 'undef' to 'define' in -+ * the following line. Needless to say, if your gunzip is installed elsewhere -+ * on your machine, change the 'GUNZIP' definition appropriately. (use -+ * 'which gunzip' to find if you have gunzip, and where it lives; ditto for -+ * gzip) - */ --#undef USE_GUNZIP -+#define USE_GUNZIP - - #ifdef USE_GUNZIP - # ifdef VMS - # define GUNZIP "UNCOMPRESS" - # else --/* define GUNZIP "/usr/local/bin/gunzip -q" */ --# define GUNZIP "/usr/bin/gzip -dq" /* more portable */ -+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__) -+# define GUNZIP "/usr/bin/gzip -dq" -+# else -+# define GUNZIP "/usr/local/bin/gzip -dq" /* is full path truly needed? */ -+# endif - # endif - #endif - - - /*************************************************************************** -+ * BZIP2'd file support -+ * -+ * if you have the uncompression utility 'bunzip2' (or 'bzip2' itself, which -+ * is just a link to bunzip2), XV can use it to automatically 'unzip' any -+ * bzip2'd files. To enable this feature, change 'undef' to 'define' in the -+ * following line (if not already done). Use 'which bunzip2' or 'which bzip2' -+ * to find if you have bzip2/bunzip2, and where it lives. -+ */ -+#define USE_BUNZIP2 -+ -+#ifdef USE_BUNZIP2 -+# define BUNZIP2 "bzip2 -d" /* should this include the full path? */ -+#endif -+ -+ -+/*************************************************************************** - * compress'd file support - * - * if you have GUNZIP defined above, just ignore this, as 'gunzip' can -@@ -38,7 +58,14 @@ - */ - #define UNCOMPRESS "/usr/ucb/uncompress" - --#if defined(hpux) || defined(SVR4) || defined(__386BSD__) -+#if defined(hpux) || defined(SVR4) || \ -+ defined(__386BSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || \ -+ defined(__linux__) -+ /* -+ I want to use BSD macro for checking if this OS is *BSD or not, -+ but the macro is defined in <sys/parm.h>, which I don't know all -+ machine has or not. -+ */ - # undef UNCOMPRESS - # define UNCOMPRESS "/usr/bin/uncompress" - #endif -@@ -90,6 +117,7 @@ - */ - - /* #define GS_PATH "/usr/local/bin/gs" */ -+#define GS_PATH "/usr/bin/gs" - /* #define GS_LIB "." */ - /* #define GS_DEV "ppmraw" */ - -@@ -120,3 +148,201 @@ - - #define BACKING_STORE - -+ -+/*************************************************************************** -+ * PhotoCD/MAG/PIC/MAKI/Pi/PIC2/HIPS format Support: -+ * -+ * if, for whatever reason--say, security concerns--you don't want to -+ * include support for one or more of the PhotoCD, MAG/MAKI/Pi/PIC/PIC2 -+ * (Japanese), or HIPS (astronomical) image formats, change the relevant -+ * 'define' to 'undef' in the following lines. Conversely, if you *do* -+ * want them, change 'undef' to 'define' as appropriate. -+ */ -+ -+#define HAVE_PCD /* believed to be reasonably safe */ -+ -+#undef HAVE_MAG /* probable security issues */ -+#undef HAVE_MAKI /* probable security issues */ -+#undef HAVE_PI /* probable security issues */ -+#undef HAVE_PIC /* probable security issues */ -+#undef HAVE_PIC2 /* probable security issues */ -+ -+#undef HAVE_HIPS /* probable security issues */ -+ -+ -+/*************************************************************************** -+ * MacBinary file support: -+ * -+ * if you want XV to be able to handle ``MacBinary'' files (which have -+ * 128 byte info file header at the head), change 'undef' to 'define' -+ * in the following line. -+ */ -+ -+#undef MACBINARY -+ -+ -+/*************************************************************************** -+ * Auto Expand support: -+ * -+ * if you want to extract archived file automatically and regard it as -+ * a directory, change 'undef' to 'define' in the AUTO_EXPAND line. -+ * -+ * Virtual Thumbdir support: -+ * -+ * if you want Virtual directory based Thumbdir(It means that XV -+ * doesn't forget builded Icons still be quited even if the directory -+ * is read-only), change 'undef' to 'define' the VIRTUAL_TD line. -+ */ -+ -+#undef AUTO_EXPAND -+#undef VIRTUAL_TD -+ -+#if defined(VIRTUAL_TD) && !defined(AUTO_EXPAND) -+# undef VIRTUAL_TD -+#endif -+ -+ -+/*************************************************************************** -+ * Adjust the aspect ratio of Icons: -+ * -+ * if you want to adjust the aspect ratio of the icons in Visual -+ * Schnauzer, change 'undef' to 'define' in the following line. -+ */ -+ -+#undef VS_ADJUST -+ -+ -+/*************************************************************************** -+ * Restore original colormap: -+ * -+ * if you want to restore original colormap when icons in Visual -+ * Shunauzer is double-clicked, change 'undef' to 'define' in the -+ * following line. -+ */ -+ -+#undef VS_RESCMAP -+ -+ -+/*************************************************************************** -+ * TextViewer l10n support: -+ * -+ * if you want XV to show the text in Japanese on TextViewer, change -+ * 'undef' to 'define' in the following line. -+ */ -+ -+#undef TV_L10N -+ -+#ifdef TV_L10N -+/* -+ * if you want to change the default code-set used in case that XV -+ * fails to select correct code-set, uncomment the '#define -+ * LOCALE_DEFAULT' line and change the 'LOCALE_DEFAULT' definition -+ * appropriately. -+ * (0:ASCII, 1:EUC-j, 2:JIS, 3:MS Kanji) */ -+ -+/* # define LOCALE_DEFAULT 0 */ -+ -+/* -+ * Uncomment and edit the following lines, if your X Window System was -+ * not compiled with -DX_LOCALE and you failed to display the Japanese -+ * text in TextViewer. You don't have to write locale name of JIS code-set -+ * and Microsoft code-set, if your system doesn't support those code-sets. -+ */ -+ -+/* -+# define LOCALE_NAME_EUC "ja_JP.EUC" -+# define LOCALE_NAME_JIS "ja_JP.JIS" -+# define LOCALE_NAME_MSCODE "ja_JP.SJIS" -+*/ -+ -+/* -+ * if your system doesn't have the Japanese fonts in the sizes, -+ * Uncomment and edit the following font size entries. -+ */ -+ -+/* # define TV_FONTSIZE 14,16,24 */ -+ -+/* -+ * If you need, uncomment and modify the following font name. -+ */ -+ -+/* # define TV_FONTSET "-*-fixed-medium-r-normal--%d-*" */ -+#endif /* TV_L10N */ -+ -+ -+/*************************************************************************** -+ * User definable filter support: -+ * -+ * Use the filters as input and output method for load and save unsupported -+ * image format file. The filter command is recognized by definition of -+ * magic number or suffix in "~/.xv_mgcsfx" . -+ * To enable this feature, change 'undef' to 'define' in the following line. -+ */ -+#undef HAVE_MGCSFX -+ -+#ifdef HAVE_MGCSFX -+/* -+ * Support symbol 'auto' as <input image type> in startup file. This type -+ * cannot use pipe as input; it writes to a temporary file and recognizes -+ * the actual filetype by XV processing. -+ */ -+# define HAVE_MGCSFX_AUTO -+ -+/* -+ * The startup file of definition for MgcSfx. 'MGCSFX_SITE_RC' is read -+ * first and '~/MGCSFX_RC' is second. So same definitions in both files -+ * are overridden by '~/MGCSFX_RC' -+ * To define startup file, see the sample of startup file 'xv_mgcsfx.sample'. -+ */ -+# define MGCSFX_SITE_RC "xv_mgcsfx" -+# define MGCSFX_RC ".xv_mgcsfx" -+ -+/* -+ * If you want startup file to pass preprocessor in reading time, then -+ * change 'undef' to 'define' in the following line. -+ * -+ * WARNING : If you decide to use preprocessor, you must not write -+ * '# <comment>' style comment in startup file. Because, -+ * preprocessor can't recognize. */ -+# undef USE_MGCSFX_PREPROCESSOR -+ -+# ifdef USE_MGCSFX_PREPROCESSOR -+/* -+ * This is used like "system("MGCSFX_PREPROCESSOR MGCSFX_RC > tmp_name");", -+ * and read tmp_name instead of MGCSFX_RC. -+ */ -+# define MGCSFX_PREPROCESSOR "/usr/lib/cpp" -+/* # define MGCSFX_PREPROCESSOR "cc -E" */ -+ -+# endif /* USE_MGCSFX_PREPROCESSOR */ -+ -+/* -+ * Default string of command. If input command is required for undefined file, -+ * dialog is popuped with 'MGCSFX_DEFAULT_INPUT_COMMAND'. And, if output -+ * command is required in save dialog of MgcSfx, dialog is popuped with -+ * 'MGCSFX_DEFAULT_OUTPUT_COMMAND'. -+ * -+ * WARNING : Now, supported only 'PNM' image format, when command input is -+ * required. You should define filter which use 'PNM' image format -+ * as input or output. -+ */ -+# define MGCSFX_DEFAULT_INPUT_COMMAND "tifftopnm" -+# define MGCSFX_DEFAULT_OUTPUT_COMMAND "pnmtotiff" -+ -+#endif /* HAVE_MGCSFX */ -+ -+ -+/*************************************************************************** -+ * Multi-Lingual TextViewer -+ * -+ * if you want XV to show the text in multi-lingual on TextViewer, change -+ * 'undef' to 'define' in the following line. -+ */ -+ -+#undef TV_MULTILINGUAL -+ -+#define TV_DEFAULT_CODESET TV_EUC_JAPAN -+ -+#ifdef TV_MULTILINGUAL -+# undef TV_L10N -+#endif -diff -ruN xv-3.10a-bugfixes/tiff/Makefile xv-3.10a-enhancements/tiff/Makefile ---- xv-3.10a-bugfixes/tiff/Makefile 2004-05-16 18:49:11.000000000 -0700 -+++ xv-3.10a-enhancements/tiff/Makefile 2005-04-17 14:45:28.000000000 -0700 -@@ -38,7 +38,7 @@ - IPATH= -I. - - COPTS= -O --CFLAGS= ${COPTS} ${IPATH} -+CFLAGS= ${COPTS} ${IPATH} -D_BSD_SOURCE - - INCS= tiff.h tiffio.h - -diff -ruN xv-3.10a-bugfixes/vdcomp.c xv-3.10a-enhancements/vdcomp.c ---- xv-3.10a-bugfixes/vdcomp.c 2005-03-20 17:48:59.000000000 -0800 -+++ xv-3.10a-enhancements/vdcomp.c 2005-04-17 22:59:39.000000000 -0700 -@@ -106,6 +106,7 @@ - !defined(pyr) && \ - !defined(__UMAXV__) && \ - !defined(bsd43) && \ -+ !defined(__bsd43) && \ - !defined(aux) && \ - !defined(__bsdi__) && \ - !defined(sequent) && \ -@@ -115,7 +116,14 @@ - # if defined(hp300) || defined(hp800) || defined(NeXT) - # include <sys/malloc.h> /* it's in 'sys' on HPs and NeXT */ - # else --# include <malloc.h> -+# if !defined(__386BSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__) -+ /* -+ I want to use BSD macro for checking if this OS is *BSD or not, -+ but the macro is defined in <sys/parm.h>, which I don't know all -+ machine has or not. -+ */ -+# include <malloc.h> -+# endif - # endif - # endif - #endif /* !VMS */ -diff -ruN xv-3.10a-bugfixes/xcmap.c xv-3.10a-enhancements/xcmap.c ---- xv-3.10a-bugfixes/xcmap.c 2005-03-20 15:51:59.000000000 -0800 -+++ xv-3.10a-enhancements/xcmap.c 2005-04-17 14:45:28.000000000 -0700 -@@ -163,7 +163,7 @@ - XSetBackground(theDisp,theGC,bcol); - - CreateMainWindow(cmd,geom,argc,argv); -- Resize(WIDE,HIGH); -+ Resize((int)WIDE,(int)HIGH); - - XSelectInput(theDisp, mainW, ExposureMask | KeyPressMask - | StructureNotifyMask | ButtonPressMask); -@@ -212,10 +212,10 @@ - - case ConfigureNotify: { - XConfigureEvent *conf_event = (XConfigureEvent *) event; -+ int w = conf_event->width, h = conf_event->height; - -- if (conf_event->window == mainW && -- (conf_event->width != WIDE || conf_event->height != HIGH)) -- Resize(conf_event->width, conf_event->height); -+ if (conf_event->window == mainW && (w != WIDE || h != HIGH)) -+ Resize((int)(w ? w : WIDE), (int)(h ? h : HIGH)); - } - break; - -@@ -274,6 +274,8 @@ - WIDE = HIGH = 256; /* default window size */ - - x=y=w=h=1; -+ hints.flags = 0; -+ - i=XParseGeometry(geom,&x,&y,&w,&h); - if (i&WidthValue) - { -diff -ruN xv-3.10a-bugfixes/xv.c xv-3.10a-enhancements/xv.c ---- xv-3.10a-bugfixes/xv.c 2005-03-20 22:25:22.000000000 -0800 -+++ xv-3.10a-enhancements/xv.c 2005-05-01 13:33:25.000000000 -0700 -@@ -62,6 +62,19 @@ - - static char basefname[128]; /* just the current fname, no path */ - -+#ifdef TV_L10N -+# ifndef TV_FONTSET -+# define TV_FONTSET "-*-fixed-medium-r-normal--%d-*" -+# endif -+# ifndef TV_FONTSIZE -+# define TV_FONTSIZE 14,16 -+# endif -+ -+static int mfontsize[] = { TV_FONTSIZE, 0 }; -+static char mfontset[256]; -+#endif -+ -+ - /* things to do upon successfully loading an image */ - static int autoraw = 0; /* force raw if using stdcmap */ - static int autodither = 0; /* dither */ -@@ -78,6 +91,12 @@ - - static int force8 = 0; /* force 8-bit mode */ - static int force24 = 0; /* force 24-bit mode */ -+#ifdef HAVE_PCD -+static int PcdSize = -1; /* force dialog to ask */ -+#endif -+ -+static float waitsec_nonfinal = -1; /* "normal" waitsec value */ -+static float waitsec_final = -1; /* final-image waitsec value */ - - /* used in DeleteCmd() and Quit() */ - static char **mainargv; -@@ -103,7 +122,6 @@ - static void openNextLoop PARM((void)); - static void openPrevPic PARM((void)); - static void openNamedPic PARM((void)); --static int findRandomPic PARM((void)); - static void mainLoop PARM((void)); - static void createMainWindow PARM((char *, char *)); - static void setWinIconNames PARM((char *)); -@@ -120,16 +138,17 @@ - int imap, ctrlmap, gmap, browmap, cmtmap, clrroot, nopos, limit2x; - char *display, *whitestr, *blackstr, *histr, *lostr, - *infogeom, *fgstr, *bgstr, *ctrlgeom, *gamgeom, *browgeom, *tmpstr; --char *rootfgstr, *rootbgstr, *visualstr, *textgeom, *cmtgeom; -+char *rootfgstr, *rootbgstr, *imagebgstr, *visualstr, *textgeom, *cmtgeom; - char *monofontname, *flistName; -+#ifdef TV_L10N -+char **misscharset, *defstr; -+int nmisscharset; -+#endif - int curstype, stdinflag, browseMode, savenorm, preview, pscomp, preset, - rmodeset, gamset, cgamset, perfect, owncmap, rwcolor, stdcmap; - int nodecor; - double gamval, rgamval, ggamval, bgamval; - -- -- -- - /*******************************************/ - int main(argc, argv) - int argc; -@@ -137,6 +156,9 @@ - /*******************************************/ - { - int i; -+#ifdef TV_L10N -+ int j; -+#endif - XColor ecdef; - Window rootReturn, parentReturn, *children; - unsigned int numChildren, rootDEEP; -@@ -153,6 +175,13 @@ - /*** variable Initialization ***/ - /*****************************************************/ - -+#ifdef TV_L10N -+ /* setlocale(LC_ALL, localeList[LOCALE_EUCJ]); */ -+ setlocale(LC_ALL, ""); -+ xlocale = (int)XSupportsLocale(); /* assume that (Bool) is (int) */ -+ /* if X doesn't support ja_JP.ujis text viewer l10n doesn't work. */ -+#endif -+ - xv_getwd(initdir, sizeof(initdir)); - searchdir[0] = '\0'; - fullfname[0] = '\0'; -@@ -162,7 +191,7 @@ - - /* init internal variables */ - display = NULL; -- fgstr = bgstr = rootfgstr = rootbgstr = NULL; -+ fgstr = bgstr = rootfgstr = rootbgstr = imagebgstr = NULL; - histr = lostr = whitestr = blackstr = NULL; - visualstr = monofontname = flistName = NULL; - winTitle = NULL; -@@ -180,6 +209,7 @@ - autoclose = autoDelete = 0; - cmapInGam = 0; - grabDelay = 0; -+ startGrab = 0; - showzoomcursor = 0; - perfect = owncmap = stdcmap = rwcolor = 0; - -@@ -228,6 +258,10 @@ - if (!tmpdir) FatalError("can't malloc 'tmpdir'\n"); - strcpy(tmpdir, tmpstr); - } -+#ifdef AUTO_EXPAND -+ Vdinit(); -+ vd_handler_setup(); -+#endif - - /* init command-line options flags */ - infogeom = DEFINFOGEOM; ctrlgeom = DEFCTRLGEOM; -@@ -238,7 +272,7 @@ - ninstall = 0; fixedaspect = 0; noFreeCols = nodecor = 0; - DEBUG = 0; bwidth = 2; - nolimits = useroot = clrroot = noqcheck = 0; -- waitsec = -1; waitloop = 0; automax = 0; -+ waitsec = waitsec_final = -1.0; waitloop = 0; automax = 0; - rootMode = 0; hsvmode = 0; - rmodeset = gamset = cgamset = 0; - nopos = limit2x = 0; -@@ -251,6 +285,10 @@ - preset = 0; - viewonly = 0; - -+#ifdef ENABLE_FIXPIX_SMOOTH -+ do_fixpix_smooth = 0; -+#endif -+ - /* init 'xormasks' array */ - xorMasks[0] = 0x01010101; - xorMasks[1] = 0x02020203; -@@ -277,6 +315,24 @@ - tiffW = (Window) NULL; tiffUp = 0; - #endif - -+#ifdef HAVE_PNG -+ pngW = (Window) NULL; pngUp = 0; -+#endif -+ -+ pcdW = (Window) NULL; pcdUp = 0; -+ -+#ifdef HAVE_PIC2 -+ pic2W = (Window) NULL; pic2Up = 0; -+#endif -+ -+#ifdef HAVE_PCD -+ pcdW = (Window) NULL; pcdUp = 0; -+#endif -+ -+#ifdef HAVE_MGCSFX -+ mgcsfxW = (Window) NULL; mgcsfxUp = 0; -+#endif -+ - imap = ctrlmap = gmap = browmap = cmtmap = 0; - - ch_offx = ch_offy = p_offx = p_offy = 0; -@@ -303,13 +359,35 @@ - verifyArgs(); - - -+#if 0 -+#ifdef XVEXECPATH -+ /* set up path to search for external executables */ -+ { -+ char *systempath = getenv("PATH"); -+ char *xvexecpath = getenv("XVPATH"); -+ if (xvexecpath == NULL) xvexecpath = XVEXECPATH; -+ /* FIXME: can systempath == NULL? */ -+ strcat(systempath, ":"); /* FIXME: writing to mem we don't own */ -+ strcat(systempath, xvexecpath); /* FIXME: writing to mem we don't own */ -+ /* FIXME: was there supposed to be a setenv() call in here? */ -+ if (DEBUG) -+ fprintf(stderr, "DEBUG: executable search path: %s\n", systempath); -+ } -+#endif -+#endif -+ -+ - /*****************************************************/ - /*** X Setup ***/ - /*****************************************************/ - - 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); -@@ -320,7 +398,7 @@ - - rootDEEP = dispDEEP; - -- /* things dependant on theVisual: -+ /* things dependent on theVisual: - * dispDEEP, theScreen, rootW, ncells, theCmap, theGC, - * vrWIDE, dispWIDE, vrHIGH, dispHIGH, maxWIDE, maxHIGH - */ -@@ -500,6 +578,7 @@ - arrow = XCreateFontCursor(theDisp,(u_int) curstype); - cross = XCreateFontCursor(theDisp,XC_crosshair); - tcross = XCreateFontCursor(theDisp,XC_tcross); -+ tlcorner = XCreateFontCursor(theDisp,XC_top_left_corner); - zoom = XCreateFontCursor(theDisp,XC_sizing); - - { -@@ -575,6 +654,18 @@ - xvAllocColor(theDisp, theCmap, &ecdef)) rootbg = ecdef.pixel; - - -+ /* GRR 19980308: set up image bg color (for transparent images) */ -+ have_imagebg = 0; -+ if (imagebgstr && XParseColor(theDisp, theCmap, imagebgstr, &ecdef) && -+ xvAllocColor(theDisp, theCmap, &ecdef)) { -+ /* imagebg = ecdef.pixel; */ -+ have_imagebg = 1; -+ imagebgR = ecdef.red; -+ imagebgG = ecdef.green; -+ imagebgB = ecdef.blue; -+ } -+ -+ - /* set up hi/lo colors */ - i=0; - if (dispDEEP > 1) { /* only if we're on a reasonable display */ -@@ -664,6 +755,61 @@ - - monofont=monofinfo->fid; - -+#ifdef TV_L10N -+ if (xlocale) { -+ i = 0; -+ while (mfontsize[i]) { -+ xlocale = 1; /* True */ -+ -+ sprintf(mfontset, TV_FONTSET, mfontsize[i]); -+/*fprintf(stderr, "FontSet: %s\n", mfontset);*/ -+ -+ monofset = XCreateFontSet(theDisp, mfontset, -+ &misscharset, &nmisscharset, &defstr); -+# if 0 /* not useful */ -+ if (!monofset) { -+ /* the current locale is not supported */ -+/*fprintf(stderr, "Current locale `%s' is not supported.\n", localeList[i]);*/ -+ xlocale = 0; -+ break; -+ } -+# endif -+/*fprintf(stderr, "# of misscharset in mfontsize[%d]: %d\n", i,nmisscharset);*/ -+ -+ for (j = 0; j < nmisscharset; j++) { -+ if (!strncmp(misscharset[j], "jisx0208", 8)) { -+ /* font for JIS X 0208 is not found */ -+ xlocale = 0; -+ break; -+ } -+ } -+ -+ if (xlocale) { -+ monofsetinfo = XExtentsOfFontSet(monofset); -+ monofsetinfo->max_logical_extent.width = mfontsize[i]; -+ /* correct size of TextViewer -+ in case that JIS X 0208 is not found */ -+ break; -+ } -+ -+ i++; -+ } /* while (mfontsize[i]) */ -+ -+# if 0 -+ if (nmisscharset > 0) { -+ sprintf(str,"missing %d charset:\n", nmisscharset); -+ for (i = 0; i < nmisscharset; i++) { -+ sprintf(str, "%s\t%s\n", str, misscharset[i]); -+ } -+# if 0 -+ FatalError(str); -+# else -+ fprintf(stderr, "%s", str); -+# endif -+ } -+# endif -+ } -+#endif /* TV_L10N */ - - - -@@ -693,6 +839,18 @@ - } - else namelist[0] = NULL; - } -+ else if (randomShow) { -+ int i, j; -+ char *tmp; -+ -+ srandom((int)time((time_t *)0)); -+ for (i = numnames; i > 1; i--) { -+ j = random() % i; -+ tmp = namelist[i-1]; -+ namelist[i-1] = namelist[j]; -+ namelist[j] = tmp; -+ } -+ } - - if (numnames) makeDispNames(); - -@@ -796,6 +954,25 @@ - XSetTransientForHint(theDisp, tiffW, dirW); - #endif - -+#ifdef HAVE_PNG -+ CreatePNGW(); -+ XSetTransientForHint(theDisp, pngW, dirW); -+#endif -+ -+#ifdef HAVE_PCD -+ CreatePCDW(); -+ XSetTransientForHint(theDisp, pcdW, dirW); -+#endif -+ -+#ifdef HAVE_PIC2 -+ CreatePIC2W(); -+ XSetTransientForHint(theDisp, pic2W, dirW); -+#endif -+ -+#ifdef HAVE_MGCSFX -+ CreateMGCSFXW(); -+ XSetTransientForHint(theDisp, mgcsfxW, dirW); -+#endif - - LoadFishCursors(); - SetCursors(-1); -@@ -964,7 +1141,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); - -@@ -1095,6 +1276,9 @@ - - if (rd_str ("fileList")) flistName = def_str; - if (rd_flag("fixed")) fixedaspect = def_int; -+#ifdef ENABLE_FIXPIX_SMOOTH -+ if (rd_flag("fixpix")) do_fixpix_smooth = def_int; -+#endif - if (rd_flag("force8")) force8 = def_int; - if (rd_flag("force24")) force24 = def_int; - if (rd_str ("foreground")) fgstr = def_str; -@@ -1106,21 +1290,37 @@ - if (rd_str ("highlight")) histr = def_str; - if (rd_str ("iconGeometry")) icongeom = def_str; - if (rd_flag("iconic")) startIconic = def_int; -+ if (rd_str ("imageBackground")) imagebgstr = def_str; - if (rd_str ("infoGeometry")) infogeom = def_str; - if (rd_flag("infoMap")) imap = def_int; - if (rd_flag("loadBrowse")) browseMode = def_int; - if (rd_str ("lowlight")) lostr = def_str; -+#ifdef MACBINARY -+ if (rd_flag("macbinary")) handlemacb = def_int; -+#endif -+#ifdef HAVE_MGCSFX -+ if (rd_flag("mgcsfx")) mgcsfx = def_int; -+#endif - if (rd_flag("mono")) mono = def_int; - if (rd_str ("monofont")) monofontname = def_str; - if (rd_int ("ncols")) ncols = def_int; - if (rd_flag("ninstall")) ninstall = def_int; - if (rd_flag("nodecor")) nodecor = def_int; - if (rd_flag("nolimits")) nolimits = def_int; -+#ifdef HAVE_MGCSFX -+ if (rd_flag("nomgcsfx")) nomgcsfx = def_int; -+#endif -+#if defined(HAVE_PIC) || defined(HAVE_PIC2) -+ if (rd_flag("nopicadjust")) nopicadjust = def_int; -+#endif - if (rd_flag("nopos")) nopos = def_int; - if (rd_flag("noqcheck")) noqcheck = def_int; - if (rd_flag("nostat")) nostat = def_int; - if (rd_flag("ownCmap")) owncmap = def_int; - if (rd_flag("perfect")) perfect = def_int; -+#ifdef HAVE_PIC2 -+ if (rd_flag("pic2split")) pic2split = def_int; -+#endif - if (rd_flag("popupKludge")) winCtrPosKludge = def_int; - if (rd_str ("print")) strncpy(printCmd, def_str, - (size_t) PRINTCMDLEN); -@@ -1138,6 +1338,9 @@ - if (rd_str ("textviewGeometry")) textgeom = def_str; - if (rd_flag("useStdCmap")) stdcmap = def_int; - if (rd_str ("visual")) visualstr = def_str; -+#ifdef VS_ADJUST -+ if (rd_flag("vsadjust")) vsadjust = def_int; -+#endif - if (rd_flag("vsDisable")) novbrowse = def_int; - if (rd_str ("vsGeometry")) browgeom = def_str; - if (rd_flag("vsMap")) browmap = def_int; -@@ -1172,7 +1375,13 @@ - } - - if (numnames<MAXNAMES) { -+#ifdef AUTO_EXPAND -+ if(Isarchive(argv[i]) == 0){ /* Not archive file */ -+ namelist[numnames++] = argv[i]; -+ } -+#else - namelist[numnames++] = argv[i]; -+#endif - if (numnames==MAXNAMES) { - fprintf(stderr,"%s: too many filenames. Only using first %d.\n", - cmd, MAXNAMES); -@@ -1198,6 +1407,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; - -@@ -1289,7 +1506,11 @@ - else if (!argcmp(argv[i],"-fg",3,0,&pm)) /* fg color */ - { if (++i<argc) fgstr = argv[i]; } - -- else if (!argcmp(argv[i],"-fixed",3,1,&fixedaspect)); /* fix asp. ratio */ -+ else if (!argcmp(argv[i],"-fixed",5,1,&fixedaspect)); /* fix asp. ratio */ -+ -+#ifdef ENABLE_FIXPIX_SMOOTH -+ else if (!argcmp(argv[i],"-fixpix",5,1,&do_fixpix_smooth)); /* dithering */ -+#endif - - else if (!argcmp(argv[i],"-flist",3,0,&pm)) /* file list */ - { if (++i<argc) flistName = argv[i]; } -@@ -1330,6 +1551,10 @@ - { if (++i<argc) infogeom = argv[i]; } - - else if (!argcmp(argv[i],"-imap", 3,1,&imap)); /* imap */ -+ -+ else if (!argcmp(argv[i],"-ibg",3,0,&pm)) /* GRR: image background color */ -+ { if (++i<argc) imagebgstr = argv[i]; } -+ - else if (!argcmp(argv[i],"-lbrowse", 3,1,&browseMode)); /* browse mode */ - - else if (!argcmp(argv[i],"-lo",3,0,&pm)) /* lowlight */ -@@ -1354,9 +1579,17 @@ - else if (!argcmp(argv[i],"-maxpect",5,1,&pm)) /* auto maximize */ - { automax=pm; fixedaspect=pm; } - -+#ifdef MACBINARY -+ else if (!argcmp(argv[i],"-macbinary",3,1,&handlemacb)); /* macbinary */ -+#endif -+ - else if (!argcmp(argv[i],"-mfn",3,0,&pm)) /* mono font name */ - { if (++i<argc) monofontname = argv[i]; } - -+#ifdef HAVE_MGCSFX -+ else if (!argcmp(argv[i],"-mgcsfx", 4,1,&mgcsfx)); /* mgcsfx */ -+#endif -+ - else if (!argcmp(argv[i],"-mono",3,1,&mono)); /* mono */ - - else if (!argcmp(argv[i],"-name",3,0,&pm)) /* name */ -@@ -1365,17 +1598,30 @@ - else if (!argcmp(argv[i],"-ncols",3,0,&pm)) /* ncols */ - { if (++i<argc) ncols=abs(atoi(argv[i])); } - -- else if (!argcmp(argv[i],"-ninstall", 3,1,&ninstall)); /* inst cmaps?*/ -+ else if (!argcmp(argv[i],"-ninstall", 3,1,&ninstall)); /* inst cmaps? */ - else if (!argcmp(argv[i],"-nodecor", 4,1,&nodecor)); - else if (!argcmp(argv[i],"-nofreecols",4,1,&noFreeCols)); - else if (!argcmp(argv[i],"-nolimits", 4,1,&nolimits)); /* nolimits */ -+#ifdef HAVE_MGCSFX -+ else if (!argcmp(argv[i],"-nomgcsfx", 4,1,&nomgcsfx)); /* nomgcsfx */ -+#endif -+#if defined(HAVE_PIC) || defined(HAVE_PIC2) -+ else if (!argcmp(argv[i],"-nopicadjust", 4,1,&nopicadjust));/*nopicadjust*/ -+#endif - else if (!argcmp(argv[i],"-nopos", 4,1,&nopos)); /* nopos */ - else if (!argcmp(argv[i],"-noqcheck", 4,1,&noqcheck)); /* noqcheck */ -- else if (!argcmp(argv[i],"-noresetroot",5,1,&resetroot)); /* reset root*/ -+ else if (!argcmp(argv[i],"-noresetroot",5,1,&resetroot)); /* reset root */ - 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 */ -+#ifdef HAVE_PCD -+ else if (!argcmp(argv[i],"-pcd", 4,0,&pm)) /* pcd with size */ -+ { if (i+1<argc) PcdSize = atoi(argv[++i]); } -+#endif - else if (!argcmp(argv[i],"-perfect", 3,1,&perfect)); /* -perfect */ -+#ifdef HAVE_PIC2 -+ else if (!argcmp(argv[i],"-pic2split", 3,1,&pic2split)); /* pic2split */ -+#endif - else if (!argcmp(argv[i],"-pkludge", 3,1,&winCtrPosKludge)); - else if (!argcmp(argv[i],"-poll", 3,1,&polling)); /* chk mod? */ - -@@ -1418,6 +1664,7 @@ - conv24 = CONV24_SLOW; - - else if (!argcmp(argv[i],"-smooth",3,1,&autosmooth)); /* autosmooth */ -+ else if (!argcmp(argv[i],"-startgrab",3,1,&startGrab)); /* startGrab */ - else if (!argcmp(argv[i],"-stdcmap",3,1,&stdcmap)); /* use stdcmap */ - - else if (!argcmp(argv[i],"-tgeometry",2,0,&pm)) /* textview geom */ -@@ -1429,6 +1676,10 @@ - else if (!argcmp(argv[i],"-visual",4,0,&pm)) /* visual */ - { if (++i<argc) visualstr = argv[i]; } - -+#ifdef VS_ADJUST -+ else if (!argcmp(argv[i],"-vsadjust", 3,1,&vsadjust)); /* vsadjust */ -+#endif -+ - else if (!argcmp(argv[i],"-vsdisable",4,1,&novbrowse)); /* disable sch? */ - - else if (!argcmp(argv[i],"-vsgeometry",4,0,&pm)) /* visSchnauzer geom */ -@@ -1440,8 +1691,9 @@ - - else if (!argcmp(argv[i],"-wait",3,0,&pm)) { /* secs betwn pics */ - if (++i<argc) { -- waitsec = abs(atoi(argv[i])); -- if (waitsec<0) waitsec = 0; -+ char *comma = strchr(argv[i], ','); -+ waitsec_nonfinal = fabs(atof(argv[i])); -+ waitsec_final = comma? fabs(atof(comma+1)) : waitsec_nonfinal; - } - } - -@@ -1467,7 +1719,11 @@ - /* check options for validity */ - - if (strlen(searchdir)) { /* got a search directory */ -+#ifdef AUTO_EXPAND -+ if (Chvdir(searchdir)) { -+#else - if (chdir(searchdir)) { -+#endif - fprintf(stderr,"xv: unable to cd to directory '%s'.\n",searchdir); - fprintf(stderr, - " Ignoring '-dir' option and/or 'xv.searchDirectory' resource\n"); -@@ -1514,7 +1770,7 @@ - preset = 0; - } - -- if (waitsec < 0) noFreeCols = 0; /* disallow nfc if not doing slideshow */ -+ if (waitsec < 0.0) noFreeCols = 0; /* disallow nfc if not doing slideshow */ - if (noFreeCols && perfect) { perfect = 0; owncmap = 1; } - - /* decide what default color allocation stuff we've settled on */ -@@ -1556,6 +1812,20 @@ - - static void cmdSyntax() - { -+ /* GRR 19980605: added version info for most common libraries */ -+ fprintf(stderr, "XV - %s.\n", REVDATE); -+#ifdef HAVE_JPEG -+ VersionInfoJPEG(); -+#endif -+#ifdef HAVE_TIFF -+ VersionInfoTIFF(); -+#endif -+#ifdef HAVE_PNG -+ VersionInfoPNG(); -+#endif -+ /* pbm/pgm/ppm support is native, not via pbmplus/netpbm libraries */ -+ fprintf(stderr, "\n"); -+ - fprintf(stderr, "Usage:\n"); - printoption(cmd); - printoption("[-]"); -@@ -1595,6 +1865,9 @@ - printoption("[-expand exp | hexp:vexp]"); - printoption("[-fg color]"); - printoption("[-/+fixed]"); -+#ifdef ENABLE_FIXPIX_SMOOTH -+ printoption("[-/+fixpix]"); -+#endif - printoption("[-flist fname]"); - printoption("[-gamma val]"); - printoption("[-geometry geom]"); -@@ -1607,6 +1880,7 @@ - printoption("[-hi color]"); - printoption("[-/+hist]"); - printoption("[-/+hsv]"); -+ printoption("[-ibg color]"); /* GRR 19980314 */ - printoption("[-icgeometry geom]"); - printoption("[-/+iconic]"); - printoption("[-igeometry geom]"); -@@ -1614,9 +1888,15 @@ - printoption("[-/+lbrowse]"); - printoption("[-lo color]"); - printoption("[-/+loadclear]"); -+#ifdef MACBINARY -+ printoption("[-/+macbinary]"); -+#endif - printoption("[-/+max]"); - printoption("[-/+maxpect]"); - printoption("[-mfn font]"); -+#ifdef HAVE_MGCSFX -+ printoption("[-/+mgcsfx]"); -+#endif - printoption("[-/+mono]"); - printoption("[-name str]"); - printoption("[-ncols #]"); -@@ -1624,13 +1904,25 @@ - printoption("[-/+nodecor]"); - printoption("[-/+nofreecols]"); - printoption("[-/+nolimits]"); -+#ifdef HAVE_MGCSFX -+ printoption("[-/+nomgcsfx]"); -+#endif -+#if defined(HAVE_PIC) || defined(HAVE_PIC2) -+ printoption("[-/+nopicadjust]"); -+#endif - printoption("[-/+nopos]"); - printoption("[-/+noqcheck]"); - printoption("[-/+noresetroot]"); - printoption("[-/+norm]"); - printoption("[-/+nostat]"); - printoption("[-/+owncmap]"); -+#ifdef HAVE_PCD -+ printoption("[-pcd size(0=192*128,1,2,3,4=3072*2048)]"); -+#endif - printoption("[-/+perfect]"); -+#ifdef HAVE_PIC2 -+ printoption("[-/+pic2split]"); -+#endif - printoption("[-/+pkludge]"); - printoption("[-/+poll]"); - printoption("[-preset #]"); -@@ -1649,17 +1941,22 @@ - printoption("[-/+rw]"); - printoption("[-slow24]"); - printoption("[-/+smooth]"); -+ printoption("[-/+startgrab]"); - printoption("[-/+stdcmap]"); - printoption("[-tgeometry geom]"); - printoption("[-/+vflip]"); - printoption("[-/+viewonly]"); - printoption("[-visual type]"); -+#ifdef VS_ADJUST -+ printoption("[-/+vsadjust]"); -+#endif - printoption("[-/+vsdisable]"); - printoption("[-vsgeometry geom]"); - printoption("[-/+vsmap]"); - printoption("[-/+vsperfect]"); -- printoption("[-wait seconds]"); -+ printoption("[-wait secs[,final_secs]]"); - printoption("[-white color]"); -+ printoption("[-windowid windowid]"); - printoption("[-/+wloop]"); - printoption("[filename ...]"); - fprintf(stderr,"\n\n"); -@@ -1682,6 +1979,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); - } -@@ -1694,7 +1992,7 @@ - int *plusminus; - { - /* does a string compare between a1 and a2. To return '0', a1 and a2 -- must match to the length of a2, and that length has to -+ must match to the length of a1, and that length has to - be at least 'minlen'. Otherwise, return non-zero. plusminus set to '1' - if '-option', '0' if '+option' */ - -@@ -1734,6 +2032,10 @@ - char *tmp; - char *fullname, /* full name of the original file */ - filename[512]; /* full name of file to load (could be /tmp/xxx)*/ -+#ifdef MACBINARY -+ char origname[512]; /* file name of original file (NO processing) */ -+ origname[0] = '\0'; -+#endif - - xvbzero((char *) &pinfo, sizeof(PICINFO)); - -@@ -1866,8 +2168,22 @@ - frompipe = 1; - } - } -+#ifdef AUTO_EXPAND -+ else { -+ fullname = (char *) malloc(MAXPATHLEN+2); -+ strcpy(fullname, namelist[filenum]); -+ freename = 1; -+ } -+ tmp = (char *) rindex(fullname, '/'); -+ if (tmp) { -+ *tmp = '\0'; -+ Mkvdir(fullname); -+ *tmp = '/'; -+ } -+ Dirtovd(fullname); -+#else - else fullname = namelist[filenum]; -- -+#endif - - strcpy(fullfname, fullname); - tmp = BaseName(fullname); -@@ -1875,18 +2191,20 @@ - - - /* chop off trailing ".Z", ".z", or ".gz" from displayed basefname, if any */ -- if (strlen(basefname) > (size_t) 2 && -- strcmp(basefname+strlen(basefname)-2,".Z")==0) -+ if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".Z")==0) - basefname[strlen(basefname)-2]='\0'; - else { - #ifdef GUNZIP -- if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".Z")==0) -+ if (strlen(basefname)>2 && strcmp(basefname+strlen(basefname)-2,".z")==0) - basefname[strlen(basefname)-2]='\0'; -- -- else if (strlen(basefname)>3 && -- strcmp(basefname+strlen(basefname)-3,".gz")==0) -+ else -+ if (strlen(basefname)>3 && strcmp(basefname+strlen(basefname)-3,".gz")==0) - basefname[strlen(basefname)-3]='\0'; --#endif /* GUNZIP */ -+#endif -+#ifdef BUNZIP2 -+ if (strlen(basefname)>4 && strcmp(basefname+strlen(basefname)-4,".bz2")==0) -+ basefname[strlen(basefname)-4]='\0'; -+#endif - } - - -@@ -1973,6 +2291,9 @@ - - if (strcmp(filename,STDINSTR)==0) { - FILE *fp = NULL; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif - - #ifndef VMS - sprintf(filename,"%s/xvXXXXXX",tmpdir); -@@ -1984,13 +2305,18 @@ - fp = fdopen(mkstemp(filename), "w"); - #else - mktemp(filename); -- fp = fopen(filename, "w"); -+ tmpfd = open(filename,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) FatalError("openPic(): can't create temporary file"); -+ fp = fdopen(tmpfd,"w"); - #endif - if (!fp) FatalError("openPic(): can't write temporary file"); - - clearerr(stdin); - while ( (i=getchar()) != EOF) putc(i,fp); - fclose(fp); -+#ifndef USE_MKSTEMP -+ close(tmpfd); -+#endif - - /* and remove it from list, since we can never reload from stdin */ - if (strcmp(namelist[0], STDINSTR)==0) deleteFromList(0); -@@ -2005,15 +2331,21 @@ - (no pipes or stdin, though it could be compressed) to be loaded */ - filetype = ReadFileType(filename); - -+#ifdef HAVE_MGCSFX -+ if (mgcsfx && filetype == RFT_UNKNOWN){ /* force use MgcSfx */ -+ if(getInputCom() != 0) filetype = RFT_MGCSFX; -+ } -+#endif - -- if (filetype == RFT_COMPRESS) { /* a compressed file. uncompress it */ -+ /* if it's a compressed file, uncompress it: */ -+ if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) { - char tmpname[128]; - - if ( - #ifndef VMS -- UncompressFile(filename, tmpname) -+ UncompressFile(filename, tmpname, filetype) - #else -- UncompressFile(basefname, tmpname) -+ UncompressFile(basefname, tmpname, filetype) - #endif - ) { - -@@ -2029,6 +2361,57 @@ - WaitCursor(); - } - -+#ifdef MACBINARY -+ if (handlemacb && macb_file == True) { -+ char tmpname[128]; -+ -+ if (RemoveMacbinary(filename, tmpname)) { -+ if (strcmp(fullname,filename)!=0) unlink(filename); -+ strcpy(origname, filename); -+ strcpy(filename, tmpname); -+ } -+ else filetype = RFT_ERROR; -+ -+ WaitCursor(); -+ } -+#endif -+ -+#ifdef HAVE_MGCSFX_AUTO -+ if (filetype == RFT_MGCSFX) { -+ char tmpname[128], tmp[256]; -+ char *icom; -+ -+ if ((icom = mgcsfx_auto_input_com(filename)) != NULL) { -+ sprintf(tmpname, "%s/xvmsautoXXXXXX", tmpdir); -+#ifdef USE_MKSTEMP -+ close(mkstemp(tmpname)); -+#else -+ mktemp(tmpname); -+#endif -+ SetISTR(ISTR_INFO, "Converting to known format by MgcSfx auto..."); -+ sprintf(tmp,"%s >%s", icom, tmpname); -+ } -+ else goto ms_auto_no; -+ -+#ifndef VMS -+ if (system(tmp)) -+#else -+ if (!system(tmp)) -+#endif -+ { -+ SetISTR(ISTR_INFO, "Unable to convert '%s' by MgcSfx auto.", -+ BaseName(filename)); -+ Warning(); -+ filetype = RFT_ERROR; -+ goto ms_auto_no; -+ } -+ -+ filetype = ReadFileType(tmpname); -+ if (strcmp(fullname,filename)!=0) unlink(filename); -+ strcpy(filename, tmpname); -+ } -+ms_auto_no: -+#endif /* HAVE_MGCSFX_AUTO */ - - if (filetype == RFT_ERROR) { - char foostr[512]; -@@ -2042,10 +2425,16 @@ - - if (filetype == RFT_UNKNOWN) { - /* view as a text/hex file */ -- TextView(filename); -+#ifdef MACBINARY -+ if (origname[0]) -+ i = TextView(origname); -+ else -+#endif -+ i = TextView(filename); - SetISTR(ISTR_INFO,"'%s' not in a recognized format.", basefname); - /* Warning(); */ -- goto SHOWN_AS_TEXT; -+ if (i) goto SHOWN_AS_TEXT; -+ else goto FAILED; - } - - if (filetype < RFT_ERROR) { -@@ -2073,8 +2462,9 @@ - if (filetype == RFT_XBM && (!i || pinfo.w==0 || pinfo.h==0)) { - /* probably just a '.h' file or something... */ - SetISTR(ISTR_INFO," "); -- TextView(filename); -- goto SHOWN_AS_TEXT; -+ i = TextView(filename); -+ if (i) goto SHOWN_AS_TEXT; -+ else goto FAILED; - } - - if (!i) { -@@ -2209,12 +2599,15 @@ - if (fullname && strcmp(fullname,filename)!=0) unlink(filename); - - -- SetISTR(ISTR_INFO,formatStr); -+ SetISTR(ISTR_INFO, "%s", formatStr); - - SetInfoMode(INF_PART); -- SetISTR(ISTR_FILENAME, "%s", -- (filenum==DFLTPIC || filenum==GRABBED || frompipe) ? -- "<none>" : basefname); -+ if (filenum==DFLTPIC || filenum==GRABBED || frompipe) -+ SetISTR(ISTR_FILENAME, "<none>"); -+ else if (numPages > 1) -+ SetISTR(ISTR_FILENAME, "%s Page %d of %d", basefname, curPage+1, numPages); -+ else -+ SetISTR(ISTR_FILENAME, "%s", basefname); - - SetISTR(ISTR_RES,"%d x %d",pWIDE,pHIGH); - SetISTR(ISTR_COLOR, ""); -@@ -2424,7 +2817,7 @@ - if (autodither && ncols>0) epicMode = EM_DITH; - - /* if in CM_STDCMAP mode, and *not* in '-wait 0', then autodither */ -- if (colorMapMode == CM_STDCMAP && waitsec != 0) epicMode = EM_DITH; -+ if (colorMapMode == CM_STDCMAP && waitsec != 0.0) epicMode = EM_DITH; - - /* if -smooth or image has been shrunk to fit screen */ - if (autosmooth || (pWIDE >maxWIDE || pHIGH>maxHIGH) -@@ -2510,7 +2903,11 @@ - to generate the correct exposes (particularly with 'BitGravity' turned - on */ - -- if (mainW && !useroot) GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH); -+ /*Brian T. Schellenberger: fix for X 4.2 refresh problem*/ -+ if (mainW && !useroot) { -+ XSync(theDisp, False); -+ GenExpose(mainW, 0, 0, (u_int) eWIDE, (u_int) eHIGH); -+ } - - return 1; - -@@ -2542,6 +2939,9 @@ - } - - -+extern byte ZXheader[128]; /* [JCE] Spectrum screen magic number is -+ defined in xvzx.c */ -+ - - /********************************/ - int ReadFileType(fname) -@@ -2554,76 +2954,105 @@ - - FILE *fp; - byte magicno[30]; /* first 30 bytes of file */ -- int rv, n; -+ int rv=RFT_UNKNOWN, n; -+#ifdef MACBINARY -+ int macbin_alrchk = False; -+#endif - - if (!fname) return RFT_ERROR; /* shouldn't happen */ - - fp = xv_fopen(fname, "r"); - if (!fp) return RFT_ERROR; - -+ if (strlen(fname) > 4 && -+ strcasecmp(fname+strlen(fname)-5, ".wbmp")==0) rv = RFT_WBMP; -+ - n = fread(magicno, (size_t) 1, (size_t) 30, fp); - fclose(fp); - -- if (n<30) return RFT_UNKNOWN; /* files less than 30 bytes long... */ -+ if (n<30) return rv; /* files less than 30 bytes long... */ - -- rv = RFT_UNKNOWN; -+#ifdef MACBINARY -+ macb_file = False; -+ while (1) { -+#endif - -- if (strncmp((char *) magicno,"GIF87a", (size_t) 6)==0 || -- strncmp((char *) magicno,"GIF89a", (size_t) 6)==0) rv = RFT_GIF; -+#ifdef HAVE_MGCSFX -+ if (is_mgcsfx(fname, magicno, 30) != 0) rv = RFT_MGCSFX; -+ else -+#endif -+ if (strncmp((char *) magicno,"GIF87a", (size_t) 6)==0 || -+ strncmp((char *) magicno,"GIF89a", (size_t) 6)==0) rv = RFT_GIF; - - else if (strncmp((char *) magicno,"VIEW", (size_t) 4)==0 || -- strncmp((char *) magicno,"WEIV", (size_t) 4)==0) rv = RFT_PM; -+ strncmp((char *) magicno,"WEIV", (size_t) 4)==0) rv = RFT_PM; -+ -+#ifdef HAVE_PIC2 -+ else if (magicno[0]=='P' && magicno[1]=='2' && -+ magicno[2]=='D' && magicno[3]=='T') rv = RFT_PIC2; -+#endif - - else if (magicno[0] == 'P' && magicno[1]>='1' && -- magicno[1]<='6') rv = RFT_PBM; -+ (magicno[1]<='6' || magicno[1]=='8')) rv = RFT_PBM; - - /* note: have to check XPM before XBM, as first 2 chars are the same */ - else if (strncmp((char *) magicno, "/* XPM */", (size_t) 9)==0) rv = RFT_XPM; - - else if (strncmp((char *) magicno,"#define", (size_t) 7)==0 || -- (magicno[0] == '/' && magicno[1] == '*')) rv = RFT_XBM; -+ (magicno[0] == '/' && magicno[1] == '*')) rv = RFT_XBM; - - else if (magicno[0]==0x59 && (magicno[1]&0x7f)==0x26 && -- magicno[2]==0x6a && (magicno[3]&0x7f)==0x15) rv = RFT_SUNRAS; -+ magicno[2]==0x6a && (magicno[3]&0x7f)==0x15) rv = RFT_SUNRAS; - -- else if (magicno[0] == 'B' && magicno[1] == 'M') rv = RFT_BMP; -+ else if (magicno[0] == 'B' && magicno[1] == 'M') rv = RFT_BMP; - -- else if (magicno[0]==0x52 && magicno[1]==0xcc) rv = RFT_UTAHRLE; -+ else if (magicno[0]==0x52 && magicno[1]==0xcc) rv = RFT_UTAHRLE; - - else if ((magicno[0]==0x01 && magicno[1]==0xda) || -- (magicno[0]==0xda && magicno[1]==0x01)) rv = RFT_IRIS; -+ (magicno[0]==0xda && magicno[1]==0x01)) rv = RFT_IRIS; - -- else if (magicno[0]==0x1f && magicno[1]==0x9d) rv = RFT_COMPRESS; -+ else if (magicno[0]==0x1f && magicno[1]==0x9d) rv = RFT_COMPRESS; - - #ifdef GUNZIP -- else if (magicno[0]==0x1f && magicno[1]==0x8b) rv = RFT_COMPRESS; -+ else if (magicno[0]==0x1f && magicno[1]==0x8b) rv = RFT_COMPRESS; - #endif - -- else if (magicno[0]==0x0a && magicno[1] <= 5) rv = RFT_PCX; -+#ifdef BUNZIP2 -+ else if (magicno[0]==0x42 && magicno[1]==0x5a) rv = RFT_BZIP2; -+#endif -+ -+ else if (magicno[0]==0x0a && magicno[1] <= 5) rv = RFT_PCX; - - else if (strncmp((char *) magicno, "FORM", (size_t) 4)==0 && -- strncmp((char *) magicno+8, "ILBM", (size_t) 4)==0) rv = RFT_IFF; -+ strncmp((char *) magicno+8, "ILBM", (size_t) 4)==0) rv = RFT_IFF; - - else if (magicno[0]==0 && magicno[1]==0 && - magicno[2]==2 && magicno[3]==0 && - magicno[4]==0 && magicno[5]==0 && -- magicno[6]==0 && magicno[7]==0) rv = RFT_TARGA; -+ magicno[6]==0 && magicno[7]==0) rv = RFT_TARGA; - - else if (magicno[4]==0x00 && magicno[5]==0x00 && -- magicno[6]==0x00 && magicno[7]==0x07) rv = RFT_XWD; -+ magicno[6]==0x00 && magicno[7]==0x07) rv = RFT_XWD; - - else if (strncmp((char *) magicno,"SIMPLE ", (size_t) 8)==0 && -- magicno[29] == 'T') rv = RFT_FITS; -+ magicno[29] == 'T') rv = RFT_FITS; - -+ /* [JCE] Spectrum screen */ -+ else if (memcmp(magicno, ZXheader, (size_t) 18)==0) rv = RFT_ZX; - - #ifdef HAVE_JPEG - else if (magicno[0]==0xff && magicno[1]==0xd8 && -- magicno[2]==0xff) rv = RFT_JFIF; -+ magicno[2]==0xff) rv = RFT_JFIF; - #endif - - #ifdef HAVE_TIFF - else if ((magicno[0]=='M' && magicno[1]=='M') || -- (magicno[0]=='I' && magicno[1]=='I')) rv = RFT_TIFF; -+ (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 -@@ -2635,11 +3064,59 @@ - rv = RFT_PDSVICAR; - #endif - --#ifdef GS_PATH -+#ifdef GS_PATH /* Ghostscript handles both PostScript and PDF */ - else if (strncmp((char *) magicno, "%!", (size_t) 2)==0 || -- strncmp((char *) magicno, "\004%!", (size_t) 3)==0) rv = RFT_PS; -+ strncmp((char *) magicno, "\004%!", (size_t) 3)==0 || -+ strncmp((char *) magicno, "%PDF", (size_t) 4)==0) rv = RFT_PS; - #endif - -+#ifdef HAVE_MAG -+ else if (strncmp((char *) magicno,"MAKI02 ", (size_t) 8)==0) rv = RFT_MAG; -+#endif -+ -+#ifdef HAVE_MAKI -+ else if (strncmp((char *) magicno,"MAKI01A ", (size_t) 8)==0 || -+ strncmp((char *) magicno,"MAKI01B ", (size_t) 8)==0) rv = RFT_MAKI; -+#endif -+ -+#ifdef HAVE_PIC -+ else if (magicno[0]=='P' && magicno[1]=='I'&&magicno[2]=='C') rv = RFT_PIC; -+#endif -+ -+#ifdef HAVE_PI -+ else if (magicno[0]=='P' && magicno[1]=='i') rv = RFT_PI; -+#endif -+ -+#ifdef HAVE_HIPS -+ else if (strstr((char *) magicno, "./digest")) rv = RFT_HIPS; -+#endif -+ -+#ifdef HAVE_PCD -+ else if (magicno[0]==0xff && magicno[1]==0xff && -+ magicno[2]==0xff && magicno[3]==0xff) rv = RFT_PCD; -+#endif -+ -+#ifdef MACBINARY -+ /* Now we try to handle MacBinary files, but the method is VERY dirty... */ -+ if (macbin_alrchk == True) { -+ macb_file = True; -+ break; -+ } -+ -+ if (rv != RFT_UNKNOWN) -+ break; -+ -+ /* Skip MACBSIZE and recheck */ -+ macbin_alrchk = True; -+ fp = xv_fopen(fname, "r"); -+ if (!fp) return RFT_ERROR; -+ fseek(fp, MACBSIZE, SEEK_SET); -+ n = fread(magicno, (size_t) 1, (size_t) 30, fp); -+ fclose(fp); -+ -+ if (n<30) return RFT_UNKNOWN; /* files less than 30 bytes long... */ -+ } -+#endif - return rv; - } - -@@ -2652,9 +3129,10 @@ - PICINFO *pinfo; - { - /* 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 */ -+ like that. We should load the image as quickly as possible. Previously, -+ this affected only the LoadPS routine, which, if quick is set, only -+ generates the page file for the first page of the document. Now it -+ also affects PCD, which loads only a thumbnail. */ - - int rv = 0; - -@@ -2665,7 +3143,11 @@ - switch (ftype) { - case RFT_GIF: rv = LoadGIF (fname, pinfo); break; - case RFT_PM: rv = LoadPM (fname, pinfo); break; -+#ifdef HAVE_MGCSFX -+ case RFT_PBM: rv = LoadPBM (fname, pinfo, -1); break; -+#else - case RFT_PBM: rv = LoadPBM (fname, pinfo); break; -+#endif - case RFT_XBM: rv = LoadXBM (fname, pinfo); break; - case RFT_SUNRAS: rv = LoadSunRas(fname, pinfo); break; - case RFT_BMP: rv = LoadBMP (fname, pinfo); break; -@@ -2677,21 +3159,60 @@ - case RFT_XPM: rv = LoadXPM (fname, pinfo); break; - case RFT_XWD: rv = LoadXWD (fname, pinfo); break; - case RFT_FITS: rv = LoadFITS (fname, pinfo, quick); break; -+ case RFT_ZX: rv = LoadZX (fname, pinfo); break; /* [JCE] */ -+ case RFT_WBMP: rv = LoadWBMP (fname, pinfo); break; -+ -+#ifdef HAVE_PCD -+ /* if quick is switched on, use the smallest image size; don't ask the user */ -+ case RFT_PCD: rv = LoadPCD (fname, pinfo, quick ? 0 : PcdSize); break; -+#endif - - #ifdef HAVE_JPEG -- case RFT_JFIF: rv = LoadJFIF (fname, pinfo, quick); break; -+ case RFT_JFIF: rv = LoadJFIF (fname, pinfo, quick); break; - #endif - - #ifdef HAVE_TIFF -- case RFT_TIFF: rv = LoadTIFF (fname, pinfo, quick); 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 -- case RFT_PDSVICAR: rv = LoadPDS (fname, pinfo); break; -+ case RFT_PDSVICAR: rv = LoadPDS (fname, pinfo); break; - #endif - - #ifdef GS_PATH -- case RFT_PS: rv = LoadPS (fname, pinfo, quick); break; -+ case RFT_PS: rv = LoadPS (fname, pinfo, quick); break; -+#endif -+ -+#ifdef HAVE_MAG -+ case RFT_MAG: rv = LoadMAG (fname, pinfo); break; -+#endif -+ -+#ifdef HAVE_MAKI -+ case RFT_MAKI: rv = LoadMAKI (fname, pinfo); break; -+#endif -+ -+#ifdef HAVE_PIC -+ case RFT_PIC: rv = LoadPIC (fname, pinfo); break; -+#endif -+ -+#ifdef HAVE_PI -+ case RFT_PI: rv = LoadPi (fname, pinfo); break; -+#endif -+ -+#ifdef HAVE_PIC2 -+ case RFT_PIC2: rv = LoadPIC2 (fname, pinfo, quick); break; -+#endif -+ -+#ifdef HAVE_HIPS -+ case RFT_HIPS: rv = LoadHIPS (fname, pinfo); break; -+#endif -+ -+#ifdef HAVE_MGCSFX -+ case RFT_MGCSFX: rv = LoadMGCSFX (fname, pinfo); break; - #endif - - } -@@ -2700,13 +3221,17 @@ - - - /********************************/ --int UncompressFile(name, uncompname) -+int UncompressFile(name, uncompname, filetype) - char *name, *uncompname; -+ int filetype; - { - /* returns '1' on success, with name of uncompressed file in uncompname - returns '0' on failure */ - - char namez[128], *fname, buf[512]; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif - - fname = name; - namez[0] = '\0'; -@@ -2746,15 +3271,23 @@ - close(mkstemp(uncompname)); - #else - mktemp(uncompname); -+ tmpfd = open(uncompname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) FatalError("UncompressFile(): can't create temporary file"); -+ close(tmpfd); - #endif - - #ifndef VMS -- sprintf(buf,"%s -c %s >%s", UNCOMPRESS, fname, uncompname); -+ if (filetype == RFT_COMPRESS) -+ sprintf(buf,"%s -c '%s' > '%s'", UNCOMPRESS, fname, uncompname); -+# ifdef BUNZIP2 -+ else if (filetype == RFT_BZIP2) -+ sprintf(buf,"%s -c '%s' > '%s'", BUNZIP2, fname, uncompname); -+# endif - #else /* it IS VMS */ - # ifdef GUNZIP -- sprintf(buf,"%s %s %s", UNCOMPRESS, fname, uncompname); -+ sprintf(buf,"%s '%s' '%s'", UNCOMPRESS, fname, uncompname); - # else -- sprintf(buf,"%s %s", UNCOMPRESS, fname); -+ sprintf(buf,"%s '%s'", UNCOMPRESS, fname); - # endif - #endif - -@@ -2797,6 +3330,62 @@ - } - - -+#ifdef MACBINARY -+/********************************/ -+int RemoveMacbinary(src, dst) -+ char *src, *dst; -+{ -+ char buffer[8192]; /* XXX */ -+ int n, eof; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif -+ FILE *sfp, *dfp; -+ -+ sprintf(dst, "%s/xvmXXXXXX", tmpdir); -+#ifdef USE_MKSTEMP -+ close(mkstemp(dst)); -+#else -+ mktemp(dst); -+ tmpfd = open(dst,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) FatalError("RemoveMacbinary(): can't create temporary file"); -+#endif -+ -+ SetISTR(ISTR_INFO, "Removing MacBinary..."); -+ -+ sfp = xv_fopen(src, "r"); -+#ifdef USE_MKSTEMP -+ dfp = xv_fopen(dst, "w"); -+#else -+ dfp = fdopen(tmpfd, "w"); -+#endif -+ if (!sfp || !dfp) { -+ SetISTR(ISTR_INFO, "Unable to remove a InfoFile header form '%s'.", src); -+ Warning(); -+ return 0; -+ } -+ fseek(sfp, MACBSIZE, SEEK_SET); -+ while ((n = fread(buffer, 1, sizeof(buffer), sfp)) == 8192) /* XXX */ -+ fwrite(buffer, 1, n, dfp); -+ if ((eof = feof(sfp))) -+ fwrite(buffer, 1, n, dfp); -+ fclose(sfp); -+ fflush(dfp); -+ fclose(dfp); -+#ifndef USE_MKSTEMP -+ close(tmpfd); -+#endif -+ if (!eof) { -+ SetISTR(ISTR_INFO, "Unable to remove a InfoFile header form '%s'.", src); -+ Warning(); -+ return 0; -+ } -+ -+ return 1; -+} -+#endif -+ -+ - /********************************/ - void KillPageFiles(bname, numpages) - char *bname; -@@ -2918,6 +3507,9 @@ - - char fullcmd[512], tmpname[64], str[512]; - int i; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif - - if (!cmd || (strlen(cmd) < (size_t) 2)) return 1; - -@@ -2926,6 +3518,9 @@ - close(mkstemp(tmpname)); - #else - mktemp(tmpname); -+ tmpfd = open(tmpname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) FatalError("openPic(): can't create temporary file"); -+ close(tmpfd); - #endif - if (tmpname[0] == '\0') { /* mktemp() or mkstemp() blew up */ - sprintf(str,"Unable to create temporary filename."); -@@ -2966,26 +3561,21 @@ - { - int i; - -+ waitsec = (numnames <= 1)? waitsec_final : waitsec_nonfinal; -+ - if (!numnames) { openPic(DFLTPIC); return; } - - i = 0; -- if (!randomShow) { -- while (numnames>0) { -- if (openPic(0)) return; /* success */ -- else { -- if (polling && !i) -- fprintf(stderr,"%s: POLLING: Waiting for file '%s' \n\tto %s\n", -- cmd, namelist[0], "be created, or whatever..."); -- i = 1; -- } -+ while (numnames>0) { -+ if (openPic(0)) return; /* success */ -+ else { -+ if (polling && !i) -+ fprintf(stderr,"%s: POLLING: Waiting for file '%s' \n\tto %s\n", -+ cmd, namelist[0], "be created, or whatever..."); -+ i = 1; - } - } - -- else { /* pick random first picture */ -- for (i=findRandomPic(); i>=0; i=findRandomPic()) -- if (openPic(i)) return; /* success */ -- } -- - if (numnames>1) FatalError("couldn't open any pictures"); - else Quit(-1); - } -@@ -3014,19 +3604,15 @@ - { - int i; - -- if (!randomShow) { -- if (curname>=0) i = curname+1; -- else if (nList.selected >= 0 && nList.selected < numnames) -- i = nList.selected; -- else i = 0; -+ if (curname>=0) i = curname+1; -+ else if (nList.selected >= 0 && nList.selected < numnames) -+ i = nList.selected; -+ else i = 0; - -- while (i<numnames && !openPic(i)); -- if (i<numnames) return; /* success */ -- } -- else { -- for (i=findRandomPic(); i>=0; i=findRandomPic()) -- if (openPic(i)) return; -- } -+ waitsec = (i == numnames-1)? waitsec_final : waitsec_nonfinal; -+ -+ while (i<numnames && !openPic(i)); -+ if (i<numnames) return; /* success */ - - Quit(0); - } -@@ -3039,25 +3625,21 @@ - - j = loop = 0; - while (1) { -- if (!randomShow) { - -- if (curname>=0) i = curname+1; -- else if (nList.selected >= 0 && nList.selected < numnames) -- i = nList.selected; -- else i = 0; -+ if (curname>=0) i = curname+1; -+ else if (nList.selected >= 0 && nList.selected < numnames) -+ i = nList.selected; -+ else i = 0; - -- if (loop) { i = 0; loop = 0; } -+ if (loop) { i = 0; loop = 0; } - -- while (i<numnames && !openPic(i)); -- if (i<numnames) return; -- } -- else { -- for (i=findRandomPic(); i>=0; i=findRandomPic()) -- if (openPic(i)) return; -- } -+ waitsec = (i == numnames-1)? waitsec_final : waitsec_nonfinal; -+ -+ while (i<numnames && !openPic(i)); -+ if (i<numnames) return; - - loop = 1; /* back to top of list */ -- if (j) break; /* we're in a 'failure loop' */ -+ if (j) break; /* we're in a 'failure loop' */ - j++; - } - -@@ -3090,47 +3672,6 @@ - openPic(LOADPIC); - } - -- -- -- --/****************/ --static int findRandomPic() --/****************/ --{ -- static byte *loadList; -- static int left_to_load, listLen = -1; -- int k; -- time_t t; -- -- /* picks a random name out of the list, and returns it's index. If there -- are no more names to pick, it returns '-1' and resets itself */ -- -- if (!loadList || numnames!=listLen) { -- if (loadList) free(loadList); -- else { -- time(&t); -- srandom((unsigned int) t); /* seed the random */ -- } -- -- left_to_load = listLen = numnames; -- loadList = (byte *) malloc((size_t) listLen); -- for (k=0; k<listLen; k++) loadList[k] = 0; -- } -- -- if (left_to_load <= 0) { /* we've loaded all the pics */ -- for (k=0; k<listLen; k++) loadList[k] = 0; /* clear flags */ -- left_to_load = listLen; -- return -1; /* 'done' return */ -- } -- -- for (k=abs(random()) % listLen; loadList[k]; k = (k+1) % listLen); -- -- left_to_load--; -- loadList[k] = TRUE; -- -- return k; --} -- - /****************/ - static void mainLoop() - { -@@ -3144,10 +3685,11 @@ - selected file (or the 0th file, if no selection either), and 'Prev' means - view the one right before the selected file */ - -- openFirstPic(); /* find first displayable picture, exit if none */ -+ /* find first displayable picture, exit if none */ -+ if (!startGrab) openFirstPic(); - - if (!pic) { /* must've opened a text file... display dflt pic */ -- openPic(DFLTPIC); -+ if (!startGrab) openPic(DFLTPIC); - if (mainW && !useroot) RaiseTextWindows(); - } - -@@ -3224,8 +3766,16 @@ - hints.flags = 0; - if ((i&XValue || i&YValue)) hints.flags = USPosition; - -- if (i&XValue && i&XNegative) x = vrWIDE - eWIDE - abs(x); -- if (i&YValue && i&YNegative) y = vrHIGH - eHIGH - abs(y); -+ hints.win_gravity = NorthWestGravity; -+ if (i&XValue && i&XNegative) { -+ hints.win_gravity = NorthEastGravity; -+ x = vrWIDE - (eWIDE + 2 * bwidth) - abs(x); -+ } -+ if (i&YValue && i&YNegative) { -+ hints.win_gravity = (hints.win_gravity == NorthWestGravity) ? -+ SouthWestGravity : SouthEastGravity; -+ y = vrHIGH - (eHIGH + 2 * bwidth) - abs(y); -+ } - - if (x+eWIDE > vrWIDE) x = vrWIDE - eWIDE; /* keep on screen */ - if (y+eHIGH > vrHIGH) y = vrHIGH - eHIGH; -@@ -3245,7 +3795,7 @@ - hints.x = x; hints.y = y; - hints.width = eWIDE; hints.height = eHIGH; - hints.max_width = maxWIDE; hints.max_height = maxHIGH; -- hints.flags |= USSize | PMaxSize; -+ hints.flags |= USSize | PMaxSize | PWinGravity; - - xswa.bit_gravity = StaticGravity; - xswa.background_pixel = bg; -@@ -3294,10 +3844,6 @@ - } - } - -- -- XSetStandardProperties(theDisp,mainW,"","",None,NULL,0,&hints); -- setWinIconNames(name); -- - xwmh.input = True; - xwmh.flags = InputHint; - -@@ -3322,12 +3868,13 @@ - } - } - } -- XSetWMHints(theDisp, mainW, &xwmh); - - classh.res_name = "xv"; - classh.res_class = "XVroot"; -- XSetClassHint(theDisp, mainW, &classh); - -+ XmbSetWMProperties(theDisp, mainW, NULL, NULL, NULL, 0, &hints, &xwmh, -+ &classh); -+ setWinIconNames(name); - - if (nodecor) { /* turn of image window decorations (in MWM) */ - Atom mwm_wm_hints; -@@ -4070,16 +4617,30 @@ - unsigned long nitems, nleft; - byte *data; - -- i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0), -- resAtom, 0L, 1L, False, -- XA_STRING, &actType, &actFormat, &nitems, &nleft, -- (unsigned char **) &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); -- i = XGetWindowProperty(theDisp, RootWindow(theDisp, 0), resAtom, 0L, -- (long) ((nleft+4+3)/4), -- False, XA_STRING, &actType, &actFormat, -- &nitems, &nleft, (unsigned char **) &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 -ruN xv-3.10a-bugfixes/xv.h xv-3.10a-enhancements/xv.h ---- xv-3.10a-bugfixes/xv.h 2005-04-10 09:37:18.000000000 -0700 -+++ xv-3.10a-enhancements/xv.h 2005-05-01 13:32:10.000000000 -0700 -@@ -14,8 +14,9 @@ - /* GRR orig jumbo enhancements patch: 20000220 */ - /* GRR 1st public jumbo F+E patches: 20040531 */ - /* GRR 2nd public jumbo F+E patches: 20050410 */ --#define REVDATE "version 3.10a-jumboFix of 20050410" --#define VERSTR "3.10a-20050410" -+/* GRR 3rd public jumbo F+E patches: 20050501 */ -+#define REVDATE "version 3.10a-jumboFix+Enh of 20050501" -+#define VERSTR "3.10a-20050501" - - /* - * uncomment the following, and modify for your site, but only if you've -@@ -49,6 +50,10 @@ - /* START OF MACHINE-DEPENDENT CONFIGURATION INFO */ - /*************************************************/ - -+ -+#define ENABLE_FIXPIX_SMOOTH /* GRR 19980607 */ -+ -+ - /* Things to make xv more likely to just build, without the user tweaking - the makefile */ - -@@ -67,6 +72,14 @@ - # define SVR4 - #endif - -+#if defined(__sony_news) && defined(bsd43) && !defined(__bsd43) -+# define __bsd43 -+#elif defined(__sony_news) && (defined(SYSTYPE_BSD) || defined(__SYSTYPE_BSD)) && !defined(bsd43) && !defined(__bsd43) -+# define bsd43 -+# define __bsd43 -+#endif -+ -+#include <signal.h> /* for interrupt handling */ - - /* at least on Linux, the following file (1) includes sys/types.h and - * (2) defines __USE_BSD (which was not defined before here), so __linux__ -@@ -78,7 +91,9 @@ - # ifndef _LINUX_LIMITS_H - # include <linux/limits.h> - # endif --# define USLEEP -+# ifndef USLEEP -+# define USLEEP -+# endif - /* want only one or the other defined, not both: */ - # if !defined(BSDTYPES) && !defined(__USE_BSD) - # define BSDTYPES -@@ -117,6 +132,16 @@ - #endif - - -+#if defined(__sony_news) && defined(__bsd43) -+# include <unistd.h> -+#endif -+ -+ -+#if defined(__FreeBSD__) -+# include <sys/param.h> -+#endif -+ -+ - /* include files */ - #include <stdio.h> - #include <math.h> -@@ -132,9 +157,11 @@ - - #ifndef VMS - # include <errno.h> -- extern int errno; /* SHOULD be in errno.h, but often isn't */ --# if !defined(__NetBSD__) && !(defined(__linux__) && defined(__USE_BSD)) -- extern char *sys_errlist[]; /* this too... */ -+# ifndef __NetBSD__ -+# if !(defined __GLIBC__ && __GLIBC__ >= 2) -+ extern int errno; /* SHOULD be in errno.h, but often isn't */ -+ extern char *sys_errlist[]; /* this too... */ -+# endif - # endif - #endif - -@@ -203,9 +230,10 @@ - #include <X11/Xatom.h> - #include <X11/Xmd.h> - -+#ifdef TV_L10N -+# include <X11/Xlocale.h> -+#endif - --#undef SIGCHLD /* defined in both Xos.h and signal.h */ --#include <signal.h> /* for interrupt handling */ - - #include <sys/types.h> - -@@ -316,7 +344,9 @@ - # endif - #endif - -- -+#ifndef S_IRWUSR -+# define S_IRWUSR (S_IRUSR|__S_IWRITE) -+#endif - - #ifndef MAXPATHLEN - # define MAXPATHLEN 256 -@@ -343,13 +373,36 @@ - #endif - - --/* GRR 20040430: This is new and still only partially implemented. No doubt -- * there are many other systems that have mkstemp() (SUSv3), -- * but let's start small... */ --#if defined(__linux__) || defined(__OpenBSD__) --# define USE_MKSTEMP /* use 'mkstemp()' instead of 'mktemp()' */ -+/* GRR 20040430: This is new and still not fully deployed. No doubt there -+ * are other systems that have mkstemp() (SUSv3); we can add -+ * them later. */ -+#ifndef VMS /* VMS hates multi-line definitions */ -+# if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ -+ defined(__bsdi__) -+# ifndef USE_MKSTEMP -+# define USE_MKSTEMP /* use 'mkstemp()' instead of 'mktemp()' */ -+# endif /* >> SECURITY ISSUE << */ -+# endif -+#endif -+ -+ -+/* GRR 20040503: This is new and so far tested only under Linux. But it -+ * allows -wait to work with subsecond values as long as -+ * times() exists and clock_t is a long int (latter matters -+ * only if/when clocks wrap, which for Linux is multiples of -+ * 497.11 days since the last reboot). */ -+#if defined(__linux__) -+# define USE_TICKS /* use times()/Timer(), not time()/sleep() */ -+# include <limits.h> /* LONG_MAX (really want CLOCK_T_MAX) */ -+# include <sys/times.h> /* times() */ -+# ifndef CLK_TCK /* can be undefined in strict-ANSI mode */ -+# define CLK_TCK CLOCKS_PER_SEC /* claimed to be same thing in time.h */ -+# endif - #endif - -+#if (defined(SYSV) || defined(SVR4) || defined(linux)) && !defined(USE_GETCWD) -+# define USE_GETCWD -+#endif - - /*****************************/ - /* END OF CONFIGURATION INFO */ -@@ -363,17 +416,21 @@ - # define HAVE_TIFF - #endif - -+#ifdef DOPNG -+# define HAVE_PNG -+#endif -+ - #ifdef DOPDS - # define HAVE_PDS - #endif - - - --#define PROGNAME "xv" /* used in resource database */ -+#define PROGNAME "xv" /* used in resource database */ - --#define MAXNAMES 4096 /* max # of files in ctrlW list */ -+#define MAXNAMES 32768 /* max # of files in ctrlW list */ - --#define MAXBRWIN 4 /* max # of vis browser windows */ -+#define MAXBRWIN 16 /* max # of vis browser windows */ - - /* strings in the INFOBOX (used in SetISTR and GetISTR) */ - #define NISTR 10 /* number of ISTRs */ -@@ -494,24 +551,80 @@ - #define F_TIFINC 0 - #endif - -+#ifdef HAVE_PNG -+#define F_PNGINC 1 -+#else -+#define F_PNGINC 0 -+#endif -+ -+#ifdef HAVE_MAG -+# define F_MAGINC 1 -+#else -+# define F_MAGINC 0 -+#endif -+ -+#ifdef HAVE_PIC -+# define F_PICINC 1 -+#else -+# define F_PICINC 0 -+#endif -+ -+#ifdef HAVE_MAKI -+# define F_MAKINC 1 -+#else -+# define F_MAKINC 0 -+#endif -+ -+#ifdef HAVE_PI -+# define F_PAIINC 1 -+#else -+# define F_PAIINC 0 -+#endif -+ -+#ifdef HAVE_PIC2 -+# define F_PC2INC 1 -+#else -+# define F_PC2INC 0 -+#endif -+ -+#ifdef HAVE_MGCSFX -+# define F_MGCSFXINC 1 -+#else -+# define F_MGCSFXINC 0 -+#endif -+ -+#ifdef MACBINARY -+# define MACBSIZE 128 -+#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_ZX (12 + F_JPGINC + F_TIFINC + F_PNGINC) /* [JCE] */ -+#define F_WBMP (13 + F_JPGINC + F_TIFINC + F_PNGINC) -+#define JP_EXT_F (F_WBMP) -+#define F_MAG (JP_EXT_F + F_MAGINC) -+#define F_PIC (JP_EXT_F + F_MAGINC + F_PICINC) -+#define F_MAKI (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC) -+#define F_PI (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC) -+#define F_PIC2 (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC + F_PC2INC) -+#define F_MGCSFX (JP_EXT_F + F_MAGINC + F_PICINC + F_MAKINC + F_PAIINC + F_PC2INC + F_MGCSFXINC) -+#define JP_EXT_F_END (F_MGCSFX) -+#define F_DELIM1 (JP_EXT_F_END + 1) /* ----- */ -+#define F_FILELIST (JP_EXT_F_END + 2) -+#define F_MAXFMTS (JP_EXT_F_END + 3) /* 23, normally */ - - - -@@ -541,6 +654,19 @@ - #define RFT_XPM 17 - #define RFT_XWD 18 - #define RFT_FITS 19 -+#define RFT_PNG 20 -+#define RFT_ZX 21 /* [JCE] */ -+#define RFT_WBMP 22 -+#define RFT_PCD 23 -+#define RFT_HIPS 24 -+#define RFT_BZIP2 25 -+#define JP_EXT_RFT (RFT_BZIP2) -+#define RFT_MAG (JP_EXT_RFT + 1) -+#define RFT_MAKI (JP_EXT_RFT + 2) -+#define RFT_PIC (JP_EXT_RFT + 3) -+#define RFT_PI (JP_EXT_RFT + 4) -+#define RFT_PIC2 (JP_EXT_RFT + 5) -+#define RFT_MGCSFX (JP_EXT_RFT + 6) - - /* definitions for page up/down, arrow up/down list control */ - #define LS_PAGEUP 0 -@@ -599,7 +725,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 */ -@@ -649,7 +776,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 */ -@@ -784,9 +912,9 @@ - int len; /* length of major axis */ - int vert; /* true if vertical, else horizontal */ - int active; /* true if scroll bar can do anything*/ -- int min,max; /* min/max values 'pos' can take */ -- int val; /* 'value' of scrollbar */ -- int page; /* amt val change on pageup/pagedown */ -+ double min,max; /* min/max values 'pos' can take */ -+ double val; /* 'value' of scrollbar */ -+ double page; /* amt val change on pageup/pagedown */ - int tpos; /* thumb pos. (pixels from tmin) */ - int tmin,tmax; /* min/max thumb offsets (from 0,0) */ - int tsize; /* size of thumb (in pixels) */ -@@ -801,9 +929,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 */ -@@ -971,15 +1100,19 @@ - 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; - WHERE u_long blkRGB, whtRGB; - WHERE Font mfont, monofont; - WHERE XFontStruct *mfinfo, *monofinfo; -+#ifdef TV_L10N -+WHERE XFontSet monofset; -+WHERE XFontSetExtents *monofsetinfo; -+#endif - WHERE Visual *theVisual; --WHERE Cursor arrow, cross, tcross, zoom, inviso; -+WHERE Cursor arrow, cross, tcross, zoom, inviso, tlcorner; - WHERE Pixmap iconPix, iconmask; - WHERE Pixmap riconPix, riconmask; - WHERE int showzoomcursor; -@@ -996,6 +1129,10 @@ - WHERE int picType; /* CONV24_8BIT,CONV24_24BIT,etc.*/ - WHERE char *picComments; /* text comments on current pic */ - -+#ifdef TV_L10N -+WHERE int xlocale; /* true if Xlib supports locale */ -+#endif -+ - WHERE int numPages, curPage; /* for multi-page files */ - WHERE char pageBaseName[64]; /* basename for multi-page files */ - -@@ -1029,6 +1166,23 @@ - WHERE unsigned long cols[256]; /* maps pic pixel values to X pixel vals */ - WHERE int fc2pcol[256]; /* maps freecols into pic pixel values */ - WHERE int numcols; /* # of desired colors in picture */ -+#ifdef MACBINARY -+WHERE char macb_file; /* True if this file type is MacBinary */ -+WHERE int handlemacb; /* True if we want to handle MacBinary */ -+#endif -+#if defined(HAVE_PIC) || defined(HAVE_PIC2) -+WHERE int nopicadjust; /* True if we don't want to adjust aspect */ -+#endif -+#ifdef HAVE_PIC2 -+WHERE int pic2split; /* True if we want to split multiblocks */ -+#endif -+#ifdef VS_ADJUST -+WHERE int vsadjust; /* True if we want to adjust aspect of icons */ -+#endif -+#ifdef HAVE_MGCSFX -+WHERE int mgcsfx; /* True if we want to force use MgcSfx */ -+WHERE int nomgcsfx; /* True if we don't want to use MgcSfx */ -+#endif - - /* Std Cmap stuff */ - WHERE byte stdr[256], stdg[256], stdb[256]; /* std 3/3/2 cmap */ -@@ -1083,42 +1237,47 @@ - noFreeCols, /* don't free colors when loading new pic */ - autoquit, /* quit in '-root' or when click on win */ - xerrcode, /* errorcode of last X error */ -- grabDelay; /* # of seconds to sleep at start of Grab */ -+ grabDelay, /* # of seconds to sleep at start of Grab */ -+ startGrab; /* start immediate grab ? */ - - WHERE int state824; /* displays warning when going 8->24 */ - - WHERE float defaspect, /* default aspect ratio to use */ - normaspect; /* normal aspect ratio of this picture */ - --WHERE unsigned long rootbg, rootfg; /* fg/bg for root border */ --WHERE int waitsec; /* secs btwn pics. -1=wait for event */ --WHERE int waitloop; /* loop at end of slide show? */ --WHERE int automax; /* maximize pic on open */ --WHERE int rootMode; /* mode used for -root images */ -+WHERE u_long rootbg, rootfg; /* fg/bg for root border */ -+WHERE u_short imagebgR; -+WHERE u_short imagebgG; /* GRR 19980308: bg for transpar. images */ -+WHERE u_short imagebgB; -+WHERE int have_imagebg; -+WHERE double waitsec; /* secs btwn pics. -1.0=wait for event */ -+WHERE int waitloop; /* loop at end of slide show? */ -+WHERE int automax; /* maximize pic on open */ -+WHERE int rootMode; /* mode used for -root images */ - --WHERE int nostat; /* if true, don't stat() in LdCurDir */ -+WHERE int nostat; /* if true, don't stat() in LdCurDir */ - --WHERE int ctrlColor; /* whether or not to use colored butts */ -+WHERE int ctrlColor; /* whether or not to use colored butts */ - --WHERE char *def_str; /* used by rd_*() routines */ -+WHERE char *def_str; /* used by rd_*() routines */ - WHERE int def_int; --WHERE char *tmpdir; /* equal to "/tmp" or $TMPDIR env var */ --WHERE Pixmap gray25Tile, /* used for 3d effect on 1-bit disp's */ -+WHERE char *tmpdir; /* equal to "/tmp" or $TMPDIR env var */ -+WHERE Pixmap gray25Tile, /* used for 3d effect on 1-bit disp's */ - gray50Tile; --WHERE int autoDelete; /* delete cmd-line files on exit? */ -+WHERE int autoDelete; /* delete cmd-line files on exit? */ - - #define PRINTCMDLEN 256 - WHERE char printCmd[PRINTCMDLEN]; - - /* stuff used for 'info' box */ - WHERE Window infoW; --WHERE int infoUp; /* boolean: whether infobox is visible */ -+WHERE int infoUp; /* boolean: whether infobox is visible */ - WHERE int infoMode; - - - /* stuff used for 'ctrl' box */ - WHERE Window ctrlW; --WHERE int ctrlUp; /* boolean: whether ctrlbox is visible */ -+WHERE int ctrlUp; /* boolean: whether ctrlbox is visible */ - WHERE char *namelist[MAXNAMES]; /* list of file names from argv */ - WHERE char *origlist[MAXNAMES]; /* only names from argv (autoDelete)*/ - WHERE int orignumnames; -@@ -1157,25 +1316,30 @@ - - - /* stuff used for 'browse' box */ --WHERE int anyBrowUp; /* whether *any* browser visible */ -+WHERE int anyBrowUp; /* whether *any* browser visible */ - - /* stuff used for textview windows */ --WHERE int anyTextUp; /* are any text windows visible? */ --WHERE int commentUp; /* comment window up? */ -+WHERE int anyTextUp; /* are any text windows visible? */ -+WHERE int commentUp; /* comment window up? */ - - /* stuff used for xvcut.c */ --WHERE int forceClipFile; /* don't use property clipboard */ --WHERE int clearR, clearG, clearB; /* clear color in 24-bit mode */ -+WHERE int forceClipFile; /* don't use property clipboard */ -+WHERE int clearR, clearG, clearB; /* clear color in 24-bit mode */ - - - /* stuff used for 'ps' box */ - WHERE Window psW; --WHERE int psUp; /* is psW mapped, or what? */ -+WHERE int psUp; /* is psW mapped, or what? */ - WHERE CBUTT encapsCB, pscompCB; - WHERE char *gsDev, *gsGeomStr; - WHERE int gsRes; - - -+/* stuff used for 'pcd' box */ -+WHERE Window pcdW; -+WHERE int pcdUp; /* is pcdW mapped, or what? */ -+ -+ - #ifdef HAVE_JPEG - /* stuff used for 'jpeg' box */ - WHERE Window jpegW; -@@ -1190,6 +1354,91 @@ - #endif - - -+#ifdef HAVE_PNG -+/* stuff used for 'png' box */ -+WHERE Window pngW; -+WHERE int pngUp; /* is pngW mapped, or what? */ -+#endif -+ -+ -+#ifdef ENABLE_FIXPIX_SMOOTH -+WHERE int do_fixpix_smooth; /* GRR 19980607: runtime FS dithering */ -+#endif -+ -+#ifdef HAVE_PIC2 -+/* stuff used for 'pic2' box */ -+WHERE Window pic2W; -+WHERE int pic2Up; /* is pic2W mapped, or what? */ -+#endif /* HAVE_PIC2 */ -+ -+#ifdef HAVE_PCD -+/* stuff used for 'pcd' box */ -+WHERE Window pcdW; -+WHERE int pcdUp; /* is pcdW mapped, or what? */ -+#endif /* HAVE_PCD */ -+ -+#ifdef HAVE_MGCSFX -+/* stuff used for 'mgcsfx' box */ -+WHERE Window mgcsfxW; -+WHERE Window mgcsfxNameW; -+WHERE int mgcsfxUp; /* is mgcsfxW mapped, or what? */ -+#endif /* HAVE_MGCSFX */ -+ -+#ifdef TV_L10N -+/* stuff used for TextViewer Japanization */ -+# define LOCALE_USASCII 0 -+# define LOCALE_EUCJ 1 -+# define LOCALE_JIS 2 -+# define LOCALE_MSCODE 3 -+ -+# ifndef LOCALE_DEFAULT -+# define LOCALE_DEFAULT 0 -+# endif /* !LOCALE_DEFAULT */ -+ -+# ifndef MAIN -+ extern char *localeList[]; -+# else -+# ifndef LOCALE_NAME_EUC -+# ifndef X_LOCALE -+# if defined(__FreeBSD__) -+ char *localeList[] = {"", "ja_JP.EUC", "none", "none"}; -+# elif defined(__linux__) -+ char *localeList[] = {"", "ja_JP.eucJP", "none", "ja_JP.SJIS"}; -+# elif defined(__sun) || defined(sun) -+ char *localeList[] = {"", "ja", "none", "none"}; -+# elif defined(__sgi) /* sgi, __sgi, __sgi__ (gcc) */ -+ char *localeList[] = {"", "ja_JP.EUC", "none", "none"}; -+# elif defined(sony_news) -+ char *localeList[] = {"", "ja_JP.EUC", "none", "ja_JP.SJIS"}; -+# elif defined(nec) -+ char *localeList[] = {"", "japan", "none", "none"}; -+# elif defined(__hpux) -+ char *localeList[] = {"", "japanese.euc", "none", "japanese"}; -+# elif defined(__osf__) -+ char *localeList[] = {"", "ja_JP.deckanji", "none", "ja_JP.SJIS"}; -+# elif defined(_AIX) -+ char *localeList[] = {"", "ja_JP", "none", "Ja_JP" }; -+# elif defined(__bsdi) -+ char *localeList[] = {"", "Japanese-EUC", "none", "none" }; -+# else -+ char *localeList[] = {"", "ja_JP.EUC", "ja_JP.JIS", "ja_JP.SJIS"}; -+# endif -+# else -+# if (XlibSpecificationRelease > 5) -+ char *localeList[] = {"", "ja_JP.eucJP", "ja_JP.JIS7", -+ "ja_JP.SJIS"}; -+# else -+ char *localeList[] = {"", "ja_JP.ujis", "ja_JP.jis7", -+ "ja_JP.mscode"}; -+# endif -+# endif /* X_LOCALE */ -+# else -+ char *localeList[] = {"", LOCALE_NAME_EUC, -+ LOCALE_NAME_JIS, LOCALE_NAME_MSCODE}; -+# endif /* LOCALE_NAME_EUC */ -+# endif /* MAIN */ -+#endif /* TV_L10N */ -+ - #undef WHERE - - -@@ -1199,8 +1448,11 @@ - /****************************** XV.C ****************************/ - int ReadFileType PARM((char *)); - int ReadPicFile PARM((char *, int, PICINFO *, int)); --int UncompressFile PARM((char *, char *)); -+int UncompressFile PARM((char *, char *, int)); - void KillPageFiles PARM((char *, int)); -+#ifdef MACBINARY -+int RemoveMacbinary PARM((char *, char *)); -+#endif - - void NewPicGetColors PARM((int, int)); - void FixAspect PARM((int, int *, int *)); -@@ -1429,6 +1681,9 @@ - int CheckPoll PARM((int)); - void DIRDeletedFile PARM((char *)); - void DIRCreatedFile PARM((char *)); -+FILE *pic2_OpenOutFile PARM((char *, int *)); -+void pic2_KillNullFile PARM((FILE *)); -+int OpenOutFileDesc PARM((char *)); - - - /*************************** XVBROWSE.C ************************/ -@@ -1448,7 +1703,7 @@ - - /*************************** XVTEXT.C ************************/ - void CreateTextWins PARM((char *, char *)); --void TextView PARM((char *)); -+int TextView PARM((char *)); - void OpenTextView PARM((char *, int, char *, int)); - - void OpenCommentText PARM((void)); -@@ -1466,6 +1721,8 @@ - int TextCheckEvent PARM((XEvent *, int *, int *)); - int TextDelWin PARM((Window)); - -+int CharsetCheckEvent PARM((XEvent *)); -+int CharsetDelWin PARM((Window)); - - - /**************************** XVGAM.C **************************/ -@@ -1502,12 +1759,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)); -@@ -1585,7 +1842,11 @@ - byte *, byte *, int, int, char *)); - - /**************************** XVPBM.C ***************************/ -+#ifdef HAVE_MGCSFX -+int LoadPBM PARM((char *, PICINFO *, int)); -+#else - int LoadPBM PARM((char *, PICINFO *)); -+#endif - int WritePBM PARM((FILE *, byte *, int, int, int, byte *, - byte *, byte *, int, int, int, char *)); - -@@ -1604,6 +1865,11 @@ - int WriteBMP PARM((FILE *, byte *, int, int, int, byte *, - byte *, byte *, int, int)); - -+/**************************** XVWBMP.C ***************************/ -+int LoadWBMP PARM((char *, PICINFO *)); -+int WriteWBMP PARM((FILE *, byte *, int, int, int, byte *, -+ byte *, byte *, int, int)); -+ - /**************************** XVRLE.C ***************************/ - int LoadRLE PARM((char *, PICINFO *)); - -@@ -1642,6 +1908,7 @@ - void JPEGDialog PARM((int)); - int JPEGCheckEvent PARM((XEvent *)); - void JPEGSaveParams PARM((char *, int)); -+void VersionInfoJPEG PARM((void)); /* GRR 19980605 */ - - /**************************** XVTIFF.C ***************************/ - int LoadTIFF PARM((char *, PICINFO *, int)); -@@ -1649,6 +1916,15 @@ - void TIFFDialog PARM((int)); - int TIFFCheckEvent PARM((XEvent *)); - void TIFFSaveParams PARM((char *, int)); -+void VersionInfoTIFF PARM((void)); /* GRR 19980605 */ -+ -+/**************************** XVPNG.C ***************************/ -+int LoadPNG PARM((char *, PICINFO *)); -+void CreatePNGW PARM((void)); -+void PNGDialog PARM((int)); -+int PNGCheckEvent PARM((XEvent *)); -+void PNGSaveParams PARM((char *, int)); -+void VersionInfoPNG PARM((void)); /* GRR 19980605 */ - - /**************************** XVPDS.C ***************************/ - int LoadPDS PARM((char *, PICINFO *)); -@@ -1661,6 +1937,87 @@ - void PSResize PARM((void)); - int LoadPS PARM((char *, PICINFO *, int)); - -+/************************ [JCE] XVZX.C ***************************/ -+ -+int LoadZX PARM((char *, PICINFO *)); -+int WriteZX PARM((FILE *, byte *, int, int, int, byte *, -+ byte *, byte *, int, int, char *)); -+ -+/**************************** XVPCD.C ***************************/ -+int LoadPCD PARM((char *, PICINFO *, int)); -+void CreatePCDW PARM((void)); -+void PCDDialog PARM((int)); -+int PCDCheckEvent PARM((XEvent *)); -+void PCDSetParamOptions PARM((char *)); -+ -+/*************************** XVMAG.C ***************************/ -+int LoadMAG PARM((char *, PICINFO *)); -+int WriteMAG PARM((FILE *, byte *, int, int, int, -+ byte *, byte *, byte *, int, int, char *)); -+ -+/*************************** XVMAKI.C ***************************/ -+int LoadMAKI PARM((char *, PICINFO *)); -+int WriteMAKI PARM((FILE *, byte *, int, int, int, -+ byte *, byte *, byte *, int, int)); -+ -+/*************************** XVPIC.C ***************************/ -+int LoadPIC PARM((char *, PICINFO *)); -+int WritePIC PARM((FILE *, byte *, int, int, int, -+ byte *, byte *, byte *, int, int, char *)); -+ -+/*************************** XVPI.C ***************************/ -+int LoadPi PARM((char *, PICINFO *)); -+int WritePi PARM((FILE *, byte *, int, int, int, -+ byte *, byte *, byte *, int, int, char *)); -+ -+/*************************** XVPIC2.C ***************************/ -+int LoadPIC2 PARM((char *, PICINFO *, int)); -+void CreatePIC2W PARM((void)); -+void PIC2Dialog PARM((int)); -+int PIC2CheckEvent PARM((XEvent *)); -+int PIC2SetParamOptions PARM((char *)); -+ -+/**************************** XVPCD.C ***************************/ -+int LoadPCD PARM((char *, PICINFO *,int)); -+void CreatePCDW PARM((void)); -+void PCDDialog PARM((int)); -+int PCDCheckEvent PARM((XEvent *)); -+void PCDSetParamOptions PARM((char *)); -+ -+/**************************** XVHIPS.C ***************************/ -+int LoadHIPS PARM((char *, PICINFO *)); -+ -+/*************************** XVMGCSFX.C ***************************/ -+int is_mgcsfx PARM((char *, unsigned char *, int)); -+char *mgcsfx_auto_input_com PARM((char *)); -+int LoadMGCSFX PARM((char *, PICINFO *)); -+void CreateMGCSFXW PARM((void)); -+void MGCSFXDialog PARM((int)); -+int MGCSFXCheckEvent PARM((XEvent *)); -+int MGCSFXSaveParams PARM((char *, int)); -+ -+int getInputCom PARM((void)); -+int getOutputCom PARM((void)); -+ -+/**************************** XVVD.C ****************************/ -+void Vdinit PARM((void)); -+void Vdsettle PARM((void)); -+int Chvdir PARM((char *)); -+void Dirtovd PARM((char *)); -+void Vdtodir PARM((char *)); -+void Dirtosubst PARM((char *)); -+int Mkvdir PARM((char *)); -+void Mkvdir_force PARM((char *)); -+int Rmvdir PARM((char *)); -+int Movevdir PARM((char *, char *)); -+int Isarchive PARM((char *)); -+int Isvdir PARM((char *)); -+void vd_HUPhandler PARM((void)); -+void vd_handler PARM((int)); -+int vd_Xhandler PARM((Display *, XErrorEvent *)); -+int vd_XIOhandler PARM((Display *)); -+void vd_handler_setup PARM((void)); -+ - /*************************** XVPOPUP.C ***************************/ - void CenterMapWindow PARM((Window, int, int, int, int)); - int PopUp PARM((char *, char **, int)); -@@ -1714,3 +2071,13 @@ - void CoordP2E PARM((int, int, int *, int *)); - void CoordE2P PARM((int, int, int *, int *)); - -+#if defined(__mips) && defined(__SYSTYPE_BSD43) -+# define strstr(A,B) pds_strstr((A),(B)) -+# undef S_IFIFO -+#endif /* !mips_bsd */ -+ -+#ifndef SEEK_SET -+# define SEEK_SET 0 -+# define SEEK_CUR 1 -+# define SEEK_END 2 -+#endif -diff -ruN xv-3.10a-bugfixes/xv_mgcsfx.sample xv-3.10a-enhancements/xv_mgcsfx.sample ---- xv-3.10a-bugfixes/xv_mgcsfx.sample 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xv_mgcsfx.sample 2005-04-17 14:04:22.000000000 -0700 -@@ -0,0 +1,125 @@ -+#/* -+# Configuration file for XV with recognition of 'Magic and Suffix' -+# -+# -+# $Id: xv_mgcsfx.sample,v 1.11 95/10/03 17:00:05 tin329 Exp Locker: tin329 $ -+# -+# Author: Tetsuya INOUE <tin329@chino.it.okayama-u.ac.jp> -+# -+# -+# MgcSfx definition should write in one line. -+# Format: -+# <desc>:<ms type>:<ofs>:<magic>:<suffix>:<in it>:<in c>:<out it>:<out c> -+# If you decide to not use preprocessor, comment style is allowed. -+# # <comment> -+# -+# <desc> Description of your recognized image format. -+# <ms type> Type ID for recognition. (You should use 'magic'.) -+# * magic Data of string style. -+# `\' escape for special characters: -+# \b \f \n \r \t \v \\ \' \" \a \? -+# \0 ...\377 octal value -+# \x0 ...\xff hexadecimal value -+# * suffix Suffix of file name. -+# This type check <suffix> instead -+# of <magic>. -+# * [b|l]eint16 2 byte integer of [big|little] endian. -+# * [b|l]eint32 4 byte integer of [big|little] endian. -+# <ofs> Offset of magic number in the target image file. -+# <magic> Data(magic number) of <ms type> to match at <ofs>. -+# <suffix> Suffix of filename with '.'start. -+# -+# <in it> Input image format type (output from <in c>). -+# * PNM (PPM, PGM, PBM) -+# * AUTO Recognized by xv management, and load. -+# This is different from others, because -+# this write file to temporary. -+# <out it> Output image format type (input to <out c>). -+# * PNM_RAW (PPM_RAW, PGM_RAW, PBM_RAW) -+# * PNM_ASCII (PPM_ASCII, PGM_ASCII, PBM_ASCII) -+# -+# <in c> Command to get the input image. -+# * Command mast read stdin or file(specified by -+# argument), and write to stdout. -+# * Use %s to represent the file name. Without %s, -+# get file on stdin. -+# <out c> Command to put the output image. -+# * Command mast read stdin and write to stdout. -+# -+# <comment> Any message. -+#*/ -+ -+#/*############################################################################ -+# -+# definition of the rule with Magic and Suffix -+# -+#*/ -+ -+# /* Canon View Station Image Format */ -+ViewStation(std):magic:0:VsStdImf V0.2:.vs:PNM:VStopnm %s:PNM_RAW:pnmtoVS -+ViewStation(obj):magic:0:VsObjFormat V1.0:.vs:PNM:VSobjtopnm -:PNM_RAW:pnmtoVSobj -+ -+# /* CERN httpd cache */ -+# /* unchc skip header of CERN httpd cache file, and write data to stdout. */ -+CERN httpd cache:magic:0:HTTP/1.0::AUTO:unchc %s:: -+ -+# /* XLD4(Q4) image format */ -+XLD(Q4):magic:11:MAJYO:.q4:PNM:q4toppm:: -+ -+# /* ML1 image format */ -+ML1:magic:0:\1\0\0\x1a:.ml1:PNM:ml1toppm %s:: -+ -+# /* Pict image format, 256 color only */ -+PICT:suffix:::.pict:PNM:picttoppm:PNM_RAW:ppmquant 256 | ppmtopict -+PICT(gzip):suffix:::.pict.gz:PNM:gzip -dc | picttoppm:PNM_RAW:ppmquant 256 | ppmtopict | gzip -+PICT(compress):suffix:::.pict.Z:PNM:compress -dc | picttoppm:PNM_RAW:ppmquant 256 | ppmtopict | compress -+ -+# /* Tim image format(used by SONY PlayStation) */ -+TIM:magic:0:\x10\x00\x00\x00:.tim:PNM:timtoppm:: -+ -+# /* Cam image format(used by CASIO QV-10) */ -+# /* CAM:magic:0:\x07\x20\x4d\x4d:.cam:AUTO:camtoppm -j:PNM_RAW */ -+CAM:magic:0:\x07\x20\x4d\x4d:.cam:PNM:camtoppm:: -+ -+# /* Portable Network Graphics (PNG) format : magic is "0x89 PNG" */ -+PNG:magic:0:\x89\x50\x4e\x47:.png:PNM:pngtopnm %s:PNM_RAW:pnmtopng -+# /* PNG(interlace):magic:0:\x89\x50\x4e\x47:.png:PNM:pngtopnm %s:PNM_RAW:pnmtopng -interlace */ -+ -+# /* DB-Z, SAURUS Freehand Memo, PV-F1 Action Board, Wiz Quick Memo format */ -+# /* Use xbm2free-1.10 or later. Old version is NOT a filter. */ -+# /* To show version of xbm2free, type "xbm2free" (with no argument). */ -+ZAURUS:magic:19:IMG1:.zau:PBM_ASCII:free2pbm:PBM:pbmtoxbm|xbm2free -s - -+DBZ:magic:19:IMG1:.dbz:::PBM:pbmtoxbm|xbm2free -d - -+PVF1:magic:12:IMG1:.pvf1:PBM_ASCII:free2pbm:PBM:pbmtoxbm|xbm2free -v - -+# /* WIZ:magic:19:IMG1:.wiz:::PBM:pbmtoxbm|xbm2free -w - */ -+ -+ -+ -+# /* Compress:magic:0:\037\235:.Z:AUTO:uncompress %s:: */ -+# /* Gzip:magic:0:\037\213:.gz:AUTO:gunzip %s:: */ -+# /* Gzip(old):magic:0:\037\236:.z:AUTO:gunzip %s:: */ -+ -+# /* MAKI:magic:0:MAKI01A\040:.mki:::: */ -+# /* MAKI:magic:0:MAKI01B\040:.mki:::: */ -+# /* MAG:magic:0:MAKI02\040\040:.mag:::: */ -+# /* Pi:magic:0:Pi:.pi:::: */ -+# /* PIC:magic:0:PIC:.pic:::: */ -+# /* PIC2:magic:0:P2DT:.p2:::: */ -+# /* PhotoCD:magic:0:\xff\xff\xff\xff:.pcd:::: */ -+ -+# /* PBM(ascii):magic:0:P1:.pbm:::: */ -+# /* PGM(ascii):magic:0:P2:.pgm:::: */ -+# /* PPM(ascii):magic:0:P3:.ppm:::: */ -+# /* PBM(raw):magic:0:P4:.pbm:::: */ -+# /* PGM(raw):magic:0:P5:.pgm:::: */ -+# /* PPM(raw):magic:0:P6:.ppm:::: */ -+ -+# /* Sun raster:magic:0:\131\246\152\225:.sun:::: */ -+# /* JFIF(JPEG):magic:0:\xff\xd8\xff:.jpg:::: */ -+# /* TIFF big-endian:magic:0:\115\115:.tif:::: */ -+# /* TIFF little-endian:magic:0:\111\111:.tif:::: */ -+# /* GIF(87):magic:0:GIF87a:.gif:::: */ -+# /* GIF(89):magic:0:GIF89a:.gif:::: */ -+# /* SGI(1):magic:0:\x01\xda:.rgb:::: */ -+# /* SGI(2):magic:0:\xda\x01:.rgb:::: */ -+# /* XWD:magic:0:\0\0\0\7: :::: */ -diff -ruN xv-3.10a-bugfixes/xvbmp.c xv-3.10a-enhancements/xvbmp.c ---- xv-3.10a-bugfixes/xvbmp.c 2005-03-27 18:12:17.000000000 -0800 -+++ xv-3.10a-enhancements/xvbmp.c 2005-04-17 13:56:31.000000000 -0700 -@@ -1,5 +1,5 @@ - /* -- * xvbmp.c - i/o routines for .BMP files (MS Windows 3.x) -+ * xvbmp.c - I/O routines for .BMP files (MS Windows 3.x and later; OS/2) - * - * LoadBMP(fname, numcols) - * WriteBMP(fp, pic, ptype, w, h, r, g, b, numcols, style); -@@ -9,30 +9,39 @@ - - #include "xv.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. -- -- a file with garbage characters in it is an unloadable file. All allocated -- stuff is tossed, and LoadBMP returns non-zero -- -- not being able to malloc is a Fatal Error. The program is aborted. */ -- -- --#define BI_RGB 0 --#define BI_RLE8 1 --#define BI_RLE4 2 -+/* Comments on error-handling: -+ A truncated file is not considered a Major Error. The file is loaded, -+ and the rest of the pic is filled with 0's. -+ -+ A file with garbage characters in it is an unloadable file. All allocated -+ stuff is tossed, and LoadBMP returns non-zero. -+ -+ Not being able to malloc is a Fatal Error. The program is aborted. */ -+ -+ -+#define BI_RGB 0 /* a.k.a. uncompressed */ -+#define BI_RLE8 1 -+#define BI_RLE4 2 -+#define BI_BITFIELDS 3 /* BMP version 4 */ -+#define BI_JPEG 4 /* BMP version 5 (not yet supported) */ -+#define BI_PNG 5 /* BMP version 5 (not yet supported) */ - - #define WIN_OS2_OLD 12 - #define WIN_NEW 40 - #define OS2_NEW 64 - -+#if (defined(UINT_MAX) && UINT_MAX != 0xffffffffU) -+# error XV's BMP code requires 32-bit unsigned integer type, but u_int isn't -+#endif -+ - static long filesize; - - 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 loadBMP16 PARM((FILE *, byte *, u_int, u_int, u_int *)); -+static int loadBMP24 PARM((FILE *, byte *, u_int, u_int, u_int)); -+static int loadBMP32 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)); -@@ -52,15 +61,14 @@ - PICINFO *pinfo; - /*******************************************/ - { -- FILE *fp; -- int i, c, c1, rv; -- u_int bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes; -- u_int biBitCount, biCompression, biSizeImage, biXPelsPerMeter; -- u_int biYPelsPerMeter, biClrUsed, biClrImportant; -- int bPad; -- char *cmpstr; -- byte *pic24, *pic8; -- char buf[512], *bname; -+ FILE *fp; -+ int i, c, c1, rv, bPad; -+ u_int bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes; -+ u_int biBitCount, biCompression, biSizeImage, biXPelsPerMeter; -+ u_int biYPelsPerMeter, biClrUsed, biClrImportant; -+ u_int colormask[3]; -+ char buf[512], *bname, *cmpstr, rgb_bits[16]; -+ byte *pic24, *pic8; - - /* returns '1' on success */ - -@@ -98,14 +106,13 @@ - biClrUsed = getint(fp); - biClrImportant = getint(fp); - } -- - else { /* old bitmap format */ - biWidth = getshort(fp); /* Types have changed ! */ - biHeight = getshort(fp); - biPlanes = getshort(fp); - biBitCount = getshort(fp); - -- /* Not in old versions so have to compute them*/ -+ /* not in old versions, so have to compute them */ - biSizeImage = (((biPlanes * biBitCount*biWidth)+31)/32)*4*biHeight; - - biCompression = BI_RGB; -@@ -126,25 +133,39 @@ - if (FERROR(fp)) { bmpError(bname,"EOF reached in file header"); goto ERROR; } - - -- /* error checking */ -- if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && biBitCount!=24) || -- biPlanes!=1 || biCompression>BI_RLE4 || -+ /* error-checking */ -+ if ((biBitCount!=1 && biBitCount!=4 && biBitCount!=8 && -+ biBitCount!=16 && biBitCount!=24 && biBitCount!=32) || -+ biPlanes!=1 || biCompression>BI_PNG || - biWidth<=0 || biHeight<=0 || - (biClrUsed && biClrUsed > (1 << biBitCount))) { - - sprintf(buf, -- "Bogus BMP File! (%dx%d, Bits=%d, Colors=%d, Planes=%d, Compr=%d)", -+ "Unsupported BMP type (%dx%d, Bits=%d, Colors=%d, Planes=%d, " -+ "Compr=%d)", - biWidth, biHeight, biBitCount, biClrUsed, biPlanes, biCompression); - - bmpError(bname, buf); - goto ERROR; - } - -+ if (biCompression>BI_BITFIELDS) { -+ sprintf(buf, "Unsupported BMP compression method (%s)", -+ biCompression == BI_JPEG? "JPEG" : -+ biCompression == BI_PNG? "PNG" : -+ "unknown/newer than v5"); -+ -+ bmpError(bname, buf); -+ goto ERROR; -+ } -+ - if (((biBitCount==1 || biBitCount==24) && biCompression != BI_RGB) || -- (biBitCount==4 && biCompression==BI_RLE8) || -- (biBitCount==8 && biCompression==BI_RLE4)) { -+ (biBitCount==4 && biCompression!=BI_RGB && biCompression!=BI_RLE4) || -+ (biBitCount==8 && biCompression!=BI_RGB && biCompression!=BI_RLE8) || -+ ((biBitCount==16 || biBitCount==32) && -+ biCompression!=BI_RGB && biCompression!=BI_BITFIELDS)) { - -- sprintf(buf,"Bogus BMP File! (bitCount=%d, Compression=%d)", -+ sprintf(buf,"Unsupported BMP type (bitCount=%d, Compression=%d)", - biBitCount, biCompression); - - bmpError(bname, buf); -@@ -156,20 +177,23 @@ - if (biSize != WIN_OS2_OLD) { - /* skip ahead to colormap, using biSize */ - c = biSize - 40; /* 40 bytes read from biSize to biClrImportant */ -- for (i=0; i<c; i++) getc(fp); -- -+ for (i=0; i<c; i++) -+ getc(fp); - bPad = bfOffBits - (biSize + 14); - } - -+ /* 16-bit or 32-bit color mask */ -+ if (biCompression==BI_BITFIELDS) { -+ colormask[0] = getint(fp); -+ colormask[1] = getint(fp); -+ colormask[2] = getint(fp); -+ bPad -= 12; -+ } -+ - /* load up colormap, if any */ -- if (biBitCount!=24) { -+ if (biBitCount == 1 || biBitCount == 4 || biBitCount == 8) { - int i, cmaplen; - --/* this is superfluous; see identical test in "error checking" block above -- if (biClrUsed > (1 << biBitCount)) -- biClrUsed = (1 << biBitCount); -- */ -- - cmaplen = (biClrUsed) ? biClrUsed : 1 << biBitCount; - for (i=0; i<cmaplen; i++) { - pinfo->b[i] = getc(fp); -@@ -205,7 +229,7 @@ - - /* create pic8 or pic24 */ - -- if (biBitCount==24) { -+ if (biBitCount==16 || biBitCount==24 || biBitCount==32) { - u_int npixels = biWidth * biHeight; - u_int count = 3 * npixels; - -@@ -227,19 +251,35 @@ - WaitCursor(); - - /* load up the image */ -- 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, -- biCompression); -- else rv = loadBMP24(fp,pic24,biWidth,biHeight); -+ switch (biBitCount) { -+ case 1: -+ rv = loadBMP1(fp, pic8, biWidth, biHeight); -+ break; -+ case 4: -+ rv = loadBMP4(fp, pic8, biWidth, biHeight, biCompression); -+ break; -+ case 8: -+ rv = loadBMP8(fp, pic8, biWidth, biHeight, biCompression); -+ break; -+ case 16: -+ rv = loadBMP16(fp, pic24, biWidth, biHeight, /* v-- BI_RGB */ -+ biCompression == BI_BITFIELDS? colormask : NULL); -+ break; -+ default: -+ if (biBitCount == 32 && biCompression == BI_BITFIELDS) -+ rv = loadBMP32(fp, pic24, biWidth, biHeight, colormask); -+ else /* 24 or (32 and BI_RGB) */ -+ rv = loadBMP24(fp, pic24, biWidth, biHeight, biBitCount); -+ break; -+ } - - if (rv) bmpError(bname, "File appears truncated. Winging it."); - -+ - fclose(fp); - - -- if (biBitCount == 24) { -+ if (biBitCount > 8) { - pinfo->pic = pic24; - pinfo->type = PIC24; - } -@@ -251,6 +291,22 @@ - cmpstr = ""; - if (biCompression == BI_RLE4) cmpstr = ", RLE4 compressed"; - else if (biCompression == BI_RLE8) cmpstr = ", RLE8 compressed"; -+ else if (biCompression == BI_BITFIELDS) { -+ int bit, c[3], i; -+ u_int mask; -+ -+ for (i = 0; i < 3; ++i) { -+ mask = colormask[i]; -+ c[i] = 0; -+ for (bit = 0; bit < 32; ++bit) { -+ if (mask & 1) -+ ++c[i]; -+ mask >>= 1; -+ } -+ } -+ sprintf(rgb_bits, ", RGB%d%d%d", c[0], c[1], c[2]); -+ cmpstr = rgb_bits; -+ } - - pinfo->w = biWidth; pinfo->h = biHeight; - pinfo->normw = pinfo->w; pinfo->normh = pinfo->h; -@@ -282,12 +338,13 @@ - u_int w,h; - { - int i,j,c,bitnum,padw; -- byte *pp; -+ byte *pp = pic8 + ((h - 1) * w); -+ size_t l = w*h; - - c = 0; - padw = ((w + 31)/32) * 32; /* 'w', padded to be a multiple of 32 */ - -- for (i=h-1; i>=0; i--) { -+ for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { - pp = pic8 + (i * w); - if ((i&0x3f)==0) WaitCursor(); - for (j=bitnum=0; j<padw; j++,bitnum++) { -@@ -316,8 +373,8 @@ - u_int w,h,comp; - { - int i,j,c,c1,x,y,nybnum,padw,rv; -- byte *pp; -- -+ byte *pp = pic8 + ((h - 1) * w); -+ size_t l = w*h; - - rv = 0; - c = c1 = 0; -@@ -325,7 +382,7 @@ - if (comp == BI_RGB) { /* read uncompressed data */ - padw = ((w + 7)/8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */ - -- for (i=h-1; i>=0; i--) { -+ for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { - pp = pic8 + (i * w); - if ((i&0x3f)==0) WaitCursor(); - -@@ -353,7 +410,7 @@ - - if (c) { /* encoded mode */ - c1 = getc(fp); -- for (i=0; i<c; i++,x++,pp++) -+ for (i=0; i<c && (pp - pic8 <= l); i++,x++,pp++) - *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f); - } - -@@ -373,7 +430,7 @@ - } - - else { /* absolute mode */ -- for (i=0; i<c; i++, x++, pp++) { -+ for (i=0; i<c && (pp - pic8 <= l); i++, x++, pp++) { - if ((i&1) == 0) c1 = getc(fp); - *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f); - } -@@ -402,14 +459,18 @@ - u_int w,h,comp; - { - int i,j,c,c1,padw,x,y,rv; -- byte *pp; -+ byte *pp = pic8 + ((h - 1) * w); -+ size_t l = w*h; -+ byte *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) */ - -- for (i=h-1; i>=0; i--) { -+ for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { - pp = pic8 + (i * w); - if ((i&0x3f)==0) WaitCursor(); - -@@ -425,12 +486,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 */ -@@ -449,7 +510,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; - } -@@ -472,26 +533,133 @@ - - - /*******************************************/ --static int loadBMP24(fp, pic24, w, h) -+static int loadBMP16(fp, pic24, w, h, mask) -+ FILE *fp; -+ byte *pic24; -+ u_int w, h, *mask; -+{ -+ int x, y; -+ byte *pp = pic24 + ((h - 1) * w * 3); -+ size_t l = w*h*3; -+ u_int buf, colormask[6]; -+ int i, bit, bitshift[6], colorbits[6], bitshift2[6]; -+ -+ if (mask == NULL) { /* RGB555 */ -+ colormask[0] = 0x00007c00; -+ colormask[1] = 0x000003e0; -+ colormask[2] = 0x0000001f; -+ colormask[3] = 0x7c000000; -+ colormask[4] = 0x03e00000; -+ colormask[5] = 0x001f0000; -+ bitshift[0] = 7; bitshift2[0] = 0; -+ bitshift[1] = 2; bitshift2[1] = 0; -+ bitshift[2] = 0; bitshift2[2] = 3; -+ bitshift[3] = 23; bitshift2[3] = 0; -+ bitshift[4] = 18; bitshift2[4] = 0; -+ bitshift[5] = 13; bitshift2[5] = 0; -+ } else { -+ colormask[0] = mask[0]; -+ colormask[1] = mask[1]; -+ colormask[2] = mask[2]; -+ colormask[3] = (mask[0] & 0xffff) << 16; -+ colormask[4] = (mask[1] & 0xffff) << 16; -+ colormask[5] = (mask[2] & 0xffff) << 16; -+ -+ for (i = 0; i < 3; ++i) { -+ buf = colormask[i]; -+ -+ bitshift[i] = 0; -+ for (bit = 0; bit < 32; ++bit) { -+ if (buf & 1) -+ break; -+ else -+ ++bitshift[i]; -+ buf >>= 1; -+ } -+ bitshift[i+3] = bitshift[i] + 16; -+ -+ colorbits[i] = 0; -+ for (; bit < 32; ++bit) { -+ if (buf & 1) -+ ++colorbits[i]; -+ else -+ break; -+ buf >>= 1; -+ } -+ if (colorbits[i] > 8) { /* over 8-bit depth */ -+ bitshift[i] += (colorbits[i] - 8); -+ bitshift[i+3] = bitshift[i] + 16; -+ bitshift2[i] = bitshift2[i+3] = 0; -+ } else -+ bitshift2[i] = bitshift2[i+3] = 8 - colorbits[i]; -+ } -+ } -+ -+ if (DEBUG > 1) -+ fprintf(stderr, "loadBMP16: bitfields\n" -+ "\tR: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n" -+ "\t (mask = %08x, shift >>%2d, <<%2d)\n" -+ "\tG: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n" -+ "\t (mask = %08x, shift >>%2d, <<%2d)\n" -+ "\tB: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n" -+ "\t (mask = %08x, shift >>%2d, <<%2d)\n", -+ colorbits[0], colormask[0], bitshift[0], bitshift2[0], -+ colormask[3], bitshift[3], bitshift2[3], -+ colorbits[1], colormask[1], bitshift[1], bitshift2[1], -+ colormask[4], bitshift[4], bitshift2[4], -+ colorbits[2], colormask[2], bitshift[2], bitshift2[2], -+ colormask[5], bitshift[5], bitshift2[5]); -+ -+ for (y = h-1; y >= 0 && (pp - pic24 <= l); y--) { -+ pp = pic24 + (3 * w * y); -+ if ((y&0x3f)==0) WaitCursor(); -+ -+ for (x = w; x > 1; x -= 2) { -+ buf = getint(fp); -+ *(pp++) = (buf & colormask[0]) >> bitshift[0] << bitshift2[0]; -+ *(pp++) = (buf & colormask[1]) >> bitshift[1] << bitshift2[1]; -+ *(pp++) = (buf & colormask[2]) >> bitshift[2] << bitshift2[2]; -+ *(pp++) = (buf & colormask[3]) >> bitshift[3] << bitshift2[3]; -+ *(pp++) = (buf & colormask[4]) >> bitshift[4] << bitshift2[4]; -+ *(pp++) = (buf & colormask[5]) >> bitshift[5] << bitshift2[5]; -+ } -+ if (w & 1) { /* padded to 2 pix */ -+ buf = getint(fp); -+ *(pp++) = (buf & colormask[0]) >> bitshift[0]; -+ *(pp++) = (buf & colormask[1]) >> bitshift[1]; -+ *(pp++) = (buf & colormask[2]) >> bitshift[2]; -+ } -+ } -+ -+ return FERROR(fp)? 1 : 0; -+} -+ -+ -+ -+/*******************************************/ -+static int loadBMP24(fp, pic24, w, h, bits) /* also handles 32-bit BI_RGB */ - FILE *fp; - byte *pic24; -- u_int w,h; -+ u_int w,h, bits; - { - int i,j,padb,rv; -- byte *pp; -+ byte *pp = pic24 + ((h - 1) * w * 3); -+ size_t l = w*h*3; - - 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); - if ((i&0x3f)==0) WaitCursor(); - -- for (j=0; j<w; j++) { -+ for (j=0; j<w && (pp - pic24 <= l); j++) { - pp[2] = getc(fp); /* blue */ - pp[1] = getc(fp); /* green */ - pp[0] = getc(fp); /* red */ -+ if (bits==32) getc(fp); - pp += 3; - } - -@@ -507,6 +675,70 @@ - - - /*******************************************/ -+static int loadBMP32(fp, pic24, w, h, colormask) /* 32-bit BI_BITFIELDS only */ -+ FILE *fp; -+ byte *pic24; -+ u_int w, h, *colormask; -+{ -+ int x, y; -+ byte *pp; -+ u_int buf; -+ int i, bit, bitshift[3], colorbits[3], bitshift2[3]; -+ -+ for (i = 0; i < 3; ++i) { -+ buf = colormask[i]; -+ -+ bitshift[i] = 0; -+ for (bit = 0; bit < 32; ++bit) { -+ if (buf & 1) -+ break; -+ else -+ ++bitshift[i]; -+ buf >>= 1; -+ } -+ -+ colorbits[i] = 0; -+ for (; bit < 32; ++bit) { -+ if (buf & 1) -+ ++colorbits[i]; -+ else -+ break; -+ buf >>= 1; -+ } -+ if (colorbits[i] > 8) { /* over 8-bit depth */ -+ bitshift[i] += (colorbits[i] - 8); -+ bitshift2[i] = 0; -+ } else -+ bitshift2[i] = 8 - colorbits[i]; -+ } -+ -+ if (DEBUG > 1) -+ fprintf(stderr, "loadBMP32: bitfields\n" -+ "\tR: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n" -+ "\tG: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n" -+ "\tB: bits = %2d, mask = %08x, shift >>%2d, <<%2d\n", -+ colorbits[0], colormask[0], bitshift[0], bitshift2[0], -+ colorbits[1], colormask[1], bitshift[1], bitshift2[1], -+ colorbits[2], colormask[2], bitshift[2], bitshift2[2]); -+ -+ for (y = h-1; y >= 0; y--) { -+ pp = pic24 + (3 * w * y); -+ if ((y&0x3f)==0) WaitCursor(); -+ -+ for(x = w; x > 0; x --) { -+ buf = getint(fp); -+ *(pp++) = (buf & colormask[0]) >> bitshift[0] << bitshift2[0]; -+ *(pp++) = (buf & colormask[1]) >> bitshift[1] << bitshift2[1]; -+ *(pp++) = (buf & colormask[2]) >> bitshift[2] << bitshift2[2]; -+ } -+ } -+ -+ return FERROR(fp)? 1 : 0; -+} -+ -+ -+ -+/*******************************************/ - static u_int getshort(fp) - FILE *fp; - { -@@ -523,7 +755,7 @@ - int c, c1, c2, c3; - c = getc(fp); c1 = getc(fp); c2 = getc(fp); c3 = getc(fp); - return ((u_int) c) + -- (((u_int) c1) << 8) + -+ (((u_int) c1) << 8) + - (((u_int) c2) << 16) + - (((u_int) c3) << 24); - } -diff -ruN xv-3.10a-bugfixes/xvbrowse.c xv-3.10a-enhancements/xvbrowse.c ---- xv-3.10a-bugfixes/xvbrowse.c 2004-05-16 18:01:25.000000000 -0700 -+++ xv-3.10a-enhancements/xvbrowse.c 2005-04-25 23:30:27.000000000 -0700 -@@ -24,6 +24,10 @@ - typedef unsigned int mode_t; /* file mode bits */ - #endif - -+#ifndef MAX -+# define MAX(a,b) (((a)>(b))?(a):(b)) /* used only for wheelmouse support */ -+#endif -+ - - /* load up built-in icons */ - #include "bits/br_file" -@@ -36,6 +40,7 @@ - #include "bits/br_error" - /* #include "bits/br_unknown" commented out (near line 492) */ - #include "bits/br_cmpres" -+#include "bits/br_bzip2" - - #include "bits/br_gif" - #include "bits/br_pm" -@@ -50,11 +55,20 @@ - #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_zx" /* [JCE] The Spectrum+3 icon */ -+#include "bits/br_mag" -+#include "bits/br_maki" -+#include "bits/br_pic" -+#include "bits/br_pi" -+#include "bits/br_pic2" -+#include "bits/br_mgcsfx" - - #include "bits/br_trash" - #include "bits/fcurs" -@@ -94,14 +108,23 @@ - #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_ZX 29 /* [JCE] Spectrum SCREEN$ */ -+#define BF_PCD 30 -+#define BF_BZIP2 31 -+#define JP_EXT_BF (BF_BZIP2) -+#define BF_MAG (JP_EXT_BF + 1) -+#define BF_MAKI (JP_EXT_BF + 2) -+#define BF_PIC (JP_EXT_BF + 3) -+#define BF_PI (JP_EXT_BF + 4) -+#define BF_PIC2 (JP_EXT_BF + 5) -+#define BF_MGCSFX (JP_EXT_BF + 6) -+#define JP_EXT_BF_END (BF_MGCSFX) -+#define BF_MAX (JP_EXT_BF_END + 1) /* # of built-in icons */ - - #define ISLOADABLE(ftyp) (ftyp!=BF_DIR && ftyp!=BF_CHR && ftyp!=BF_BLK && \ - ftyp!=BF_SOCK && ftyp!=BF_FIFO) - --#define DEF_BROWWIDE 615 /* default size of window */ --#define DEF_BROWHIGH 356 -- - #define SCROLLVERT 8 /* height of scroll region at top/bottom of iconw */ - #define PAGEVERT 40 /* during rect drag, if further than this, page */ - -@@ -113,16 +136,35 @@ - #define BOTMARGIN 58 /* room for a row of buttons and a line of text */ - #define LRMARGINS 5 /* left and right margins */ - --#define ISIZE_WIDE 80 /* maximum size of an icon */ --#define ISIZE_HIGH 60 -+/* some people like bigger icons; 4:3 aspect ratio is recommended -+ * (NOTE: standard XV binaries will not be able to read larger icons!) */ -+#ifndef ISIZE_WIDE -+# define ISIZE_WIDE 80 /* maximum size of an icon */ -+#endif -+#ifndef ISIZE_HIGH -+# define ISIZE_HIGH 60 -+#endif - --#define ISPACE_WIDE (ISIZE_WIDE+16) /* icon spacing */ -+#ifndef ISIZE_WPAD -+# define ISIZE_WPAD 16 /* extra horizontal padding between icons */ -+#endif -+ -+#ifndef INUM_WIDE -+# define INUM_WIDE 6 /* size initial window to hold this many icons */ -+#endif -+#ifndef INUM_HIGH -+# define INUM_HIGH 3 -+#endif -+ -+#define ISPACE_WIDE (ISIZE_WIDE+ISIZE_WPAD) /* icon spacing */ - #define ISPACE_TOP 4 /* dist btwn top of ISPACE and ISIZE */ - #define ISPACE_TTOP 4 /* dist btwn bot of icon and title */ - #define ISPACE_HIGH (ISIZE_HIGH+ISPACE_TOP+ISPACE_TTOP+16+4) - - #define DBLCLICKTIME 300 /* milliseconds */ - -+#define COUNT(x) (sizeof (x) / sizeof (x)[0]) -+ - /* button/menu indicies */ - #define BR_CHDIR 0 - #define BR_DELETE 1 -@@ -140,12 +182,23 @@ - #define BR_NBUTTS 13 /* # of command buttons */ - #define BR_SEP1 13 /* separator */ - #define BR_HIDDEN 14 -+#ifdef AUTO_EXPAND -+#define BR_CLEARVD 15 -+#define BR_SELFILES 16 -+#define BR_NCMDS 17 /* # of menu commands */ -+#else - #define BR_SELFILES 15 - #define BR_NCMDS 16 /* # of menu commands */ -+#endif - - #define BUTTW 80 - #define BUTTH 24 - -+/* original size of window was 615 x 356 (for 80x60 thumbnails in 6x3 array) */ -+#define DEF_BROWWIDE (ISPACE_WIDE * INUM_WIDE + LRMARGINS * 2 + 29) -+#define DEF_BROWHIGH (ISPACE_HIGH * INUM_HIGH + BUTTH * 2 + 16 + 28) -+/* last number is a fudge--e.g., extra spaces, borders, etc. -----^ */ -+ - static char *showHstr = "Show hidden files"; - static char *hideHstr = "Hide 'hidden' files"; - -@@ -164,6 +217,9 @@ - "Close window\t^c", - MBSEP, - "Show hidden files", /* no equiv */ -+#ifdef AUTO_EXPAND -+ "Clear virtual directory", -+#endif - "Select files...\t^f" - }; - -@@ -209,6 +265,13 @@ - } BROWINFO; - - -+/* keep track of last icon visible in each path */ -+typedef struct IVIS IVIS; -+ struct IVIS { IVIS *next; -+ char *name; -+ int icon; -+ }; -+ - static Cursor movecurs, copycurs, delcurs; - static BROWINFO binfo[MAXBRWIN]; - static Pixmap bfIcons[BF_MAX], trashPix; -@@ -294,10 +357,16 @@ - static void cp_special PARM((struct stat *, int)); - static void cp_fifo PARM((struct stat *, int)); - -+#ifdef AUTO_EXPAND -+static int stat2bf PARM((u_int, char *)); -+#else - static int stat2bf PARM((u_int)); -+#endif - - static int selmatch PARM((char *, char *)); - static int selmatch1 PARM((char *, char *)); -+static void recIconVisible PARM((char *, int)); -+static void restIconVisible PARM((BROWINFO *)); - - - -@@ -511,9 +580,10 @@ - bfIcons[BF_JFIF]=MakePix1(br->win,br_jfif_bits,br_jfif_width,br_jfif_height); - bfIcons[BF_TIFF]=MakePix1(br->win,br_tiff_bits,br_tiff_width,br_tiff_height); - bfIcons[BF_PDS] =MakePix1(br->win,br_pds_bits, br_pds_width, br_pds_height); -- -- bfIcons[BF_COMPRESS]= MakePix1(br->win, br_cmpres_bits, -- br_cmpres_width, br_cmpres_height); -+ bfIcons[BF_COMPRESS] = MakePix1(br->win, br_cmpres_bits, -+ br_cmpres_width, br_cmpres_height); -+ bfIcons[BF_BZIP2] = MakePix1(br->win, br_bzip2_bits, -+ br_bzip2_width, br_bzip2_height); - - bfIcons[BF_PS] =MakePix1(br->win,br_ps_bits, br_ps_width, br_ps_height); - bfIcons[BF_IFF] =MakePix1(br->win,br_iff_bits, br_iff_width, br_iff_height); -@@ -524,6 +594,16 @@ - 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_ZX] =MakePix1(br->win,br_zx_bits, br_zx_width, br_zx_height); -+ bfIcons[BF_PCD] =MakePix1(br->win,br_pcd_bits, br_pcd_width, br_pcd_height); -+ bfIcons[BF_MAG] =MakePix1(br->win,br_mag_bits, br_mag_width, br_mag_height); -+ bfIcons[BF_MAKI]=MakePix1(br->win,br_maki_bits,br_maki_width,br_maki_height); -+ bfIcons[BF_PIC] =MakePix1(br->win,br_pic_bits, br_pic_width, br_pic_height); -+ bfIcons[BF_PI] =MakePix1(br->win,br_pi_bits, br_pi_width, br_pi_height); -+ bfIcons[BF_PIC2]=MakePix1(br->win,br_pic2_bits,br_pic2_width,br_pic2_height); -+ bfIcons[BF_MGCSFX] = MakePix1(br->win,br_mgcsfx_bits, -+ br_mgcsfx_width,br_mgcsfx_height); - - - /* check that they all got built */ -@@ -698,6 +778,9 @@ - } - } - -+#ifdef VS_RESCMAP -+static int _IfTempOut=0; -+#endif - - /***************************************************************/ - void KillBrowseWindows() -@@ -730,7 +813,6 @@ - return 0; - } - -- - /***************************************************************/ - static int brChkEvent(br, xev) - BROWINFO *br; -@@ -745,15 +827,32 @@ - - if (!hasBeenSized) return 0; /* ignore evrythng until we get 1st Resize */ - -+ -+#ifdef VS_RESCMAP -+ /* force change color map if have LocalCmap */ -+ if (browPerfect && browCmap && (_IfTempOut==2)) { -+ int i; -+ XSetWindowAttributes xswa; -+ -+ xswa.colormap = LocalCmap? LocalCmap : theCmap; -+ for (i=0; i<MAXBRWIN; ++i) -+ XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa); -+ XFlush(theDisp); -+ _IfTempOut=1; -+ } -+#endif -+ - 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 redraws for 'dumb' windows */ -- if (e->count > 0 && (e->window == br->scrl.win)) {} -+ if (e->count > 0 && (e->window == br->scrl.win)) -+ ; - -- else if (e->window == br->scrl.win) SCRedraw(&(br->scrl)); -+ else if (e->window == br->scrl.win) -+ SCRedraw(&(br->scrl)); - - else if (e->window == br->win || e->window == br->iconW) { /* smart wins */ - /* group individual expose rects into a single expose region */ -@@ -806,13 +905,57 @@ - int i,x,y; - x = e->x; y = e->y; - -- if (e->button == Button1) { -+#ifdef VS_RESCMAP -+ if (browCmap && browPerfect && (_IfTempOut!=0)) -+ { -+ XSetWindowAttributes xswa; -+ _IfTempOut--; -+ xswa.colormap = browCmap; -+ for(i=0;i<MAXBRWIN;i++) -+ XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa); -+ XFlush(theDisp); -+ } -+ -+#endif -+ -+ if (e->button == Button1) { - if (e->window == br->win) clickBrow(br,x,y); - else if (e->window == br->scrl.win) SCTrack(&(br->scrl),x,y); - else if (e->window == br->iconW) { - i = clickIconWin(br, x,y,(unsigned long) e->time, - (e->state&ControlMask) || (e->state&ShiftMask)); -- -+ } -+ else rv = 0; -+ } -+ else if (e->button == Button4) { /* note min vs. max, + vs. - */ -+ /* scroll regardless of where we are in the browser window */ -+ if (e->window == br->win || -+ e->window == br->scrl.win || -+ e->window == br->iconW) -+ { -+ SCRL *sp=&(br->scrl); -+ int halfpage=MAX(1,sp->page/2); /* user resize to 1 line? */ -+ -+ if (sp->val > sp->min+halfpage) -+ SCSetVal(sp,sp->val-halfpage); -+ else -+ SCSetVal(sp,sp->min); -+ } -+ else rv = 0; -+ } -+ else if (e->button == Button5) { /* note max vs. min, - vs. + */ -+ /* scroll regardless of where we are in the browser window */ -+ if (e->window == br->win || -+ e->window == br->scrl.win || -+ e->window == br->iconW) -+ { -+ SCRL *sp=&(br->scrl); -+ int halfpage=MAX(1,sp->page/2); /* user resize to 1 line? */ -+ -+ if (sp->val < sp->max-halfpage) -+ SCSetVal(sp,sp->val+halfpage); -+ else -+ SCSetVal(sp,sp->max); - } - else rv = 0; - } -@@ -1101,6 +1244,10 @@ - case BR_SELFILES: doSelFilesCmd(br); break; - - case BR_RECURSUP: doRecurseCmd(br); break; -+ -+#ifdef AUTO_EXPAND -+ case BR_CLEARVD: Vdsettle(); break; -+#endif - } - } - -@@ -1250,6 +1397,18 @@ - int i, allowtext; - - if (!nostr) setSelInfoStr(br, sel); -+#ifdef AUTO_EXPAND -+ if (Isvdir(br->path)) { -+ BTSetActive(&br->but[BR_DELETE], 0); -+ br->cmdMB.dim[BR_DELETE] = 1; -+ -+ BTSetActive(&br->but[BR_RENAME], 0); -+ br->cmdMB.dim[BR_RENAME] = 1; -+ -+ BTSetActive(&br->but[BR_MKDIR], 0); -+ br->cmdMB.dim[BR_MKDIR] = 1; -+ } else { -+#endif - BTSetActive(&br->but[BR_DELETE], br->numlit>0); - br->cmdMB.dim[BR_DELETE] = !(br->numlit>0); - -@@ -1258,6 +1417,11 @@ - - BTSetActive(&br->but[BR_GENICON], br->numlit>0); - br->cmdMB.dim[BR_GENICON] = !(br->numlit>0); -+#ifdef AUTO_EXPAND -+ BTSetActive(&br->but[BR_MKDIR], 1); -+ br->cmdMB.dim[BR_MKDIR] = 0; -+ } -+#endif - - /* turn on 'text view' cmd if exactly one non-dir is lit */ - allowtext = 0; -@@ -1318,8 +1482,11 @@ - struct stat st; - - sprintf(buf, "%s%s", br->path, bf->name); /* build filename */ -+#ifdef AUTO_EXPAND -+ Dirtovd(buf); -+#endif - if (stat(buf, &st) == 0) { -- sprintf(buf, "%s: %ld bytes", bf->name, st.st_size); -+ sprintf(buf, "%s: %ld bytes", bf->name, (long)st.st_size); - strcat(buf, buf1); - } - } -@@ -1598,6 +1765,10 @@ - { - int sval, first, numvis; - -+ /* if we know what path we have, remember last visible icon for this path */ -+ if (br->path) -+ recIconVisible(br->path, num); -+ - /* if icon #i isn't visible, adjust scrollbar so it *is* */ - - sval = br->scrl.val; -@@ -1649,29 +1820,14 @@ - return; - } - -- - /***************************************************************/ --static int clickIconWin(br, mx, my, mtime, multi) -- BROWINFO *br; -- int mx,my,multi; -- unsigned long mtime; -+static int updateSel(br, sel, multi, mtime) -+ BROWINFO *br; -+ int sel, multi; -+ unsigned long mtime; - { -- /* returns '-1' normally, returns an index into bfList[] if the user -- double-clicks an icon */ -- -- int i,j, rv, sel, cpymode, dodel; -- BROWINFO *destBr; -- BFIL *bf; -- char buf[256], *destFolderName; -- -- rv = -1; /* default return value */ -- if (!br->bfList || !br->bfLen) return rv; -- -- destBr = br; destFolderName = "."; -- -- sel = mouseInWhichIcon(br, mx, my); -- -- dodel = 0; -+ int i; -+ BFIL *bf; - - if (sel == -1) { /* clicked on nothing */ - if (!multi) { /* deselect all */ -@@ -1728,11 +1884,12 @@ - - - /* see if we've double-clicked something */ -- if (sel==br->lastIconClicked && mtime-br->lastClickTime < DBLCLICKTIME) { -+ if (mtime && -+ sel==br->lastIconClicked && mtime-br->lastClickTime < DBLCLICKTIME) { - br->lastIconClicked = -1; /* YES */ - - doubleClick(br, sel); -- return rv; -+ return -1; - } - - else { -@@ -1741,9 +1898,36 @@ - } - } - -- - changedNumLit(br, -1, 0); -+ return 0; -+} -+ - -+/***************************************************************/ -+static int clickIconWin(br, mx, my, mtime, multi) -+ BROWINFO *br; -+ int mx,my,multi; -+ unsigned long mtime; -+{ -+ /* returns '-1' normally, returns an index into bfList[] if the user -+ double-clicks an icon */ -+ -+ int i,j, sel, cpymode, dodel; -+ BROWINFO *destBr; -+ BFIL *bf; -+ char buf[256], *destFolderName; -+ -+ if (!br->bfList || !br->bfLen) return -1; -+ -+ destBr = br; destFolderName = "."; -+ -+ sel = mouseInWhichIcon(br, mx, my); -+ dodel = 0; -+ -+ recIconVisible(br->path, sel); -+ -+ if (updateSel(br, sel, multi, mtime)) -+ return -1; - - - { /* track mouse until button1 is released */ -@@ -2098,7 +2282,7 @@ - } - } /* end of 'tracking' sub-function */ - -- return rv; -+ return -1; - } - - /*******************************************/ -@@ -2164,15 +2348,35 @@ - else sprintf(buf, "%s%s", br->path, br->bfList[sel].name); - #endif - -+#ifdef AUTO_EXPAND -+ if (Chvdir(buf)) { -+#else - if (chdir(buf)) { -+#endif - char str[512]; - sprintf(str,"Unable to cd to '%s'\n", br->bfList[sel].name); - setBrowStr(br, str); - XBell(theDisp, 50); - } - else { -+#ifdef AUTO_EXPAND -+ if (Isvdir(buf)) { -+ BTSetActive(&br->but[BR_DELETE], 0); -+ br->cmdMB.dim[BR_DELETE] = 1; -+ -+ BTSetActive(&br->but[BR_RENAME], 0); -+ br->cmdMB.dim[BR_RENAME] = 1; -+ -+ BTSetActive(&br->but[BR_MKDIR], 0); -+ br->cmdMB.dim[BR_MKDIR] = 1; -+ } else { -+ BTSetActive(&br->but[BR_MKDIR], 1); -+ br->cmdMB.dim[BR_MKDIR] = 0; -+ } -+#endif - scanDir(br); - SCSetVal(&(br->scrl), 0); /* reset to top on a chdir */ -+ restIconVisible(br); - } - } - -@@ -2193,6 +2397,28 @@ - } - else { *event_retP = LOADPIC; SetDirFName(buf); } - -+#ifdef VS_RESCMAP -+ /* Change Colormap for browser */ -+ if (browPerfect && browCmap) -+ { -+ int i; -+ XSetWindowAttributes xswa; -+ if(LocalCmap) -+ { -+ xswa.colormap = LocalCmap; -+ _IfTempOut=2; -+ } -+ else -+ { -+ xswa.colormap = theCmap; -+ _IfTempOut=2; -+ } -+ for(i=0;i<MAXBRWIN;i++) -+ XChangeWindowAttributes(theDisp, binfo[i].win, CWColormap, &xswa); -+ XFlush(theDisp); -+ } -+#endif -+ - *event_doneP = 1; /* make MainLoop load image */ - } - } -@@ -2347,6 +2573,9 @@ - - /* try to open this file */ - sprintf(foo, "%s%s", br->path, br->bfList[i].name); -+#ifdef AUTO_EXPAND -+ Dirtovd(foo); -+#endif - for (j=0; j<numnames && strcmp(namelist[j],foo); j++); - if (j<numnames) { - curname = nList.selected = j; -@@ -2362,6 +2591,9 @@ - else { /* not SPACE, or SPACE and lit=1 and not shift */ - for (i=0; i<br->bfLen && !br->bfList[i].lit; i++); /* find lit one */ - sprintf(fname, "%s%s", br->path, br->bfList[i].name); -+#ifdef AUTO_EXPAND -+ Dirtovd(fname); -+#endif - viewsel = !(strcmp(fname, fullfname)); - - if (viewsel) { -@@ -2553,7 +2785,11 @@ - } - #endif - -+#ifdef AUTO_EXPAND -+ if (Chvdir(tmppath)) { -+#else - if (chdir(tmppath)) { -+#endif - char str[512]; - sprintf(str,"Unable to cd to '%s'\n", tmppath); - MBRedraw(&(br->dirMB)); -@@ -2561,8 +2797,24 @@ - XBell(theDisp, 50); - } - else { -+#ifdef AUTO_EXPAND -+ if (Isvdir(tmppath)) { -+ BTSetActive(&br->but[BR_DELETE], 0); -+ br->cmdMB.dim[BR_DELETE] = 1; -+ -+ BTSetActive(&br->but[BR_RENAME], 0); -+ br->cmdMB.dim[BR_RENAME] = 1; -+ -+ BTSetActive(&br->but[BR_MKDIR], 0); -+ br->cmdMB.dim[BR_MKDIR] = 1; -+ } else { -+ BTSetActive(&br->but[BR_MKDIR], 1); -+ br->cmdMB.dim[BR_MKDIR] = 0; -+ } -+#endif - scanDir(br); - SCSetVal(&br->scrl, 0); /* reset to top of window on a chdir */ -+ restIconVisible(br); - } - } - } -@@ -2581,7 +2833,11 @@ - if ((strlen(br->path) > (size_t) 2) && br->path[strlen(br->path)-1] == '/') - br->path[strlen(br->path)-1] = '\0'; - -+#ifdef AUTO_EXPAND -+ rv = Chvdir(br->path); -+#else - rv = chdir(br->path); -+#endif - if (rv) { - char str[512]; - sprintf(str, "Unable to cd to '%s'\n", br->path); -@@ -2589,6 +2845,23 @@ - XBell(theDisp, 50); - } - -+#ifdef AUTO_EXPAND -+ if (Isvdir(br->path)) { -+ BTSetActive(&br->but[BR_DELETE], 0); -+ br->cmdMB.dim[BR_DELETE] = 1; -+ -+ BTSetActive(&br->but[BR_RENAME], 0); -+ br->cmdMB.dim[BR_RENAME] = 1; -+ -+ BTSetActive(&br->but[BR_MKDIR], 0); -+ br->cmdMB.dim[BR_MKDIR] = 1; -+ } else { -+ BTSetActive(&br->but[BR_MKDIR], 1); -+ br->cmdMB.dim[BR_MKDIR] = 0; -+ } -+#endif -+ -+ restIconVisible(br); - strcat(br->path, "/"); /* put trailing '/' back on */ - return rv; - } -@@ -2615,8 +2888,13 @@ - strcpy(dstbr->mblist[i], srcbr->mblist[i]); - } - -- dstbr->dirMB.list = srcbr->mblist; -+#if 0 -+ dstbr->dirMB.list = srcbr->mblist; /* original bug..? */ - dstbr->dirMB.nlist = srcbr->ndirs; -+#else -+ dstbr->dirMB.list = dstbr->mblist; /* fixed by */ -+ dstbr->dirMB.nlist = dstbr->ndirs; /* jp-extension. */ -+#endif - - XClearArea(theDisp, dstbr->dirMB.win, dstbr->dirMB.x, dstbr->dirMB.y, - dstbr->dirMB.w+3, dstbr->dirMB.h+3, False); -@@ -2974,7 +3252,11 @@ - - - if (stat(bf->name, &st)==0) { -+#ifdef AUTO_EXPAND -+ bf->ftype = stat2bf((u_int) st.st_mode , bf->name); -+#else - bf->ftype = stat2bf((u_int) st.st_mode); -+#endif - if (bf->ftype == BF_FILE && (st.st_mode & 0111)) bf->ftype = BF_EXE; - - switch (bf->ftype) { -@@ -3006,6 +3288,7 @@ - case RFT_XBM: bf->ftype = BF_XBM; break; - case RFT_SUNRAS: bf->ftype = BF_SUNRAS; break; - case RFT_BMP: bf->ftype = BF_BMP; break; -+ case RFT_WBMP: bf->ftype = BF_BMP; break; - case RFT_UTAHRLE: bf->ftype = BF_UTAHRLE; break; - case RFT_IRIS: bf->ftype = BF_IRIS; break; - case RFT_PCX: bf->ftype = BF_PCX; break; -@@ -3013,12 +3296,22 @@ - case RFT_TIFF: bf->ftype = BF_TIFF; break; - case RFT_PDSVICAR: bf->ftype = BF_PDS; break; - case RFT_COMPRESS: bf->ftype = BF_COMPRESS; break; -+ case RFT_BZIP2: bf->ftype = BF_BZIP2; break; - case RFT_PS: bf->ftype = BF_PS; break; - case RFT_IFF: bf->ftype = BF_IFF; break; - case RFT_TARGA: bf->ftype = BF_TARGA; break; - 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_ZX: bf->ftype = BF_ZX; break; /* [JCE] */ -+ case RFT_PCD: bf->ftype = BF_PCD; break; -+ case RFT_MAG: bf->ftype = BF_MAG; break; -+ case RFT_MAKI: bf->ftype = BF_MAKI; break; -+ case RFT_PIC: bf->ftype = BF_PIC; break; -+ case RFT_PI: bf->ftype = BF_PI; break; -+ case RFT_PIC2: bf->ftype = BF_PIC2; break; -+ case RFT_MGCSFX: bf->ftype = BF_MGCSFX; break; - } - } - } -@@ -3405,7 +3698,7 @@ - double wexpand,hexpand; - int iwide, ihigh; - byte *icon24, *icon8; -- char str[256], str1[256], *readname, uncompname[128]; -+ char str[256], str1[256], readname[128], uncompname[128]; - char basefname[128], *uncName; - - -@@ -3414,7 +3707,7 @@ - basefname[0] = '\0'; - pinfo.pic = (byte *) NULL; - pinfo.comment = (char *) NULL; -- readname = bf->name; -+ strncpy(readname, bf->name, sizeof(readname) - 1); - - /* free any old info in 'bf' */ - if (bf->imginfo) free (bf->imginfo); -@@ -3431,7 +3724,7 @@ - - filetype = ReadFileType(bf->name); - -- if (filetype == RFT_COMPRESS) { -+ if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) { - #if (defined(VMS) && !defined(GUNZIP)) - /* VMS decompress doesn't like the file to have a trailing .Z in fname - however, GUnZip is OK with it, which we are calling UnCompress */ -@@ -3442,9 +3735,9 @@ - uncName = bf->name; - #endif - -- if (UncompressFile(uncName, uncompname)) { -+ if (UncompressFile(uncName, uncompname, filetype)) { - filetype = ReadFileType(uncompname); -- readname = uncompname; -+ strncpy(readname, uncompname, sizeof(readname) - 1); - } - else { - sprintf(str, "Couldn't uncompress file '%s'", bf->name); -@@ -3453,6 +3746,56 @@ - } - } - -+#ifdef MACBINARY -+ if (handlemacb && macb_file == True && bf->ftype != BF_ERROR) { -+ if (RemoveMacbinary(readname, uncompname)) { -+ if (strcmp(readname, bf->name)!=0) unlink(readname); -+ strncpy(readname, uncompname, sizeof(readname) - 1); -+ } -+ else { -+ sprintf(str, "Unable to remove a InfoFile header form '%s'.", bf->name); -+ setBrowStr(br, str); -+ bf->ftype = BF_ERROR; -+ } -+ } -+#endif -+ -+#ifdef HAVE_MGCSFX_AUTO -+ if (bf->ftype != BF_ERROR) { -+ if(filetype == RFT_MGCSFX){ -+ char tmpname[128]; -+ char *icom; -+ -+ if((icom = mgcsfx_auto_input_com(bf->name)) != NULL){ -+ sprintf(tmpname, "%s/xvmsautoXXXXXX", tmpdir); -+#ifdef USE_MKSTEMP -+ close(mkstemp(tmpname)); -+#else -+ mktemp(tmpname); -+#endif -+ SetISTR(ISTR_INFO, "Converting to known format by MgcSfx auto..."); -+ sprintf(str,"%s >%s", icom, tmpname); -+ }else goto ms_auto_no; -+ -+#ifndef VMS -+ if (system(str)) -+#else -+ if (!system(str)) -+#endif -+ { -+ sprintf(str, "Unable to convert '%s' by MgcSfx auto.", bf->name); -+ setBrowStr(br, str); -+ bf->ftype = BF_ERROR; -+ } else { -+ filetype = ReadFileType(tmpname); -+ if (strcmp(readname, bf->name)!=0) unlink(readname); -+ strncpy(readname, tmpname, sizeof(readname) - 1); -+ } -+ } -+ } -+ms_auto_no: -+#endif /* HAVE_MGCSFX_AUTO */ -+ - /* get rid of comments. don't need 'em */ - if (pinfo.comment) free(pinfo.comment); pinfo.comment = (char *) NULL; - -@@ -3470,6 +3813,9 @@ - else { - /* otherwise it's a known filetype... do the *hard* part now... */ - -+#ifdef VS_ADJUST -+ normaspect = defaspect; -+#endif - i = ReadPicFile(readname, filetype, &pinfo, 1); - KillPageFiles(pinfo.pagebname, pinfo.numpages); - -@@ -3489,7 +3835,7 @@ - } - - /* if we made an uncompressed file, we can rm it now */ -- if (readname != bf->name) unlink(readname); -+ if (strcmp(readname, bf->name)!=0) unlink(readname); - - - /* at this point either BF_ERROR, BF_UNKNOWN, BF_EXE or pic */ -@@ -3507,16 +3853,30 @@ - - /* compute size of icon (iwide,ihigh) */ - -+#ifdef VS_ADJUST -+ if (!vsadjust) normaspect = 1; -+ -+ wexpand = (double) (pinfo.w * normaspect) / (double) ISIZE_WIDE; -+#else - wexpand = (double) pinfo.w / (double) ISIZE_WIDE; -+#endif /* VS_ADJUST */ - hexpand = (double) pinfo.h / (double) ISIZE_HIGH; - - if (wexpand >= 1.0 || hexpand >= 1.0) { /* don't expand small icons */ - if (wexpand>hexpand) { -+#ifdef VS_ADJUST -+ iwide = (int) ((pinfo.w * normaspect) / wexpand + 0.5); -+#else - iwide = (int) (pinfo.w / wexpand + 0.5); -+#endif - ihigh = (int) (pinfo.h / wexpand + 0.5); - } - else { -+#ifdef VS_ADJUST -+ iwide = (int) ((pinfo.w * normaspect) / hexpand + 0.5); -+#else - iwide = (int) (pinfo.w / hexpand + 0.5); -+#endif - ihigh = (int) (pinfo.h / hexpand + 0.5); - } - } -@@ -3566,6 +3926,15 @@ - 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_ZX: strcat(str,"Spectrum SCREEN$"); break; /* [JCE] */ -+ case RFT_PCD: strcat(str,"PhotoCD file"); break; -+ case RFT_MAG: strcat(str,"MAG file"); break; -+ case RFT_MAKI: strcat(str,"MAKI file"); break; -+ case RFT_PIC: strcat(str,"PIC file"); break; -+ case RFT_PI: strcat(str,"PI file"); break; -+ case RFT_PIC2: strcat(str,"PIC2 file"); break; -+ case RFT_MGCSFX: strcat(str,"Magic Suffix file"); break; - default: strcat(str,"file of unknown type"); break; - } - -@@ -3669,6 +4038,10 @@ - - sprintf(thFname, "%s%s/%s", br->path, THUMBDIR, bf->name); - -+#ifdef AUTO_EXPAND -+ Dirtovd(thFname); -+#endif -+ - fp = fopen(thFname, "r"); - if (!fp) return; /* nope, it doesn't have one */ - -@@ -3784,6 +4157,11 @@ - - sprintf(thFname, "%s%s/%s", br->path, THUMBDIR, bf->name); - -+#ifdef AUTO_EXPAND -+ Dirtovd(thFname); -+#endif -+ -+ unlink(thFname); /* just in case there's already an unwritable one */ - fp = fopen(thFname, "w"); - if (!fp) { - sprintf(buf, "Can't create thumbnail file '%s': %s", thFname, -@@ -3848,15 +4226,30 @@ - - sprintf(thFname, "%s%s", br->path, THUMBDIRNAME); - -+#ifdef AUTO_EXPAND -+ Dirtovd(thFname); -+#endif -+ - i = stat(thFname, &st); - if (i) { /* failed, let's create it */ - sprintf(thFname, "%s.", br->path); -+#ifdef AUTO_EXPAND -+ Dirtovd(thFname); -+#endif - i = stat(thFname, &st); /* get permissions of parent dir */ - if (!i) perm = st.st_mode & 07777; - else perm = 0755; - - sprintf(thFname, "%s%s", br->path, THUMBDIRNAME); -+#ifdef AUTO_EXPAND -+ Dirtovd(thFname); -+# ifdef VIRTUAL_TD -+ if (mkdir(thFname, (mode_t) perm) < 0) -+ Mkvdir_force(thFname); -+# else - mkdir(thFname, (mode_t) perm); -+# endif -+#endif - } - } - -@@ -3898,7 +4291,7 @@ - for (i=0, bf=br->bfList; i<br->bfLen; i++, bf++) { - if (bf->ftype <= BF_FILE || bf->ftype >= BF_ERROR || bf->ftype==BF_EXE) { - -- /* ie, not a 'special' file */ -+ /* i.e., not a 'special' file */ - - int s1, s2; - char thfname[256]; -@@ -3912,10 +4305,9 @@ - sprintf(thfname, "%s/%s", THUMBDIR, bf->name); - s2 = stat(thfname, &thumbst); - -- if (s1 || s2 || filest.st_mtime > thumbst.st_mtime || -- filest.st_ctime > thumbst.st_ctime) { -+ if (s1 || s2 || filest.st_mtime > thumbst.st_mtime) { - /* either stat'ing the file or the thumbfile failed, or -- both stat's succeeded and the file has a newer mod or creation -+ both stat's succeeded and the file has a newer mod - time than the thumbnail file */ - - makeIconVisible(br, i); -@@ -3927,8 +4319,12 @@ - iconsBuilt++; - if (DEBUG) - fprintf(stderr,"icon made:fname='%s' thfname='%s' %d,%d,%ld,%ld\n", -- bf->name, thfname, s1,s2,filest.st_mtime,thumbst.st_mtime); -+ bf->name, thfname, s1, s2, -+ (long)filest.st_mtime, (long)thumbst.st_mtime); - } -+ } else if (filest.st_ctime > thumbst.st_ctime) { -+ /* update protections */ -+ chmod(thfname, (mode_t) (filest.st_mode & 07777)); - } - } - statcount++; -@@ -3963,7 +4359,11 @@ - sprintf(thfname, "%s/%s", THUMBDIR, dp->d_name); - if (stat(thfname, &thumbst)==0) { /* success */ - int tmp; -+#ifdef AUTO_EXPAND -+ tmp = stat2bf((u_int) thumbst.st_mode , thfname); -+#else - tmp = stat2bf((u_int) thumbst.st_mode); -+#endif - - if (tmp == BF_FILE) { /* a plain file */ - /* see if this thumbfile has an associated pic file */ -@@ -4042,6 +4442,15 @@ - static char *labels[] = { "\nOk", "\033Cancel" }; - struct stat st; - -+#ifdef AUTO_EXPAND -+ if (Isvdir(br->path)) { -+ sprintf(buf,"Sorry, you can't rename file in the virtual directory, '%s'", -+ br->path); -+ ErrPopUp(buf, "\nBummer!"); -+ return; -+ } -+#endif -+ - if (cdBrow(br)) return; - - /* find the selected file */ -@@ -4129,6 +4538,15 @@ - static char *labels[] = { "\nOk", "\033Cancel" }; - struct stat st; - -+#ifdef AUTO_EXPAND -+ if (Isvdir(br->path)) { -+ sprintf(buf,"Sorry, you can't mkdir in the virtual directory, '%s'", -+ br->path); -+ ErrPopUp(buf, "\nBummer!"); -+ return; -+ } -+#endif -+ - if (cdBrow(br)) return; - - buf[0] = '\0'; -@@ -4197,14 +4615,34 @@ - if (cdBrow(br)) return; /* prints its own error message */ - } - -+#ifdef AUTO_EXPAND -+ if (Chvdir(buf)) { -+#else - if (chdir(buf)) { -+#endif - sprintf(str,"Unable to cd to '%s'\n", buf); - setBrowStr(br, str); - XBell(theDisp, 50); - } - else { -+#ifdef AUTO_EXPAND -+ if (Isvdir(buf)) { -+ BTSetActive(&br->but[BR_DELETE], 0); -+ br->cmdMB.dim[BR_DELETE] = 1; -+ -+ BTSetActive(&br->but[BR_RENAME], 0); -+ br->cmdMB.dim[BR_RENAME] = 1; -+ -+ BTSetActive(&br->but[BR_MKDIR], 0); -+ br->cmdMB.dim[BR_MKDIR] = 1; -+ } else { -+ BTSetActive(&br->but[BR_MKDIR], 1); -+ br->cmdMB.dim[BR_MKDIR] = 0; -+ } -+#endif - scanDir(br); - SCSetVal(&(br->scrl), 0); /* reset to top on a chdir */ -+ restIconVisible(br); - } - } - -@@ -4229,6 +4667,15 @@ - char buf[512]; - static char *yesno[] = { "\004Delete", "\033Cancel" }; - -+#ifdef AUTO_EXPAND -+ if (Isvdir(br->path)) { -+ sprintf(buf,"Sorry, you can't delete file at the virtual directory, '%s'", -+ br->path); -+ ErrPopUp(buf, "\nBummer!"); -+ return; -+ } -+#endif -+ - if (!br->bfLen || !br->bfList || !br->numlit) return; - - if (cdBrow(br)) return; /* can't cd to this directory. screw it! */ -@@ -4251,7 +4698,11 @@ - for (i=0, bf=br->bfList; i<br->bfLen; i++,bf++) { - if (bf->lit) { - if (firstdel == -1) firstdel = i; -- if (bf->ftype == BF_DIR) numdirs++; -+ if (bf->ftype == BF_DIR -+#ifdef AUTO_EXPAND -+ && (!Isarchive(bf->name)) -+#endif -+ ) numdirs++; - else numfiles++; - } - } -@@ -4265,7 +4716,12 @@ - slen = strlen(buf); - - for (i=0, bf=br->bfList; i<br->bfLen; i++,bf++) { -+#ifdef AUTO_EXPAND -+ if (bf->lit && (bf->ftype != BF_DIR || Isarchive(bf->name))) { -+#else - if (bf->lit && bf->ftype != BF_DIR) { -+#endif -+ - if ( (slen + strlen(bf->name) + 1) > 256) { - strcat(buf,"..."); - break; -@@ -4277,7 +4733,7 @@ - } - } - -- i = PopUp(buf, yesno, 2); -+ i = PopUp(buf, yesno, COUNT(yesno)); - if (i) return; /* cancelled */ - } - -@@ -4290,7 +4746,11 @@ - slen = strlen(buf); - - for (i=0, bf=br->bfList; i<br->bfLen; i++,bf++) { -+#ifdef AUTO_EXPAND -+ if (bf->lit && (bf->ftype == BF_DIR || !Isarchive(bf->name))) { -+#else - if (bf->lit && bf->ftype == BF_DIR) { -+#endif - if ( (slen + strlen(bf->name) + 1) > 256) { - strcat(buf,"..."); - break; -@@ -4302,7 +4762,7 @@ - } - } - -- i = PopUp(buf, yesno, 2); -+ i = PopUp(buf, yesno, COUNT(yesno)); - if (i) return; /* cancelled */ - } - -@@ -4311,7 +4771,11 @@ - - for (i=0, bf=br->bfList; i<br->bfLen; i++,bf++) { - if (bf->lit) { -- if (bf->ftype == BF_DIR) rm_dir (br, bf->name); -+ if (bf->ftype == BF_DIR -+#ifdef AUTO_EXPAND -+ && !Isarchive(bf->name) -+#endif -+ ) rm_dir (br, bf->name); - else rm_file(br, bf->name); - } - } -@@ -4440,7 +4904,11 @@ - xv_getwd(orgDir, sizeof(orgDir)); - - sprintf(curDir, "%s%s", br->path, subdir); -+#ifdef AUTO_EXPAND -+ if (Chvdir(curDir)) { -+#else - if (chdir(curDir)) { -+#endif - char str[512]; - sprintf(str, "Unable to cd to '%s'\n", curDir); - setBrowStr(br, str); -@@ -4452,14 +4920,24 @@ - /* have we looped? */ - for (i=0; i<dirStackLen && strcmp(curDir, dirStack[i]); i++); - if (i<dirStackLen) { /* YES */ -+#ifdef AUTO_EXPAND -+ Chvdir(orgDir); -+#else - chdir(orgDir); -+#endif -+ restIconVisible(br); - return; - } - - sp = (char *) malloc((size_t) strlen(curDir) + 1); - if (!sp) { - setBrowStr(br, "malloc() error in recurseUpdate()\n"); -+#ifdef AUTO_EXPAND -+ Chvdir(orgDir); -+#else - chdir(orgDir); -+#endif -+ restIconVisible(br); - return; - } - -@@ -4494,7 +4972,12 @@ - - xv_getwd(curDir, sizeof(curDir)); - if (strcmp(orgDir, curDir)) { /* change back to orgdir */ -+#ifdef AUTO_EXPAND -+ Chvdir(orgDir); -+#else - chdir(orgDir); -+#endif -+ restIconVisible(br); - scanDir(br); - } - } -@@ -4518,6 +5001,13 @@ - setBrowStr(br, buf); - } - -+#ifdef AUTO_EXPAND -+ if (Rmvdir(name)) { -+ sprintf(buf, "fail to remove virturl directory: %s", name); -+ setBrowStr(br, buf); -+ } -+#endif -+ - /* try to delete a thumbnail file, as well. ignore errors */ - strcpy(buf1, name); /* tmp1 = leading path of name */ - tmp = (char *) rindex(buf1, '/'); -@@ -4586,7 +5076,14 @@ - goto done; - } - -- if (stat2bf((u_int) st.st_mode) == BF_DIR) { /* skip, for now */ -+#ifdef AUTO_EXPAND -+ if ((stat2bf((u_int) st.st_mode , rmdirPath) == BF_DIR) -+ && !Isarchive(rmdirPath)) /* skip, for now */ -+#else -+ -+ if (stat2bf((u_int) st.st_mode) == BF_DIR) /* skip, for now */ -+#endif -+ { - rmdirPath[oldpathlen] = '\0'; - continue; /* don't remove from list */ - } -@@ -4639,9 +5136,9 @@ - - static int overwrite; - #define OWRT_ASK 0 --#define OWRT_NOASK 1 --#define OWRT_CANCEL 2 -- -+#define OWRT_ALWAYS 1 -+#define OWRT_NEVER 2 -+#define OWRT_CANCEL 3 - - /*******************************************/ - static void dragFiles(srcBr, dstBr, srcpath, dstpath, dstdir, -@@ -4676,11 +5173,26 @@ - } - else if (strcmp(dstdir,".")!=0) sprintf(dstp, "%s%s/", dstpath, dstdir); - -+#ifdef AUTO_EXPAND -+ if (Isvdir(dstp)) { -+ sprintf(buf,"Sorry, you can't %s to the virtual directory, '%s'", -+ cpymode ? "copy" : "move", dstp); -+ ErrPopUp(buf, "\nBummer!"); -+ SetCursors(-1); -+ return; -+ } -+ if (Isvdir(srcpath)) -+ cpymode = 1; -+#endif -+ - - - /* if there is a thumbnail directory in 'srcpath', make one for dstpath */ - sprintf(src,"%s%s", srcpath, THUMBDIR); - dothumbs = 0; -+#ifdef AUTO_EXPAND -+ Dirtovd(src); -+#endif - if (stat(src, &st)==0) { - sprintf(dst,"%s%s", dstp, THUMBDIR); - mkdir(dst, st.st_mode & 07777); -@@ -4711,6 +5223,14 @@ - if (overwrite == OWRT_CANCEL) break; /* abort move */ - if (j==1) fail++; - -+#ifdef AUTO_EXPAND -+ if (!cpymode && j==0) -+ if (Movevdir(src,dst)) { -+ sprintf(buf, "fail to move virturl directory: %s", names[i]); -+ setBrowStr(srcBr, buf); -+ } -+#endif -+ - if (dothumbs && j==0) { - sprintf(src,"%s%s/%s", srcpath, THUMBDIR, names[i]); - sprintf(dst,"%s%s/%s", dstp, THUMBDIR, names[i]); -@@ -4748,6 +5268,15 @@ - } - - -+ 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 */ - for (i=0; i<dstBr->bfLen; i++) { - dstBr->bfList[i].lit = 0; -@@ -4793,7 +5322,51 @@ - SetCursors(-1); - } - -+static int recursive_remove(dir) -+ char *dir; -+{ -+ DIR *dp = NULL; -+ struct dirent *di; -+ char name[MAXPATHLEN+1]; -+ -+ strncpy(name, dir, MAXPATHLEN); -+ name[MAXPATHLEN] = 0; -+ -+ if (name[strlen(name) - 1] == '/') -+ name[strlen(name) - 1] = 0; - -+ if ((dp = opendir(name)) == NULL) -+ goto err; -+ -+ while ((di = readdir(dp)) != NULL) { -+ char buf[MAXPATHLEN+1]; -+ struct stat st; -+ -+ if (!strcmp(di->d_name, ".") || !strcmp(di->d_name, "..")) -+ continue; -+ -+ snprintf(buf, MAXPATHLEN, "%s/%s", name, di->d_name); -+ -+ if (stat(buf, &st) < 0) -+ continue; -+ -+ if (S_ISDIR(st.st_mode)) { -+ if (recursive_remove(buf) < 0) -+ goto err; -+ } else -+ unlink(buf); -+ } -+ -+ if (rmdir(name) < 0) -+ goto err; -+ -+ closedir(dp); -+ return 0; -+ -+err: -+ if (dp) closedir(dp); -+ return -1; -+} - - /*************************************************/ - static int moveFile(src,dst) -@@ -4811,31 +5384,45 @@ - int i, srcdir, dstdir; - struct stat st; - char buf[512]; -- static char *owbuts[4] = { "\nOk", "dDon't ask", "nNo", "\033Cancel" }; -+ static char *owbuts[] = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" }; - - if (DEBUG) fprintf(stderr,"moveFile %s %s\n", src, dst); - -+#ifdef AUTO_EXPAND -+ Dirtosubst(src); -+#endif -+ - if (stat(src, &st)) return 0; /* src doesn't exist, it would seem */ -+#ifdef AUTO_EXPAND -+ srcdir = (stat2bf((u_int) st.st_mode , src) == BF_DIR); -+#else - srcdir = (stat2bf((u_int) st.st_mode) == BF_DIR); -+#endif - - /* see if destination exists */ -+ - if (stat(dst, &st)==0) { -+ if (overwrite==OWRT_NEVER) return -1; -+#ifdef AUTO_EXPAND -+ dstdir = (stat2bf((u_int) st.st_mode , dst) == BF_DIR); -+#else - dstdir = (stat2bf((u_int) st.st_mode) == BF_DIR); -+#endif - - if (overwrite==OWRT_ASK) { -- sprintf(buf, "%s '%s' exists.\n\nOverwrite?", -+ snprintf(buf, sizeof(buf), "%s '%s' exists.\n\nOverwrite?", - dstdir ? "Directory" : "File", dst); -- i = PopUp(buf, owbuts, 4); -- -- if (i==1) overwrite = OWRT_NOASK; -- else if (i==2) return -1; -- else if (i==3) { overwrite = OWRT_CANCEL; return 1; } -+ switch (PopUp(buf, owbuts, COUNT(owbuts))) { -+ case 1: overwrite = OWRT_ALWAYS; break; -+ case 2: return -1; -+ case 3: overwrite = OWRT_NEVER; return -1; -+ case 4: overwrite = OWRT_CANCEL; return 1; -+ } - } - - if (dstdir) { - #ifndef VMS /* we don't delete directories in VMS */ -- sprintf(buf, "rm -rf %s", dst); -- if (system(buf)) { /* okay, so it's cheating... */ -+ if (recursive_remove(dst)) { /* okay, so it's cheating... */ - SetISTR(ISTR_WARNING, "Unable to remove directory %s", dst); - return 1; - } -@@ -4858,9 +5445,8 @@ - if (i == 0) { /* copied okay, kill the original */ - if (srcdir) { - #ifndef VMS /* we don't delete directories in VMS */ -- sprintf(buf, "rm -rf %s", src); -- if (system(buf)) { /* okay, so it's cheating... */ -- SetISTR(ISTR_WARNING, "Unable to remove directory %s", dst); -+ if (recursive_remove(src)) { /* okay, so it's cheating... */ -+ SetISTR(ISTR_WARNING, "Unable to remove directory %s", src); - return 1; - } - #endif /* VMS */ -@@ -4906,38 +5492,51 @@ - fall through: if dest doesn't exist, copy the directory, recurs */ - - -- int i, dstExists, srcdir, dstdir; -+ int dstExists, srcdir, dstdir; - struct stat srcSt, dstSt; - char buf[1024]; -- static char *owdiff[3] = { "\nOk", "nNo", "\033Cancel" }; -- static char *owsame[4] = { "\nOk", "dDon't Ask", "nNo", "\033Cancel" }; -+ static char *owdiff[] = { "\nOk", "nNo", "\033Cancel" }; -+ static char *owsame[] = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" }; - - if (DEBUG) fprintf(stderr,"copyFile %s %s\n", src, dst); - -+#ifdef AUTO_EXPAND -+ Dirtosubst(src); -+#endif -+ - if (stat(src,&srcSt)) return 0; /* source doesn't exist, it would seem */ - - dstExists = (stat(dst, &dstSt)==0); - - if (dstExists) { /* ask about overwriting... */ -- srcdir = (stat2bf((u_int) srcSt.st_mode) == BF_DIR); -- dstdir = (stat2bf((u_int) dstSt.st_mode) == BF_DIR); -+#ifdef AUTO_EXPAND -+ srcdir = (stat2bf((u_int) srcSt.st_mode , src) == BF_DIR); -+ dstdir = (stat2bf((u_int) dstSt.st_mode , dst) == BF_DIR); -+#else -+ srcdir = (stat2bf((u_int) srcSt.st_mode) == BF_DIR); -+ dstdir = (stat2bf((u_int) dstSt.st_mode) == BF_DIR); -+#endif - - sprintf(buf, "%s '%s' already exists. Replace it with %s '%s'?", - (dstdir) ? "Directory" : "File", dst, - (srcdir) ? "contents of directory" : "file", src); - - if (srcdir == dstdir) { -+ if (overwrite==OWRT_NEVER) return -1; - if (overwrite==OWRT_ASK) { -- i = PopUp(buf, owsame, 4); -- if (i==1) overwrite = OWRT_NOASK; -- if (i==2) return -1; -- else if (i==3) { overwrite = OWRT_CANCEL; return 1; } -+ switch (PopUp(buf, owsame, COUNT(owsame))) { -+ case 1: overwrite = OWRT_ALWAYS; break; -+ case 2: return -1; -+ case 3: overwrite = OWRT_NEVER; return -1; -+ case 4: overwrite = OWRT_CANCEL; return 1; -+ } - } - } - else { /* one's a dir, the other's a file. *ALWAYS* ask! */ -- i = PopUp(buf, owdiff, 3); -- if (i==1) return -1; -- else if (i==2) { overwrite = OWRT_CANCEL; return 1; } -+ switch (PopUp(buf, owdiff, COUNT(owdiff))) { -+ case 1: return -1; -+ case 2: overwrite = OWRT_CANCEL; return 1; -+ } - } - - -@@ -5035,8 +5634,11 @@ - havedst = 1; - } - -- -+#ifdef AUTO_EXPAND -+ switch(stat2bf((u_int) srcSt.st_mode , cpDstPath)) { -+#else - switch(stat2bf((u_int) srcSt.st_mode)) { -+#endif - /* determine how to copy, by filetype */ - - /* NOTE: There is no S_IFLNK case here, since we're using 'stat()' and -@@ -5052,7 +5654,11 @@ - } - } - else { -+#ifdef AUTO_EXPAND -+ if (stat2bf((u_int) dstSt.st_mode , cpDstPath) != BF_DIR) { -+#else - if (stat2bf((u_int) dstSt.st_mode) != BF_DIR) { -+#endif - SetISTR(ISTR_WARNING,"%s: not a directory", cpDstPath); - copyerr++; - return; -@@ -5130,7 +5736,12 @@ - goto done; - } - -- if (stat2bf((u_int) srcSt.st_mode) == BF_DIR) { -+#ifdef AUTO_EXPAND -+ if (stat2bf((u_int) srcSt.st_mode , cpSrcPath) == BF_DIR) -+#else -+ if (stat2bf((u_int) srcSt.st_mode) == BF_DIR) -+#endif -+ { - cpSrcPath[oldsrclen] = '\0'; - continue; /* don't remove from list, just skip */ - } -@@ -5189,9 +5800,9 @@ - int exists; - /*****************************/ - { -- register int srcFd, dstFd, rcount, wcount, i; -+ register int srcFd, dstFd, rcount, wcount; - char buf[8192]; -- static char *owbuts[4] = { "\nOk", "dDon't Ask", "nNo", "\033Cancel" }; -+ static char *owbuts[] = { "\nOk", "aAlways", "nNo", "NNever", "\033Cancel" }; - - if (DEBUG) fprintf(stderr,"cp_file: src='%s', dst='%s'\n", - cpSrcPath, cpDstPath); -@@ -5203,13 +5814,15 @@ - } - - if (exists) { -+ if (overwrite==OWRT_NEVER) return; - if (overwrite==OWRT_ASK) { - sprintf(buf, "File '%s' exists.\n\nOverwrite?", cpDstPath); -- i = PopUp(buf, owbuts, 4); -- -- if (i==1) overwrite = OWRT_NOASK; -- else if (i==2) return; -- else if (i==3) { overwrite = OWRT_CANCEL; return; } -+ switch (PopUp(buf, owbuts, 4)) { -+ case 1: overwrite = OWRT_ALWAYS; break; -+ case 2: return; -+ case 3: overwrite = OWRT_NEVER; return; -+ case 4: overwrite = OWRT_CANCEL; return; -+ } - } - dstFd = open(cpDstPath, O_WRONLY|O_TRUNC, 0); - } -@@ -5303,8 +5916,14 @@ - - - /*********************************/ -+#ifdef AUTO_EXPAND -+static int stat2bf(uistmode, path) -+ u_int uistmode; -+ char *path; -+#else - static int stat2bf(uistmode) - u_int uistmode; -+#endif - { - /* given the 'st.st_mode' field from a successful stat(), returns - BF_FILE, BF_DIR, BF_BLK, BF_CHR, BF_FIFO, or BF_SOCK. Does *NOT* -@@ -5318,6 +5937,9 @@ - else if (S_ISBLK(stmode)) rv = BF_BLK; - else if (S_ISFIFO(stmode)) rv = BF_FIFO; - else if (S_ISSOCK(stmode)) rv = BF_SOCK; -+#ifdef AUTO_EXPAND -+ else if (Isarchive(path)) rv = BF_DIR; -+#endif - else rv = BF_FILE; - - return rv; -@@ -5418,4 +6040,56 @@ - } - - -+static IVIS *icon_vis_list = NULL; -+ -+/***************************************************************/ -+static void recIconVisible(name, icon) -+ char *name; -+ int icon; -+{ -+ IVIS *ptr, *prev = NULL; -+ -+ for (ptr = icon_vis_list; ptr; prev = ptr, ptr = ptr->next) { -+ if (!strcmp(ptr->name, name)) { -+ ptr->icon = icon; -+ return; -+ } -+ } -+ -+ ptr = calloc(sizeof(IVIS), 1); -+ if (!ptr) -+ return; -+ -+ ptr->name = strdup(name); - -+ if (!ptr->name) { -+ free(ptr); -+ return; -+ } -+ -+ if (!prev) { -+ icon_vis_list = ptr; -+ } else { -+ prev->next = ptr; -+ } -+ -+ ptr->next = NULL; -+ ptr->icon = icon; -+} -+ -+/***************************************************************/ -+static void restIconVisible(br) -+ BROWINFO *br; -+{ -+ IVIS *ptr; -+ -+ for (ptr = icon_vis_list; ptr; ptr = ptr->next) { -+ if (!strcmp(ptr->name, br->path)) { -+ if (ptr->icon >= 0) { -+ makeIconVisible(br, ptr->icon); -+ updateSel(br, ptr->icon, 0, 0); -+ } -+ return; -+ } -+ } -+} -diff -ruN xv-3.10a-bugfixes/xvctrl.c xv-3.10a-enhancements/xvctrl.c ---- xv-3.10a-bugfixes/xvctrl.c 2004-05-23 11:56:37.000000000 -0700 -+++ xv-3.10a-enhancements/xvctrl.c 2004-05-23 12:15:18.000000000 -0700 -@@ -104,7 +104,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 -ruN xv-3.10a-bugfixes/xvdial.c xv-3.10a-enhancements/xvdial.c ---- xv-3.10a-bugfixes/xvdial.c 2004-05-16 18:01:57.000000000 -0700 -+++ xv-3.10a-enhancements/xvdial.c 2004-05-16 18:06:38.000000000 -0700 -@@ -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 -ruN xv-3.10a-bugfixes/xvdir.c xv-3.10a-enhancements/xvdir.c ---- xv-3.10a-bugfixes/xvdir.c 2005-03-20 18:38:30.000000000 -0800 -+++ xv-3.10a-enhancements/xvdir.c 2005-04-25 22:24:28.000000000 -0700 -@@ -62,6 +62,9 @@ - #ifdef HAVE_TIFF - "TIFF", - #endif -+#ifdef HAVE_PNG -+ "PNG", -+#endif - "PostScript", - "PBM/PGM/PPM (raw)", - "PBM/PGM/PPM (ascii)", -@@ -73,9 +76,32 @@ - "Targa (24-bit)", - "FITS", - "PM", -+ "Spectrum SCREEN$", /* [JCE] */ -+ "WBMP", -+#ifdef HAVE_MAG -+ "MAG", -+#endif -+#ifdef HAVE_PIC -+ "PIC", -+#endif -+#ifdef HAVE_MAKI -+ "MAKI (640x400 only)", -+#endif -+#ifdef HAVE_PI -+ "PI", -+#endif -+#ifdef HAVE_PIC2 -+ "PIC2", -+#endif -+#ifdef HAVE_MGCSFX -+ "MgcSfx", -+#endif - MBSEP, - "Filename List"}; - -+#ifdef HAVE_PIC2 -+extern int PIC2SaveParams PARM((char *, int)); -+#endif - - static void arrangeButts PARM((int)); - static void RedrawDList PARM((int, SCRL *)); -@@ -570,7 +596,11 @@ - } - #endif - -+#ifdef AUTO_EXPAND -+ if (Chvdir(tmppath)) { -+#else - if (chdir(tmppath)) { -+#endif - char str[512]; - sprintf(str,"Unable to cd to '%s'\n", tmppath); - *trunc_point = '/'; /* restore the path */ -@@ -635,7 +665,11 @@ - xv_getwd(path, sizeof(path)); - #endif - -+#ifdef AUTO_EXPAND -+ if (Chvdir(path)) { -+#else - if (chdir(path)) { -+#endif - ErrPopUp("Current load/save directory seems to have gone away!", - "\nYikes!"); - #ifdef apollo -@@ -643,7 +677,11 @@ - #else - strcpy(path,"/"); - #endif -+#ifdef AUTO_EXPAND -+ Chvdir(path); -+#else - chdir(path); -+#endif - } - - changedDir = strcmp(path, oldpath); -@@ -748,6 +786,9 @@ - else if (S_ISFIFO(ftype)) fnames[i][0] = C_FIFO; - else if (S_ISSOCK(ftype)) fnames[i][0] = C_SOCK; - else if (fnames[i][0] == C_REG && (mode&0111)) fnames[i][0] = C_EXE; -+#ifdef AUTO_EXPAND -+ else if (Isarchive(fnames[i]+1)) fnames[i][0] = C_DIR; -+#endif - } - else { - /* fprintf(stderr,"problems 'stat-ing' files\n");*/ -@@ -847,7 +888,7 @@ - scrollToFileName(); - } - -- else if (c=='\010' || c=='\177') { /* BS or DEL */ -+ else if (c=='\010') { /* BS */ - if (curPos==0) return(-1); /* at beginning of str */ - xvbcopy(&filename[curPos], &filename[curPos-1], (size_t) (len-curPos+1)); - curPos--; -@@ -872,7 +913,7 @@ - curPos = len; - } - -- else if (c=='\004') { /* ^D: delete character at curPos */ -+ else if (c=='\004' || c=='\177') { /* ^D or DEL: delete character at curPos */ - if (curPos==len) return(-1); - xvbcopy(&filename[curPos+1], &filename[curPos], (size_t) (len-curPos)); - } -@@ -1055,6 +1096,25 @@ - - fullname = GetDirFullName(); - -+#ifdef AUTO_EXPAND -+ { -+ char path[MAXPATHLEN]; -+ -+ GetDirPath(path); -+ Mkvdir(path); -+ if ((i = Isvdir(fullname)) & 01) { -+ char buf[128]; -+ sprintf(buf, -+ "Sorry, you can't save file in the virtual directory, '%s'", -+ path); -+ ErrPopUp(buf, "\nBummer!"); -+ return -1; -+ } -+ if (i & 06) -+ Rmvdir(fullname); -+ } -+#endif -+ - fmt = MBWhich(&fmtMB); - col = MBWhich(&colMB); - -@@ -1116,7 +1176,34 @@ - } - #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 -+ -+#ifdef HAVE_PIC2 -+ else if (fmt == F_PIC2) { /* PIC2 */ -+ if (PIC2SaveParams(fullname, col) < 0) -+ return 0; -+ PIC2Dialog(1); /* open PIC2 Dialog box */ -+ dbut[S_BOK].lit = 0; BTRedraw(&dbut[S_BOK]); -+ return 0; /* always 'succeeds' */ -+ } -+#endif /* HAVE_PIC2 */ - -+#ifdef HAVE_MGCSFX -+ else if (fmt == F_MGCSFX) { /* MGCSFX */ -+ if (MGCSFXSaveParams(fullname, col) < 0) -+ return 0; -+ MGCSFXDialog(1); /* open MGCSFX Dialog box */ -+ dbut[S_BOK].lit = 0; BTRedraw(&dbut[S_BOK]); -+ return 0; /* always 'succeeds' */ -+ } -+#endif /* HAVE_MGCSFX */ - - - WaitCursor(); -@@ -1164,6 +1251,10 @@ - rv = WriteBMP (fp, thepic, ptype, w, h, rp, gp, bp, nc, col); - break; - -+ case F_WBMP: -+ rv = WriteWBMP (fp, thepic, ptype, w, h, rp, gp, bp, nc, col); -+ break; -+ - case F_IRIS: - rv = WriteIRIS (fp, thepic, ptype, w, h, rp, gp, bp, nc, col); - break; -@@ -1181,6 +1272,35 @@ - rv = WriteFITS (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, - picComments); - break; -+ -+ case F_ZX: /* [JCE] Spectrum SCREEN$ */ -+ rv = WriteZX (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, -+ picComments); -+ break; -+#ifdef HAVE_MAG -+ case F_MAG: -+ rv = WriteMAG (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, -+ picComments); -+ break; -+#endif /* HAVE_MAG */ -+#ifdef HAVE_PIC -+ case F_PIC: -+ rv = WritePIC (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, -+ picComments); -+ break; -+#endif /* HAVE_PIC */ -+#ifdef HAVE_MAKI -+ case F_MAKI: -+ rv = WriteMAKI (fp, thepic, ptype, w, h, rp, gp, bp, nc, col); -+ break; -+#endif /* HAVE_MAKI */ -+ -+#ifdef HAVE_PI -+ case F_PI: -+ rv = WritePi (fp, thepic, ptype, w, h, rp, gp, bp, nc, col, -+ picComments); -+ break; -+#endif /* HAVE_PI */ - } - - -@@ -1310,7 +1430,8 @@ - - else if (group == F_FORMAT) { - MBSelect(&fmtMB, bnum); -- if (MBWhich(&fmtMB) == F_XBM) { /* turn off all but B/W */ -+ if (MBWhich(&fmtMB) == F_XBM || -+ MBWhich(&fmtMB) == F_WBMP) { /* turn off all but B/W */ - colMB.dim[F_FULLCOLOR] = 1; - colMB.dim[F_GREYSCALE] = 1; - colMB.dim[F_BWDITHER] = 0; -@@ -1389,14 +1510,29 @@ - (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,"wbmp")==0) || -+ (strcmp(lowsuf,"xpm" )==0) || -+ (strcmp(lowsuf,"tiff")==0) || -+ (strcmp(lowsuf,"mag" )==0) || -+ (strcmp(lowsuf,"pic" )==0) || -+ (strcmp(lowsuf,"mki" )==0) || -+ (strcmp(lowsuf,"pi" )==0) || -+ (strcmp(lowsuf,"p2" )==0) || -+ (strcmp(lowsuf,"pcd" )==0)) { - - /* found one. set lowsuf = to the new suffix, and tack on to filename */ - -@@ -1419,6 +1555,7 @@ - case F_XBM: strcpy(lowsuf,"xbm"); break; - case F_SUNRAS: strcpy(lowsuf,"ras"); break; - case F_BMP: strcpy(lowsuf,"bmp"); break; -+ case F_WBMP: strcpy(lowsuf,"wbmp"); break; - case F_PS: strcpy(lowsuf,"ps"); break; - case F_IRIS: strcpy(lowsuf,"rgb"); break; - case F_TARGA: strcpy(lowsuf,"tga"); break; -@@ -1432,8 +1569,33 @@ - #ifdef HAVE_TIFF - case F_TIFF: strcpy(lowsuf,"tif"); break; - #endif -+ -+#ifdef HAVE_PNG -+ case F_PNG: strcpy(lowsuf,"png"); break; -+#endif -+ -+#ifdef HAVE_MAG -+ case F_MAG: strcpy(lowsuf,"mag"); break; -+#endif -+ -+#ifdef HAVE_PIC -+ case F_PIC: strcpy(lowsuf,"pic"); break; -+#endif -+ -+#ifdef HAVE_MAKI -+ case F_MAKI: strcpy(lowsuf,"mki"); break; -+#endif -+ -+#ifdef HAVE_PI -+ case F_PI: strcpy(lowsuf,"pi"); break; -+#endif -+ -+#ifdef HAVE_PIC2 -+ case F_PIC2: strcpy(lowsuf,"p2"); break; -+#endif - } - -+ - if (allcaps) { /* upper-caseify lowsuf */ - for (sp=lowsuf; *sp; sp++) - *sp = (islower(*sp)) ? toupper(*sp) : *sp; -@@ -1499,6 +1661,11 @@ - } - #endif - -+#ifdef AUTO_EXPAND -+ Mkvdir(newpath); -+ Dirtovd(newpath); -+#endif -+ - if (stat(newpath, &st)==0) { - int isdir; - -@@ -1596,7 +1763,11 @@ - dopipe = 0; - - /* make sure we're in the correct directory */ -+#ifdef AUTO_EXPAND -+ if (strlen(path)) Chvdir(path); -+#else - if (strlen(path)) chdir(path); -+#endif - - if (ISPIPE(filename[0])) { /* do piping */ - /* make up some bogus temp file to put this in */ -@@ -2002,7 +2173,7 @@ - if (stat(namelist[curname], &origStat)==0) { - haveStat = 1; - if (DEBUG) fprintf(stderr," origStat.size=%ld, origStat.mtime=%ld\n", -- origStat.st_size, origStat.st_mtime); -+ (long)origStat.st_size, (long)origStat.st_mtime); - } - } - } -@@ -2027,7 +2198,7 @@ - - if (stat(namelist[curname], &st)==0) { - if (DEBUG) fprintf(stderr," st.size=%ld, st.mtime=%ld\n", -- st.st_size, st.st_mtime); -+ (long)st.st_size, (long)st.st_mtime); - - if ((st.st_size == origStat.st_size) && - (st.st_mtime == origStat.st_mtime)) return 0; /* no change */ -@@ -2080,3 +2251,164 @@ - } - - -+#ifdef HAVE_PIC2 -+/**** Stuff for PIC2Dialog box ****/ -+FILE *pic2_OpenOutFile(filename, append) -+char *filename; -+int *append; -+{ -+ /* opens file for output. does various error handling bits. Returns -+ an open file pointer if success, NULL if failure */ -+ -+ FILE *fp = NULL; -+ struct stat st; -+ -+ if (!filename || filename[0] == '\0') -+ return (NULL); -+ strcpy(outFName, filename); -+ dopipe = 0; -+ -+ /* make sure we're in the correct directory */ -+#ifdef AUTO_EXPAND -+ if (strlen(path)) Chvdir(path); -+#else -+ if (strlen(path)) chdir(path); -+#endif -+ -+ if (ISPIPE(filename[0])) { /* do piping */ -+ /* make up some bogus temp file to put this in */ -+#ifndef VMS -+ sprintf(outFName, "%s/xvXXXXXX", tmpdir); -+#else -+ strcpy(outFName, "[]xvXXXXXX.lis"); -+#endif -+#ifdef USE_MKSTEMP -+ fp = fdopen(mkstemp(outFName), "w"); -+#else -+ mktemp(outFName); -+#endif -+ dopipe = 1; -+ } -+ -+ -+ /* see if file exists (i.e., we're overwriting) */ -+ *append = 0; -+#ifdef USE_MKSTEMP -+ if (!dopipe) -+#endif -+ if (stat(outFName, &st)==0) { /* stat succeeded, file must exist */ -+ if (ReadFileType(outFName) != RFT_PIC2) { -+ static char *foo[] = { "\nOk", "\033Cancel" }; -+ char str[512]; -+ -+ sprintf(str,"Overwrite existing file '%s'?", outFName); -+ if (PopUp(str, foo, 2)) -+ return (NULL); -+ } else { -+ static char *foo[] = { "\nOk", "\033Cancel" }; -+ char str[512]; -+ -+ sprintf(str,"Append to existing file '%s'?", outFName); -+ if (PopUp(str, foo, 2)) { -+ sprintf(str,"Overwrite existing file '%s'?", outFName); -+ if (PopUp(str, foo, 2)) -+ return (NULL); -+ } else -+ *append = 1; -+ } -+ } -+ -+ /* Open file */ -+#ifdef USE_MKSTEMP -+ if (!dopipe) -+#endif -+ fp = *append ? fopen(outFName, "r+") : fopen(outFName, "w"); -+ if (!fp) { -+ char str[512]; -+ sprintf(str,"Can't write file '%s'\n\n %s.",outFName, ERRSTR(errno)); -+ ErrPopUp(str, "\nBummer"); -+ return (NULL); -+ } -+ -+ return (fp); -+} -+ -+ -+/***************************************/ -+void pic2_KillNullFile(fp) -+FILE *fp; -+{ -+ fseek(fp, (size_t) 0, SEEK_END); -+ if (ftell(fp) > 0) { -+ fclose(fp); -+ return; -+ } else { -+ fclose(fp); -+ unlink(outFName); -+ return; -+ } -+} -+#endif /* HAVE_PIC2 */ -+ -+ -+#ifdef HAVE_MGCSFX -+/**** Stuff for MGCSFX Dialog box ****/ -+/***************************************/ -+int OpenOutFileDesc(filename) -+ char *filename; -+{ -+ /* opens file for output. does various error handling bits. Returns -+ an open file pointer if success, NULL if failure */ -+ -+ int fd; -+ struct stat st; -+ -+ if (!filename || filename[0] == '\0') return -1; -+ strcpy(outFName, filename); -+ dopipe = 0; -+ -+ /* make sure we're in the correct directory */ -+#ifdef AUTO_EXPAND -+ if (strlen(path)) Chvdir(path); -+#else -+ if (strlen(path)) chdir(path); -+#endif -+ -+ if (ISPIPE(filename[0])) { /* do piping */ -+ /* make up some bogus temp file to put this in */ -+#ifndef VMS -+ sprintf(outFName, "%s/xvXXXXXX", tmpdir); -+#else -+ strcpy(outFName, "[]xvXXXXXX.lis"); -+#endif -+#ifdef USE_MKSTEMP -+ close(mkstemp(outFName)); -+#else -+ mktemp(outFName); -+#endif -+ dopipe = 1; -+ } -+ -+ -+ /* if didn't just create it, see if file exists (i.e., we're overwriting) */ -+ if (!dopipe && stat(outFName, &st)==0) { /* stat succeeded, file exists */ -+ static char *foo[] = { "\nOk", "\033Cancel" }; -+ char str[512]; -+ -+ sprintf(str,"Overwrite existing file '%s'?", outFName); -+ if (PopUp(str, foo, 2)) return -1; -+ } -+ -+ -+ /* Open file */ -+ fd = open(outFName, O_WRONLY | O_CREAT | O_TRUNC, (0644)); -+ if (fd < 0) { -+ char str[512]; -+ sprintf(str,"Can't write file '%s'\n\n %s.", outFName, ERRSTR(errno)); -+ ErrPopUp(str, "\nBummer"); -+ return -1; -+ } -+ -+ return fd; -+} -+#endif /* HAVE_MGCSFX */ -diff -ruN xv-3.10a-bugfixes/xvevent.c xv-3.10a-enhancements/xvevent.c ---- xv-3.10a-bugfixes/xvevent.c 2004-05-16 18:02:03.000000000 -0700 -+++ xv-3.10a-enhancements/xvevent.c 2005-05-01 09:33:38.000000000 -0700 -@@ -64,6 +64,8 @@ - - static void annotatePic PARM((void)); - -+static int debkludge_offx; -+static int debkludge_offy; - - /****************/ - int EventLoop() -@@ -71,13 +73,25 @@ - { - XEvent event; - int retval,done,waiting; -- time_t orgtime, curtime; -+#ifdef USE_TICKS -+ clock_t waitsec_ticks=0L, orgtime_ticks=0L, curtime_ticks; -+ clock_t elapsed_ticks=0L, remaining_interval; -+#else -+ time_t orgtime=0L, curtime; -+#endif - - - #ifndef NOSIGNAL - signal(SIGQUIT, onInterrupt); - #endif - -+ if (startGrab == 1) { -+ startGrab = 2; -+ FakeButtonPress(&but[BGRAB]); -+ FakeKeyPress(ctrlW, XK_Return); -+ return(1); -+ } -+ - /* note: there's no special event handling if we're using the root window. - if we're using the root window, we will recieve NO events for mainW */ - -@@ -100,18 +114,24 @@ - - while (!done) { - -- if (waitsec > -1 && canstartwait && !waiting && XPending(theDisp)==0) { -+ if (waitsec >= 0.0 && canstartwait && !waiting && XPending(theDisp)==0) { - /* we wanna wait, we can wait, we haven't started waiting yet, and - all pending events (ie, drawing the image the first time) - have been dealt with: START WAITING */ -- time((time_t *) &orgtime); -+#ifdef USE_TICKS -+ waitsec_ticks = (clock_t)(waitsec * CLK_TCK); -+ orgtime_ticks = times(NULL); /* unclear if NULL valid, but OK on Linux */ -+#else -+ orgtime = time(NULL); -+#endif - waiting = 1; - } - - - /* if there's an XEvent pending *or* we're not doing anything - in real-time (polling, flashing the selection, etc.) get next event */ -- if ((waitsec==-1 && !polling && !HaveSelection()) || XPending(theDisp)>0) { -+ if ((waitsec<0.0 && !polling && !HaveSelection()) || XPending(theDisp)>0) -+ { - XNextEvent(theDisp, &event); - retval = HandleEvent(&event,&done); - } -@@ -121,7 +141,7 @@ - DrawSelection(0); - DrawSelection(1); - XFlush(theDisp); -- Timer(200); -+ Timer(200); /* milliseconds */ - } - - if (polling) { -@@ -129,13 +149,32 @@ - else if (!XPending(theDisp)) sleep(1); - } - -- if (waitsec>-1 && waiting) { -- time((time_t *) &curtime); -- if (curtime - orgtime < waitsec) sleep(1); -- else { -- if (waitloop) return NEXTLOOP; -- else return NEXTQUIT; -- } -+ if (waitsec>=0.0 && waiting) { -+#ifdef USE_TICKS -+ curtime_ticks = times(NULL); /* value in ticks */ -+ if (curtime_ticks < orgtime_ticks) { -+ /* clock ticks rolled over: need to correct for that (i.e., -+ * curtime_ticks is presumably quite small, while orgtime_ticks -+ * should be close to LONG_MAX, so do math accordingly--any way -+ * to check whether clock_t is *not* a signed long?) */ -+ elapsed_ticks = curtime_ticks + (LONG_MAX - orgtime_ticks); -+ } else -+ elapsed_ticks = curtime_ticks - orgtime_ticks; -+ remaining_interval = waitsec_ticks - elapsed_ticks; -+ if (remaining_interval >= (clock_t)(1 * CLK_TCK)) -+ sleep(1); -+ else { -+ /* less than one second remaining: do delay in msec, then return */ -+ Timer((remaining_interval * 1000L) / CLK_TCK); /* can't overflow */ -+ return waitloop? NEXTLOOP : NEXTQUIT; -+ } -+#else -+ curtime = time(NULL); /* value in seconds */ -+ if (curtime - orgtime < (time_t)waitsec) -+ sleep(1); -+ else -+ return waitloop? NEXTLOOP : NEXTQUIT; -+#endif - } - } - } /* while (!done) */ -@@ -154,7 +193,24 @@ - int *donep; - { - static int wasInfoUp=0, wasCtrlUp=0, wasDirUp=0, wasGamUp=0, wasPsUp=0; -- static int wasJpegUp=0, wasTiffUp=0; -+#ifdef HAVE_JPEG -+ static int wasJpegUp=0; -+#endif -+#ifdef HAVE_TIFF -+ static int wasTiffUp=0; -+#endif -+#ifdef HAVE_PNG -+ static int wasPngUp=0; -+#endif -+#ifdef HAVE_PCD -+ static int wasPcdUp=0; -+#endif -+#ifdef HAVE_PIC2 -+ static int wasPic2Up=0; -+#endif -+#ifdef HAVE_MGCSFX -+ static int wasMgcSfxUp=0; -+#endif - - static int mainWKludge=0; /* force first mainW expose after a mainW config - to redraw all of mainW */ -@@ -233,6 +289,28 @@ - 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 */ -+ -+#ifdef HAVE_PIC2 -+ if (PIC2CheckEvent(event)) break; /* event has been processed */ -+#endif -+ -+#ifdef HAVE_PCD -+ if (PCDCheckEvent (event)) break; /* event has been processed */ -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (MGCSFXCheckEvent(event)) break; /* event has been processed */ -+#endif -+ -+#ifdef TV_MULTILINGUAL -+ if (CharsetCheckEvent(event)) break; /* event has been processed */ -+#endif -+ - if (GamCheckEvent (event)) break; /* event has been processed */ - if (BrowseCheckEvent (event, &retval, &done)) break; /* event eaten */ - if (TextCheckEvent (event, &retval, &done)) break; /* event eaten */ -@@ -344,6 +422,9 @@ - - if (BrowseDelWin(client_event->window)) break; - if (TextDelWin(client_event->window)) break; -+#ifdef TV_MULTILINGUAL -+ if (CharsetDelWin(client_event->window)) break; -+#endif - - if (client_event->window == infoW) InfoBox(0); - else if (client_event->window == gamW) GamBox(0); -@@ -359,6 +440,24 @@ - 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); -+ -+#ifdef HAVE_PIC2 -+ else if (client_event->window == pic2W) PIC2Dialog(0); -+#endif -+ -+#ifdef HAVE_PCD -+ else if (client_event->window == pcdW) PCDDialog(0); -+#endif -+ -+#ifdef HAVE_MGCSFX -+ else if (client_event->window == mgcsfxW) MGCSFXDialog(0); -+#endif -+ - else if (client_event->window == mainW) Quit(0); - } - } -@@ -534,10 +633,21 @@ - #ifdef HAVE_JPEG - if (wasJpegUp) { JPEGDialog(wasJpegUp); wasJpegUp=0; } - #endif -- - #ifdef HAVE_TIFF - if (wasTiffUp) { TIFFDialog(wasTiffUp); wasTiffUp=0; } - #endif -+#ifdef HAVE_PNG -+ if (wasPngUp) { PNGDialog(wasJpegUp); wasPngUp=0; } -+#endif -+#ifdef HAVE_PCD -+ if (wasPcdUp) { PCDDialog(wasPcdUp); wasPcdUp=0; } -+#endif -+#ifdef HAVE_PIC2 -+ if (wasPic2Up) { PIC2Dialog(wasPic2Up); wasPic2Up=0; } -+#endif -+#ifdef HAVE_MGCSFX -+ if (wasMgcSfxUp) { MGCSFXDialog(wasMgcSfxUp); wasMgcSfxUp=0; } -+#endif - } - } - } -@@ -572,10 +682,21 @@ - #ifdef HAVE_JPEG - if (jpegUp) { wasJpegUp = jpegUp; JPEGDialog(0); } - #endif -- - #ifdef HAVE_TIFF - if (tiffUp) { wasTiffUp = tiffUp; TIFFDialog(0); } - #endif -+#ifdef HAVE_PNG -+ if (pngUp) { wasPngUp = pngUp; PNGDialog(0); } -+#endif -+#ifdef HAVE_PCD -+ if (pcdUp) { wasPcdUp = pcdUp; PCDDialog(0); } -+#endif -+#ifdef HAVE_PIC2 -+ if (pic2Up) { wasPic2Up = pic2Up; PIC2Dialog(0); } -+#endif -+#ifdef HAVE_MGCSFX -+ if (mgcsfxUp) { wasMgcSfxUp = mgcsfxUp; MGCSFXDialog(0); } -+#endif - } - } - } -@@ -641,6 +762,30 @@ - p_offy = xwa.y; - } - -+ /* Gather info to keep right border inside */ -+ { -+ Window current; -+ Window root_r; -+ Window parent_r; -+ Window *children_r; -+ int nchildren_r; -+ XWindowAttributes xwa; -+ -+ parent_r=mainW; -+ current=mainW; -+ do { -+ current=parent_r; -+ XQueryTree(theDisp, current, &root_r, &parent_r, -+ &children_r, &nchildren_r); -+ if (children_r!=NULL) { -+ XFree(children_r); -+ } -+ } while(parent_r!=root_r); -+ XGetWindowAttributes(theDisp, current, &xwa); -+ debkludge_offx=eWIDE-xwa.width+p_offx; -+ debkludge_offy=eHIGH-xwa.height+p_offy; -+ } -+ - - /* move window around a bit... */ - { -@@ -997,7 +1142,8 @@ - - int i; - char txt[512], str[PRINTCMDLEN + 10]; -- static char *labels[] = { " Color", " Grayscale", " B/W", "\033Cancel" }; -+ static char *labels[] = { "\03Color", "\07Grayscale", " B/W", "\033Cancel" }; -+ /* ^B ("\02") already used for moving cursor back */ - - strcpy(txt, "Print: Enter a command that will read a PostScript file "); - strcat(txt, "from stdin and print it to the desired printer.\n\n"); -@@ -1147,6 +1293,26 @@ - if (TIFFCheckEvent(event)) break; - #endif - -+#ifdef HAVE_PNG -+ if (PNGCheckEvent (event)) break; -+#endif -+ -+#ifdef HAVE_PCD -+ if (PCDCheckEvent (event)) break; /* event has been processed */ -+#endif -+ -+#ifdef HAVE_PIC2 -+ if (PIC2CheckEvent(event)) break; -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (MGCSFXCheckEvent(event)) break; -+#endif -+ -+#ifdef TV_MULTILINGUAL -+ if (CharsetCheckEvent(event)) break; -+#endif -+ - if (GamCheckEvent (event)) break; - if (BrowseCheckEvent (event, &retval, &done)) break; - if (TextCheckEvent (event, &retval, &done)) break; -@@ -1276,6 +1442,48 @@ - else if (shift) BlurPaint(); - break; - -+ case Button4: /* note min vs. max, + vs. - */ -+ if (win == ctrlW || win == nList.win || win == nList.scrl.win) { -+ SCRL *sp=&nList.scrl; -+ int halfpage=sp->page/2; -+ -+ if (sp->val > sp->min+halfpage) -+ SCSetVal(sp,sp->val-halfpage); -+ else -+ SCSetVal(sp,sp->min); -+ } -+ else if (win == dirW || win == dList.win || win == dList.scrl.win) { -+ SCRL *sp=&dList.scrl; -+ int halfpage=sp->page/2; -+ -+ if (sp->val > sp->min+halfpage) -+ SCSetVal(sp,sp->val-halfpage); -+ else -+ SCSetVal(sp,sp->min); -+ } -+ break; -+ -+ case Button5: /* note max vs. min, - vs. + */ -+ if (win == ctrlW || win == nList.win || win == nList.scrl.win) { -+ SCRL *sp=&nList.scrl; -+ int halfpage=sp->page/2; -+ -+ if (sp->val < sp->max-halfpage) -+ SCSetVal(sp,sp->val+halfpage); -+ else -+ SCSetVal(sp,sp->max); -+ } -+ else if (win == dirW || win == dList.win || win == dList.scrl.win) { -+ SCRL *sp=&dList.scrl; -+ int halfpage=sp->page/2; -+ -+ if (sp->val < sp->max-halfpage) -+ SCSetVal(sp,sp->val+halfpage); -+ else -+ SCSetVal(sp,sp->max); -+ } -+ break; -+ - default: break; - } - } -@@ -1364,16 +1572,35 @@ - if (TIFFCheckEvent(event)) break; - #endif - -+#ifdef HAVE_PNG -+ if (PNGCheckEvent (event)) break; -+#endif -+ -+ if (PCDCheckEvent (event)) break; -+ -+#ifdef HAVE_PIC2 -+ if (PIC2CheckEvent(event)) break; -+#endif -+ -+#ifdef HAVE_PCD -+ if (PCDCheckEvent (event)) break; -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (MGCSFXCheckEvent(event)) break; -+#endif -+ - if (GamCheckEvent (event)) break; - if (BrowseCheckEvent (event, &retval, &done)) break; - if (TextCheckEvent (event, &retval, &done)) break; - - -- /* check for pageup/pagedown, 'p' in main window -- (you can use shift-up or shift-down if no crop rectangle drawn) -- (for viewing multipage docs) */ -+ /* Support for multi-image files ("multipage docs"). Check for PgUp/PgDn -+ or 'p' in any window but control or directory; PgUp/PgDn are already -+ used to page through the file list in those windows. If no cropping -+ rectangle is active, shift-Up and shift-Down also work. */ - -- if (key_event->window == mainW) { -+ if (key_event->window != ctrlW && key_event->window != dirW) { - dealt = 1; - - ck = CursorKey(ks, shift, 0); -@@ -1578,13 +1805,13 @@ - } - break; - -- case '\010': -- case '\177': FakeButtonPress(&but[BPREV]); break; -+ case '\010': FakeButtonPress(&but[BPREV]); break; - - - case '\014': FakeButtonPress(&but[BLOAD]); break; /* ^L */ - case '\023': FakeButtonPress(&but[BSAVE]); break; /* ^S */ - case '\020': FakeButtonPress(&but[BPRINT]); break; /* ^P */ -+ case '\177': - case '\004': FakeButtonPress(&but[BDELETE]); break; /* ^D */ - - /* BCOPY, BCUT, BPASTE, BCLEAR handled in 'meta' case */ -@@ -2025,6 +2252,16 @@ - if (xwa->width < dispWIDE && xwc.x < p_offx) xwc.x = p_offx; - if (xwa->height < dispHIGH && xwc.y < p_offy) xwc.y = p_offy; - -+ /* Try to keep bottom right decorations inside */ -+ if (xwc.x+eWIDE-debkludge_offx>dispWIDE) { -+ xwc.x=dispWIDE-eWIDE+debkludge_offx; -+ if (xwc.x<0) xwc.x=0; -+ } -+ if (xwc.y+eHIGH-debkludge_offy>dispHIGH) { -+ xwc.y=dispHIGH-eHIGH+debkludge_offy; -+ if (xwc.y<0) xwc.y=0; -+ } -+ - xwc.width = xwa->width; - xwc.height = xwa->height; - -@@ -2370,6 +2607,24 @@ - if (tiffUp) TIFFDialog(0); /* close tiff window */ - #endif - -+#ifdef HAVE_PNG -+ if (pngUp) PNGDialog(0); /* close png window */ -+#endif -+ -+ if (pcdUp) PCDDialog(0); /* close pcd window */ -+ -+#ifdef HAVE_PIC2 -+ if (pic2Up) PIC2Dialog(0); /* close pic2 window */ -+#endif -+ -+#ifdef HAVE_PCD -+ if (pcdUp) PCDDialog(0); /* close pcd window */ -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (mgcsfxUp) MGCSFXDialog(0); /* close mgcsfx window */ -+#endif -+ - ClosePopUp(); - - /* make the interrupt signal look like a '\n' keypress in ctrlW */ -@@ -2574,26 +2829,43 @@ - static void paintLine(x,y,x1,y1) - int x,y,x1,y1; - { -- int dx,dy,i,lx,ly,adx,ady; -+ int t,dx,dy,d,dd; - -- dx = x1-x; dy = y1-y; -- adx = abs(dx); ady = abs(dy); -+ dx = abs(x1-x); dy = abs(y1-y); - -- if (dx == 0 && dy == 0) paintPixel(x,y); -- -- else if (adx > ady) { /* X is major axis */ -- for (i=0; i<=adx; i++) { -- lx = x + (i * dx + (adx/2)) / abs(dx); -- ly = y + (i * dy + (adx/2)) / abs(dx); -- paintPixel(lx,ly); -+ if (dx >= dy) { /* X is major axis */ -+ if (x > x1) { -+ t = x; x = x1; x1 = t; -+ t = y; y = y1; y1 = t; -+ } -+ d = dy + dy - dx; -+ dd = y < y1 ? 1 : -1; -+ while (x <= x1) { -+ paintPixel(x,y); -+ if (d > 0) { -+ y += dd; -+ d -= dx + dx; -+ } -+ ++x; -+ d += dy + dy; - } - } - - else { /* Y is major axis */ -- for (i=0; i<=ady; i++) { -- lx = x + (i * dx + (ady/2)) / ady; -- ly = y + (i * dy + (ady/2)) / ady; -- paintPixel(lx,ly); -+ if (y > y1) { -+ t = x; x = x1; x1 = t; -+ t = y; y = y1; y1 = t; -+ } -+ d = dx + dx - dy; -+ dd = x < x1 ? 1 : -1; -+ while (y <= y1) { -+ paintPixel(x,y); -+ if (d > 0) { -+ x += dd; -+ d -= dy + dy; -+ } -+ ++y; -+ d += dx + dx; - } - } - -diff -ruN xv-3.10a-bugfixes/xvfits.c xv-3.10a-enhancements/xvfits.c ---- xv-3.10a-bugfixes/xvfits.c 2005-04-02 21:08:45.000000000 -0800 -+++ xv-3.10a-enhancements/xvfits.c 2005-04-17 14:45:28.000000000 -0700 -@@ -14,7 +14,7 @@ - * provided "as is" without express or implied warranty. - */ - -- -+#define NEEDSDIR /* for S_IRUSR|S_IWUSR */ - #include "xv.h" - - #define NCARDS (36) -@@ -228,7 +228,7 @@ - * If there was a problem writing files, then a error message will be set. - */ - -- int i, npixels=nx * ny, nwrt; -+ int i, npixels=nx * ny, nwrt, tmpfd; - FILE *fp; - char *error; - char filename[70]; -@@ -254,7 +254,12 @@ - - for (i=0; i < nz && !error; i++) { - sprintf(filename, "%s%d", basename, i+1); -- fp = xv_fopen(filename, "w"); -+ tmpfd = open(filename,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) { -+ error = "Unable to open temporary file"; -+ break; -+ } -+ fp = fdopen(tmpfd, "w"); - if (!fp) { - error = "Unable to open temporary file"; - break; -@@ -262,13 +267,17 @@ - - if (wrheader(fp, nx, ny, comment)) { - error = "I/O error writing temporary file"; -+ fflush(fp); - fclose(fp); - unlink(filename); -+ close(tmpfd); - break; - } - - nwrt = fwrite(image+i*npixels, sizeof(byte), (size_t) npixels, fp); -+ fflush(fp); - fclose(fp); -+ close(tmpfd); - - if (nwrt == 0) { /* failed to write any data */ - error = "I/O error writing temporary file"; -diff -ruN xv-3.10a-bugfixes/xvgam.c xv-3.10a-enhancements/xvgam.c ---- xv-3.10a-bugfixes/xvgam.c 2004-05-16 18:02:11.000000000 -0700 -+++ xv-3.10a-enhancements/xvgam.c 2004-05-16 18:06:48.000000000 -0700 -@@ -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 -ruN xv-3.10a-bugfixes/xvgif.c xv-3.10a-enhancements/xvgif.c ---- xv-3.10a-bugfixes/xvgif.c 2005-04-03 11:53:13.000000000 -0700 -+++ xv-3.10a-enhancements/xvgif.c 2005-04-30 21:47:44.000000000 -0700 -@@ -50,6 +50,7 @@ - BytesPerScanline, /* bytes per scanline in output raster */ - ColorMapSize, /* number of colors */ - Background, /* background color */ -+ Transparent, /* transparent color (GRR 19980314) */ - CodeSize, /* Code size, read from GIF header */ - InitCodeSize, /* Starting code size, used during Clear */ - Code, /* Value returned by ReadCode */ -@@ -111,16 +112,20 @@ - - register byte ch, *origptr; - register int i, block; -- int aspect, gotimage; -+ int aspect; -+ char tmpname[256]; -+ byte r[256], g[256], b[256]; - - /* initialize variables */ -- BitOffset = XC = YC = OutCount = gotimage = 0; -+ BitOffset = XC = YC = OutCount = 0; - Pass = -1; - RawGIF = Raster = pic8 = NULL; - gif89 = 0; -+ Transparent = -1; - - pinfo->pic = (byte *) NULL; - pinfo->comment = (char *) NULL; -+ pinfo->numpages= 0; - - bname = BaseName(fname); - fp = xv_fopen(fname,"r"); -@@ -145,7 +150,7 @@ - - if (fread(dataptr, (size_t) filesize, (size_t) 1, fp) != 1) - return( gifError(pinfo, "GIF data read failed") ); -- -+ fclose(fp); - - origptr = dataptr; - -@@ -161,6 +166,7 @@ - RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */ - ch = NEXTBYTE; - RHeight = ch + 0x100 * NEXTBYTE; -+ if (DEBUG) fprintf(stderr,"GIF89 logical screen = %d x %d\n",RWidth,RHeight); - - ch = NEXTBYTE; - HasColormap = ((ch & COLORMAPMASK) ? True : False); -@@ -176,6 +182,8 @@ - if (!gif89) return(gifError(pinfo,"corrupt GIF file (screen descriptor)")); - else normaspect = (float) (aspect + 15) / 64.0; /* gif89 aspect ratio */ - if (DEBUG) fprintf(stderr,"GIF89 aspect = %f\n", normaspect); -+ /* FIXME: apparently this _should_ apply to all frames in a multi-image -+ * GIF (i.e., PgUp/PgDn), but it doesn't */ - } - - -@@ -183,20 +191,23 @@ - - if (HasColormap) - for (i=0; i<ColorMapSize; i++) { -- pinfo->r[i] = NEXTBYTE; -- pinfo->g[i] = NEXTBYTE; -- pinfo->b[i] = NEXTBYTE; -+ r[i] = NEXTBYTE; -+ g[i] = NEXTBYTE; -+ b[i] = NEXTBYTE; - } - else { /* no colormap in GIF file */ - /* put std EGA palette (repeated 16 times) into colormap, for lack of - anything better to do */ - - for (i=0; i<256; i++) { -- pinfo->r[i] = EGApalette[i&15][0]; -- pinfo->g[i] = EGApalette[i&15][1]; -- pinfo->b[i] = EGApalette[i&15][2]; -+ r[i] = EGApalette[i&15][0]; -+ g[i] = EGApalette[i&15][1]; -+ b[i] = EGApalette[i&15][2]; - } - } -+ memcpy(pinfo->r, r, sizeof r); -+ memcpy(pinfo->g, g, sizeof g); -+ memcpy(pinfo->b, b, sizeof b); - - /* possible things at this point are: - * an application extension block -@@ -334,12 +345,28 @@ - if (DEBUG) fprintf(stderr,"Graphic Control extension\n\n"); - - SetISTR(ISTR_INFO, "%s: %s", bname, -- "Graphic Control Extension in GIF file. Ignored."); -+ "Graphic Control Extension ignored."); - -- /* read (and ignore) data sub-blocks */ -+ /* read (and ignore) data sub-blocks, unless compositing with -+ * user-defined background */ - do { -- j = 0; sbsize = NEXTBYTE; -- while (j<sbsize) { SKIPBYTE; j++; } -+ j = 0; -+ sbsize = NEXTBYTE; -+ /* GRR 19980314: get transparent index out of block */ -+ if (have_imagebg && sbsize == 4 && Transparent < 0) { -+ byte packed_fields = NEXTBYTE; -+ -+ j++; -+ SKIPBYTE; j++; -+ SKIPBYTE; j++; -+ if (packed_fields & 1) { -+ Transparent = NEXTBYTE; -+ j++; -+ } -+ } -+ while (j<sbsize) { -+ SKIPBYTE; j++; -+ } - } while (sbsize); - } - -@@ -376,36 +403,42 @@ - - - else if (block == IMAGESEP) { -- if (DEBUG) fprintf(stderr,"imagesep (got=%d) ",gotimage); -+ if (DEBUG) fprintf(stderr,"imagesep (page=%d) ",pinfo->numpages+1); - if (DEBUG) fprintf(stderr," at start: offset=0x%x\n",dataptr-RawGIF); - -- if (gotimage) { /* just skip over remaining images */ -- int i,misc,ch,ch1; -+ BitOffset = XC = YC = Pass = OutCount = 0; - -- /* skip image header */ -- SKIPBYTE; SKIPBYTE; /* left position */ -- SKIPBYTE; SKIPBYTE; /* top position */ -- SKIPBYTE; SKIPBYTE; /* width */ -- SKIPBYTE; SKIPBYTE; /* height */ -- misc = NEXTBYTE; /* misc. bits */ -- -- if (misc & 0x80) { /* image has local colormap. skip it */ -- for (i=0; i< 1 << ((misc&7)+1); i++) { -- SKIPBYTE; SKIPBYTE; SKIPBYTE; -+ if (pinfo->numpages > 0) { /* do multipage stuff */ -+ if (pinfo->numpages == 1) { /* first time only... */ -+ xv_mktemp(pinfo->pagebname, "xvpgXXXXXX"); -+ if (pinfo->pagebname[0] == '\0') { -+ ErrPopUp("LoadGIF: Unable to create temporary filename???", -+ "\nHow unlikely!"); -+ return 0; - } - } -- -- SKIPBYTE; /* minimum code size */ -- -- /* skip image data sub-blocks */ -- do { -- ch = ch1 = NEXTBYTE; -- while (ch--) SKIPBYTE; -- if ((dataptr - RawGIF) > filesize) break; /* EOF */ -- } while(ch1); -+ sprintf(tmpname, "%s%d", pinfo->pagebname, pinfo->numpages); -+ fp = xv_fopen(tmpname, "w"); -+ if (!fp) { -+ ErrPopUp("LoadGIF: Unable to open temp file", "\nDang!"); -+ return 0; -+ } -+ if (WriteGIF(fp, pinfo->pic, pinfo->type, pinfo->w, pinfo->h, pinfo->r, -+ pinfo->g, pinfo->b, numcols, pinfo->colType, NULL)) { -+ fclose(fp); -+ ErrPopUp("LoadGIF: Error writing temp file", "\nBummer!"); -+ return 0; -+ } -+ fclose(fp); -+ free(pinfo->pic); -+ pinfo->pic = (byte *) NULL; -+ if (HasColormap) { -+ memcpy(pinfo->r, r, sizeof r); -+ memcpy(pinfo->g, g, sizeof g); -+ memcpy(pinfo->b, b, sizeof b); -+ } - } -- -- else if (readImage(pinfo)) gotimage = 1; -+ if (readImage(pinfo)) pinfo->numpages++; - if (DEBUG) fprintf(stderr," at end: dataptr=0x%x\n",dataptr-RawGIF); - } - -@@ -425,7 +458,7 @@ - sprintf(str, "Unknown block type (0x%02x) at offset 0x%x", - block, (dataptr - origptr) - 1); - -- if (!gotimage) return gifError(pinfo, str); -+ if (!pinfo->numpages) return gifError(pinfo, str); - else gifWarning(str); - } - -@@ -438,8 +471,34 @@ - free(RawGIF); RawGIF = NULL; - free(Raster); Raster = NULL; - -- if (!gotimage) -+ if (!pinfo->numpages) - return( gifError(pinfo, "no image data found in GIF file") ); -+ if (pinfo->numpages > 1) { -+ /* write the last page temp file */ -+ int numpages = pinfo->numpages; -+ char *comment = pinfo->comment; -+ sprintf(tmpname, "%s%d", pinfo->pagebname, pinfo->numpages); -+ fp = xv_fopen(tmpname, "w"); -+ if (!fp) { -+ ErrPopUp("LoadGIF: Unable to open temp file", "\nDang!"); -+ return 0; -+ } -+ if (WriteGIF(fp, pinfo->pic, pinfo->type, pinfo->w, pinfo->h, pinfo->r, -+ pinfo->g, pinfo->b, numcols, pinfo->colType, NULL)) { -+ fclose(fp); -+ ErrPopUp("LoadGIF: Error writing temp file", "\nBummer!"); -+ return 0; -+ } -+ fclose(fp); -+ free(pinfo->pic); -+ pinfo->pic = (byte *) NULL; -+ -+ /* load the first page temp file */ -+ sprintf(tmpname, "%s%d", pinfo->pagebname, 1); -+ i = LoadGIF(tmpname, pinfo); -+ pinfo->numpages = numpages; -+ pinfo->comment = comment; -+ } - - return 1; - } -@@ -484,6 +543,17 @@ - } - - -+ /* GRR 19980314 */ -+ /* need not worry about size of EGA palette: full 256 colors */ -+ if (have_imagebg && Transparent >= 0 && -+ Transparent < ((Misc&0x80)? (1 << ((Misc&7)+1)) : ColorMapSize) ) -+ { -+ pinfo->r[Transparent] = (imagebgR >> 8); -+ pinfo->g[Transparent] = (imagebgG >> 8); -+ pinfo->b[Transparent] = (imagebgB >> 8); -+ } -+ -+ - - /* Start reading the raster data. First we get the intial code size - * and compute decompressor constant values, based on this code size. -@@ -540,7 +610,7 @@ - return( gifError(pinfo, "image dimensions out of range") ); - picptr = pic8 = (byte *) malloc((size_t) maxpixels); - if (!pic8) FatalError("LoadGIF: couldn't malloc 'pic8'"); -- -+ - - - /* Decompress the file, continuing until you see the GIF EOF code. -@@ -642,11 +712,10 @@ - SetISTR(ISTR_WARNING,"%s: %s", bname, - "This GIF file seems to be truncated. Winging it."); - if (!Interlace) /* clear->EOBuffer */ -- xvbzero((char *) pic8+npixels, (size_t) (maxpixels-npixels)); -+ xvbzero((char *) pic8+npixels, -+ (size_t) (maxpixels-npixels<0 ? 0 : maxpixels-npixels)); - } - -- fclose(fp); -- - /* fill in the PICINFO structure */ - - pinfo->pic = pic8; -diff -ruN xv-3.10a-bugfixes/xvgrab.c xv-3.10a-enhancements/xvgrab.c ---- xv-3.10a-bugfixes/xvgrab.c 2004-05-16 18:03:30.000000000 -0700 -+++ xv-3.10a-enhancements/xvgrab.c 2005-04-25 23:39:32.000000000 -0700 -@@ -14,6 +14,13 @@ - #define NEEDSTIME - #include "xv.h" - -+/* Allow flexibility in use of buttons JPD */ -+#define WINDOWGRABMASK Button1Mask /* JPD prefers Button2Mask */ -+#define RECTGTRACKMASK Button2Mask /* JPD prefers Button1Mask*/ -+#define CANCELGRABMASK Button3Mask -+ -+#define DO_GRABFLASH /* JPD prefers not to do that; just a loss of time ... */ -+ - - union swapun { - CARD32 l; -@@ -69,12 +76,15 @@ - 0 if cancelled */ - - int i, x, y, x1, y1, x2, y2, ix, iy, iw, ih, rv; -- int rx, ry, pretendGotB1, autograb; -+ int rx, ry, GotButton, autograb; -+ int cancelled = 0; - Window rW, cW, clickWin; - unsigned int mask; -+#ifdef RECOLOR_GRAB_CURSOR - XColor fc, bc; -+#endif - -- pretendGotB1 = 0; -+ GotButton = 0; - - if (grabInProgress) return 0; /* avoid recursive grabs during delay */ - -@@ -122,15 +132,23 @@ - free(grabPic); grabPic = (byte *) NULL; - } - -- -+ /* recolor cursor to indicate that grabbing is active? */ -+ /* Instead, change cursor JPD */ -+#ifdef RECOLOR_GRAB_CURSOR - fc.flags = bc.flags = DoRed | DoGreen | DoBlue; - fc.red = fc.green = fc.blue = 0xffff; - bc.red = bc.green = bc.blue = 0x0000; - XRecolorCursor(theDisp, tcross, &fc, &bc); -+#endif - - - XBell(theDisp, 0); /* beep once at start of grab */ - -+ /* Change cursor to top_left_corner JPD */ -+ XGrabPointer(theDisp, rootW, False, -+ PointerMotionMask|ButtonPressMask|ButtonReleaseMask, -+ GrabModeAsync, GrabModeAsync, None, tlcorner, CurrentTime); -+ - if (!autograb) XGrabButton(theDisp, (u_int) AnyButton, 0, rootW, False, 0, - GrabModeAsync, GrabModeSync, None, tcross); - -@@ -142,7 +160,7 @@ - rv = 0; - goto exit; - } -- else { pretendGotB1 = 1; mask = Button1Mask; } -+ else { GotButton = 1; mask = WINDOWGRABMASK; } - } - - else { /* !autograb */ -@@ -170,16 +188,20 @@ - } - } - -+ XUngrabPointer(theDisp, CurrentTime); -+ /* Reset cursor to XC_tcross JPD */ -+ XGrabPointer(theDisp, rootW, False, -+ PointerMotionMask|ButtonPressMask|ButtonReleaseMask, -+ GrabModeAsync, GrabModeAsync, None, tcross, CurrentTime); - - /*** - *** got button click (or pretending we did, if autograb) - ***/ - -- -- if (mask & Button3Mask || rW!=rootW) { /* Button3: CANCEL GRAB */ -+ if (mask & CANCELGRABMASK || rW!=rootW) { /* CANCEL GRAB */ - while (1) { /* wait for button to be released */ - if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x1,&y1,&mask)) { -- if (!(mask & Button3Mask)) break; -+ if (!(mask & CANCELGRABMASK)) break; - } - } - -@@ -187,19 +209,21 @@ - XBell(theDisp, 0); - XBell(theDisp, 0); - rv = 0; -+ cancelled = 1; - goto exit; - } - - -- -- if (mask & Button1Mask) { /* Button1: GRAB WINDOW (& FRAME, maybe) */ -- while (!pretendGotB1) { /* wait for button to be released, if clicked */ -+ if (mask & WINDOWGRABMASK) { /* GRAB WINDOW (& FRAME, maybe) */ -+ while (!GotButton) { /* wait for button to be released, if clicked */ - int rx,ry,x1,y1; Window rW, cW; - if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x1,&y1,&mask)) { -- if (!(mask & Button1Mask)) break; -+ if (!(mask & WINDOWGRABMASK)) break; - } - } - -+ grabwin: -+ - clickWin = (cW) ? cW : rootW; - - if (clickWin == rootW) { /* grab entire screen */ -@@ -223,7 +247,6 @@ - } - } - -- - /* range checking: keep rectangle fully on-screen */ - if (ix<0) { iw += ix; ix = 0; } - if (iy<0) { ih += iy; iy = 0; } -@@ -244,8 +267,7 @@ - endflash(); - } - -- -- else { /* Button2: TRACK A RECTANGLE */ -+ else { /* TRACK A RECTANGLE */ - int origrx, origry; - - clickWin = rootW; -@@ -259,7 +281,7 @@ - /* Wait for button release while tracking rectangle on screen */ - while (1) { - if (XQueryPointer(theDisp,rootW,&rW,&cW,&rx,&ry,&x,&y,&mask)) { -- if (!(mask & Button2Mask)) break; -+ if (!(mask & RECTGTRACKMASK)) break; - } - - flashrect(ix, iy, iw, ih, 0); /* turn off rect */ -@@ -276,6 +298,7 @@ - - flashrect(ix, iy, iw, ih, 0); /* turn off rect */ - -+#ifdef DO_GRABFLASH - /* flash the rectangle a bit... */ - for (i=0; i<5; i++) { - flashrect(ix, iy, iw, ih, 1); -@@ -283,13 +306,26 @@ - flashrect(ix, iy, iw, ih, 0); - XFlush(theDisp); Timer(100); - } -+#endif -+ - endflash(); - -+ /* if rectangle has zero width or height, search for child window JPD */ -+ if (iw==0 && ih==0) { -+ int xr, yr; -+ Window childW = 0; -+ if (rW && cW) -+ XTranslateCoordinates(theDisp, rW, cW, rx, ry, &xr, &yr, &childW); -+ if (childW) -+ cW = childW; -+ goto grabwin; -+ } -+ - XUngrabServer(theDisp); - } - -- - /*** -+ *** now that clickWin,ix,iy,iw,ih are known, try to grab the bits : - *** grab screen area (ix,iy,iw,ih) - ***/ - -@@ -303,9 +339,16 @@ - - SetCursors(-1); - -- - exit: - -+ XUngrabPointer(theDisp, CurrentTime); -+ XUngrabServer(theDisp); -+ -+ if (startGrab) { -+ startGrab = 0; -+ if (cancelled) Quit(0); -+ } -+ - if (hidewins) { /* remap XV windows */ - autoclose += 2; /* force it on once */ - if (mainW && dispMode == RMB_WINDOW) { -@@ -1217,7 +1260,3 @@ - - return 1; - } -- -- -- -- -diff -ruN xv-3.10a-bugfixes/xvhips.c xv-3.10a-enhancements/xvhips.c ---- xv-3.10a-bugfixes/xvhips.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvhips.c 2005-04-30 23:49:14.000000000 -0700 -@@ -0,0 +1,406 @@ -+/* -+ * xvhips.c - load routine for 'HIPS' format pictures -+ * -+ * LoadHIPS(fname, numcols) -+ */ -+ -+/* -+ * Copyright 1989, 1990 by the University of Pennsylvania -+ * -+ * Permission to use, copy, and distribute for non-commercial purposes, -+ * is hereby granted without fee, providing that the above copyright -+ * notice appear in all copies and that both the copyright notice and this -+ * permission notice appear in supporting documentation. -+ * -+ * The software may be modified for your own purposes, but modified versions -+ * may not be distributed. -+ * -+ * This software is provided "as is" without any express or implied warranty. -+ */ -+ -+#include "xv.h" -+ -+#ifdef HAVE_HIPS -+ -+#define Boolean FREDDIE -+#include "xvhips.h" -+#undef Boolean -+ -+#include <alloca.h> -+ -+#define LINES 100 -+#define LINELENGTH 132 -+ -+static int fread_header(int fd, struct header *hd); -+static char *getline(int fd, char **s, int *l); -+static int dfscanf(int fd); -+static void make_grayscale(char *r, char *g, char *b); -+static float hls_value (float n1, float n2, float hue); -+static void hls_to_rgb(float h, float l, float s, -+ float *r, float *g, float *b); -+static void make_huescale(char *r, char *g, char *b); -+static void make_heatscale(char *r, char *g, char *b); -+static int load_colourmap(char *filestem, int max_colours, -+ char *r, char *g, char *b); -+ -+/************************************************************************ -+ * -+ * Read Header routines -+ * -+ ************************************************************************/ -+ -+static char *ssave[LINES]; -+static int slmax[LINES]; -+static int lalloc = 0; -+//extern char *calloc(); -+ -+ -+ -+static int fread_header(fd, hd) -+ int fd; -+ struct header *hd; -+{ -+ int lineno, len, i; -+ char *s; -+ -+/*fprintf(stderr,"fread_header: entered\n");*/ -+ if(lalloc<1) { -+ ssave[0] = calloc(LINELENGTH, sizeof (char)); -+ slmax[0] = LINELENGTH; -+ lalloc = 1; -+ } -+/*fprintf(stderr,"fread_header: ssave allocated\n");*/ -+ getline(fd,&ssave[0],&slmax[0]); -+ hd->orig_name = calloc(strlen(ssave[0])+1, sizeof (char)); -+ strcpy(hd->orig_name,ssave[0]); -+ getline(fd,&ssave[0],&slmax[0]); -+ hd->seq_name = calloc(strlen(ssave[0])+1, sizeof (char)); -+ strcpy(hd->seq_name,ssave[0]); -+ hd->num_frame = dfscanf(fd); -+ getline(fd,&ssave[0],&slmax[0]); -+ hd->orig_date = calloc(strlen(ssave[0])+1, sizeof (char)); -+ strcpy(hd->orig_date,ssave[0]); -+ hd->rows = dfscanf(fd); -+ hd->cols = dfscanf(fd); -+ hd->bits_per_pixel = dfscanf(fd); -+ hd->bit_packing = dfscanf(fd); -+ hd->pixel_format = dfscanf(fd); -+ lineno = 0; -+ len = 1; -+ getline(fd,&ssave[0],&slmax[0]); -+ s = ssave[0]; -+ while(*(s += strlen(s)-3) == '|') { -+ len += strlen(ssave[lineno]); -+ lineno++; -+ if (lineno >= LINES) -+ fprintf(stderr, "Too many lines in header history"); -+ if(lineno >= lalloc) { -+ ssave[lineno] = calloc(LINELENGTH, sizeof (char)); -+ slmax[lineno] = LINELENGTH; -+ lalloc++; -+ } -+ getline(fd,&ssave[lineno],&slmax[lineno]); -+ s = ssave[lineno]; -+ } -+ len += strlen(ssave[lineno]); -+ hd->seq_history = calloc(len, sizeof (char)); -+ hd->seq_history[0] = '\0'; -+ for (i=0;i<=lineno;i++) -+ strcat(hd->seq_history,ssave[i]); -+ lineno = 0; -+ len = 1; -+ while(strcmp(getline(fd,&ssave[lineno],&slmax[lineno]),".\n")) { -+ len += strlen(ssave[lineno]); -+ lineno++; -+ if (lineno >= LINES) -+ fprintf(stderr, "Too many lines in header desc."); -+ if(lineno >= lalloc) { -+ ssave[lineno] = calloc(LINELENGTH, sizeof (char)); -+ slmax[lineno] = LINELENGTH; -+ lalloc++; -+ } -+ } -+ hd->seq_desc = calloc(len, sizeof (char)); -+ *hd->seq_desc = '\0'; -+ for (i=0;i<lineno;i++) -+ strcat(hd->seq_desc,ssave[i]); -+/*fprintf(stderr,"fread_header: exiting\n");*/ -+ return 0; -+} -+ -+ -+ -+static char *getline(fd,s,l) -+ int fd; -+ char **s; -+ int *l; -+{ -+ int i,m; -+ char c,*s1,*s2; -+ -+ i = 0; -+ s1 = *s; -+ m = *l; -+ while(read(fd,&c,1) == 1 && c != '\n') { -+ if (m-- <= 2) { -+ s2 = calloc(LINELENGTH+*l,sizeof (char)); -+ strcpy(s2,*s); -+ *s = s2; -+ *l += LINELENGTH; -+ m = LINELENGTH; -+ s1 = s2 + strlen(s2); -+ } -+ *s1++ = c; -+ } -+ if (c == '\n') { -+ *s1++ = '\n'; -+ *s1 = '\0'; -+ return *s; -+ } -+ fprintf(stderr, "Unexpected EOF while reading header."); -+ return NULL; -+} -+ -+ -+ -+static int dfscanf(fd) -+ int fd; -+{ -+ int i; -+ -+ getline(fd,&ssave[0],&slmax[0]); -+ sscanf(ssave[0],"%d",&i); -+ return(i); -+} -+ -+ -+ -+/*******************************************/ -+int LoadHIPS(fname,pinfo) -+ char *fname; -+ PICINFO * pinfo; -+/*******************************************/ -+{ -+ FILE *fp; -+ struct header h; -+ char * pic; -+ -+ /* open the stream, if necesary */ -+ fp=fopen(fname,"r"); -+ if (!fp) return 0; -+ -+ if (!fread_header(fileno(fp), &h)) { -+ SetISTR(ISTR_WARNING,"Can't read HIPS header"); -+ return 0; -+ } -+ -+ pinfo->w = h.cols; -+ pinfo->h = h.rows; -+ pic = pinfo->pic = (byte *) malloc(h.rows * h.cols); // GRR POSSIBLE OVERFLOW / FIXME -+ if (!pic) FatalError("couldn't malloc HIPS file"); -+ -+ if (!fread(pic, 1, h.cols*h.rows, fp)) { -+ SetISTR(ISTR_WARNING,"Error reading HIPS data.\n"); -+ return 0; -+ } -+ fclose (fp); -+ -+ pinfo->frmType = F_SUNRAS; -+ pinfo->colType = F_FULLCOLOR; -+ sprintf(pinfo->fullInfo, "HIPS file (%d bytes)", h.cols*h.rows); -+ sprintf(pinfo->shrtInfo, "HIPS file."); -+ pinfo->comment = (char *) NULL; -+ -+ { -+ char cmapname[256]; -+ /* Check header for colormap spec */ -+ char * s = h.seq_desc - 1; -+ char * cmaptag = "+COLORMAP"; -+ int sl = strlen(cmaptag); -+ cmapname[0] = 0; -+ while (*++s) -+ if (*s == '+') -+ if (strncmp(s, cmaptag, sl) == 0) { -+ char * p = s + sl; -+ while (*p && (*p == ' ' || *p == '\n' || *p == '\t')) p++; -+ sscanf(p, "%s", cmapname); -+ SetISTR(ISTR_INFO, cmapname); -+ fprintf(stderr, "Colormap = [%s]\n", cmapname); -+ } -+ -+ if (strcmp(cmapname, "gray") == 0 || strcmp(cmapname, "grey") == 0) -+ make_grayscale(pinfo->r, pinfo->g, pinfo->b); -+ else if (strcmp(cmapname, "heat") == 0) -+ make_heatscale(pinfo->r, pinfo->g, pinfo->b); -+ else if (strcmp(cmapname, "hues") == 0) -+ make_huescale(pinfo->r, pinfo->g, pinfo->b); -+ else if (!cmapname[0] || !load_colourmap(cmapname, 256, pinfo->r, pinfo->g, pinfo->b)) -+ make_grayscale(pinfo->r, pinfo->g, pinfo->b); -+ sprintf(pinfo->fullInfo, "HIPS file (%d x %d), Colormap = [%s]", h.cols, h.rows, cmapname); -+ } -+ -+ return 1; -+} -+ -+ -+ -+static void make_grayscale(char * r, char * g, char * b) -+{ -+ int i; -+ /* default grayscale colors */ -+ r[0] = 40; g[0] = 150; b[0] = 100; /* "green4" background */ -+ for(i = 1; i < 256; i++) -+ r[i] = g[i] = b[i] = i; -+} -+ -+ -+ -+static float hls_value (n1, n2, hue) -+ float n1,n2,hue; -+{ -+ if (hue>360.0) -+ hue-=360.0 ; -+ else if (hue<0.0) -+ hue+=360.0 ; -+ -+ if (hue<60.0) -+ return( n1+(n2-n1)*hue/60.0 ) ; -+ else if (hue<180.0) -+ return ( n2 ) ; -+ else if (hue<240.0) -+ return ( n1+(n2-n1)*(240.0-hue)/60.0 ) ; -+ else -+ return (n1) ; -+} -+ -+ -+ -+static void hls_to_rgb(h,l,s, r,g,b) -+ float h, l, s; -+ float *r, *g, *b; -+{ -+ static float m1, m2 ; -+ -+ if (l<=0.5) -+ m2=l*(1+s) ; -+ else -+ m2=l+s-l*s ; -+ m1=2.0*l-m2 ; -+ if (s==0.0) *r=*g=*b=l ; -+ else { -+ *r=hls_value(m1,m2,h+120.0) ; -+ *g=hls_value(m1,m2,h) ; -+ *b=hls_value(m1,m2,h-120.0) ; -+ } -+ -+} -+ -+ -+ -+static void make_huescale(char * r, char * g, char * b) -+{ -+ int j; -+ r[0] = g[0] = b[0] = 0; -+ for (j = 1; j<256; j++) -+ { -+ float fr, fg, fb; -+ hls_to_rgb((double)(256.0-j)*360.0/256.0, 0.5, 1.0, &fr, &fg, &fb); -+ r[j] = rint(255*fr); -+ g[j] = rint(255*fg); -+ b[j] = rint(255*fb); -+ } -+} -+ -+ -+ -+static void make_heatscale(char * r, char * g, char * b) -+{ -+ int j; -+ r[0] = g[0] = b[0] = 0; -+ for (j = 1; j<256; j++) -+ { -+ if(j<255/2) -+ r[j] = j*255/(255/2-1); -+ else -+ r[j]=255; -+ if (j>=255/2+255/3) -+ g[j] = 255; -+ else if (j>255/3) -+ g[j] = (j-255/3)*255/(255/2-1); -+ else -+ g[j] = 0; -+ if (j>255/2) -+ b[j] = (j-255/2)*255/(255-255/2-1); -+ else -+ b[j] = 0; -+ } -+} -+ -+ -+ -+static int load_colourmap(char *filestem, int max_colours, -+ char *r, char *g, char *b) -+{ -+ FILE * fp; -+ int numread=0; -+ char * filename; -+ char str[200]; -+ int num_colors; -+ /* -+ * Look for palette file in local directory -+ */ -+ -+ filename = (char*)alloca(strlen(filestem) + 5); -+ strcpy(filename, filestem); -+ strcat(filename, ".PAL"); /* Add the PAL suffix to the name specified */ -+ fp = fopen(filename,"r"); -+ if (!fp) { -+ /* -+ * If not found, try in $IM2HOME/etc/palettes -+ */ -+ char * im2home = (char*)getenv("IM2HOME"); -+ char * palette_subdirectory = "etc/palettes"; -+ char * fullfilename; -+ if (!im2home) -+ { -+ im2home = "/home/jewel/imagine2"; -+ fprintf(stderr,"IM2HOME environment variable not set -- using [%s]\n",im2home); -+ } -+ fullfilename = alloca(strlen(im2home)+strlen(palette_subdirectory)+strlen(filename)+5); -+ sprintf(fullfilename, "%s/%s/%s",im2home,palette_subdirectory,filename); -+ fp = fopen(fullfilename,"r"); -+ if (!fp) -+ { -+ fprintf(stderr,"Couldn't find any palette file -- looked for [%s] and [%s].\n", -+ filename,fullfilename); -+ perror("Last system error message was"); -+ return 0; -+ } -+ } -+ -+ strcpy(str,"(null)"); -+ if (!fscanf(fp,"%s\n",str) || strncmp(str,"Palette",7) != 0) { -+ fprintf(stderr,"error: First line of palette file should be `Palette', not [%s]\n", str); -+ return 0; -+ } -+ -+ fscanf(fp,"%[^\n]",str) ; /* Scan to end of line */ -+ fscanf (fp,"%d",&num_colors);/* Read the number of colours in the file */ -+ fgets(str,120,fp) ; /* Skip the text description, and general info lines */ -+ fgets(str,120,fp) ; -+ -+ while ((numread<max_colours)&&(numread<num_colors)) { -+ int rc, gc, bc; -+ fscanf (fp,"%d %d %d -", &rc, &gc, &bc) ; /* Get the (r,g,b) tuples */ -+ r[numread] = rc; -+ g[numread] = gc; -+ b[numread] = bc; -+ numread++; -+ fgets(str,120,fp) ; /* Skip the description, if present */ -+ } -+ -+ SetISTR(ISTR_INFO,"Read %d colors from palette file [%s]", numread, filename); -+ return (numread) ; /* Return the number of colours ACTUALLY READ */ -+} -+ -+#endif /* HAVE_HIPS */ -diff -ruN xv-3.10a-bugfixes/xvhips.h xv-3.10a-enhancements/xvhips.h ---- xv-3.10a-bugfixes/xvhips.h 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvhips.h 2005-04-25 08:34:14.000000000 -0700 -@@ -0,0 +1,154 @@ -+/* -+ * HIPL Picture Header Format Standard -+ * -+ * Michael Landy - 2/1/82 -+ */ -+ -+#define XHEADER -+#ifdef XHEADER -+struct extended { -+ char *name; -+ char *vals; -+ }; -+#endif -+ -+struct header { -+ char *orig_name; /* The originator of this sequence */ -+ char *seq_name; /* The name of this sequence */ -+ int num_frame; /* The number of frames in this sequence */ -+ char *orig_date; /* The date the sequence was originated */ -+ int rows; /* The number of rows in each image */ -+ int cols; /* The number of columns in each image */ -+ int bits_per_pixel; /* The number of significant bits per pixel */ -+ int bit_packing; /* Nonzero if bits were packed contiguously */ -+ int pixel_format; /* The format of each pixel, see below */ -+ char *seq_history; /* The sequence's history of transformations */ -+ char *seq_desc; /* Descriptive information */ -+#ifdef XHEADER -+ struct extended *xheader; -+#endif -+}; -+ -+/* -+ * Pixel Format Codes -+ */ -+ -+#define PFBYTE 0 /* Bytes interpreted as integers (8 bits) */ -+#define PFSHORT 1 /* Short integers (2 bytes) */ -+#define PFINT 2 /* Integers (4 bytes) */ -+#define PFFLOAT 3 /* Float's (4 bytes)*/ -+#define PFCOMPLEX 4 /* 2 Float's interpreted as (real,imaginary) */ -+#define PFASCII 5 /* ASCII rep, with linefeeds after each row */ -+#define PFDOUBLE 6 /* Double's (8 byte floats) */ -+#define PFDBLCOM 7 /* Double complex's (2 Double's) */ -+#define PFQUAD 10 /* quad-tree encoding (Mimaging) */ -+#define PFQUAD1 11 /* quad-tree encoding */ -+#define PFBHIST 12 /* histogram of byte image (using ints) */ -+#define PFSPAN 13 /* spanning tree format */ -+#define PLOT3D 24 /* plot-3d format */ -+#define PFINTPYR 50 /* integer pyramid */ -+#define PFFLOATPYR 51 /* float pyramid */ -+#define PFPOLYLINE 100 /* 2D points */ -+#define PFCOLVEC 101 /* Set of RGB triplets defining colours */ -+#define PFUKOOA 102 /* Data in standard UKOOA format */ -+#define PFTRAINING 104 /* Set of colour vector training examples */ -+#define PFTOSPACE 105 /* TOspace world model data structure */ -+#define PFSTEREO 106 /* Stereo sequence (l, r, l, r, ...) */ -+#define PFRGPLINE 107 /* 2D points with regions */ -+#define PFRGISPLINE 108 /* 2D points with regions and interfaces */ -+#define PFCHAIN 200 /* Chain code encoding (Mimaging) */ -+#define PFLUT 300 /* LUT format (uses Ints) (Mimaging) */ -+#define PFAHC 400 /* adaptive hierarchical encoding */ -+#define PFOCT 401 /* oct-tree encoding */ -+#define PFBT 402 /* binary tree encoding */ -+#define PFAHC3 403 /* 3-d adaptive hierarchical encoding */ -+#define PFBQ 404 /* binquad encoding */ -+#define PFRLED 500 /* run-length encoding */ -+#define PFRLEB 501 /* run-length encoding, line begins black */ -+#define PFRLEW 502 /* run-length encoding, line begins white */ -+#define PFPOLAR 600 /* rho-theta format (Mimaging) */ -+ -+/* -+ * Bit packing formats -+ */ -+ -+#define MSBFIRST 1 /* bit packing - most significant bit first */ -+#define LSBFIRST 2 /* bit packing - least significant bit first */ -+ -+#define FBUFLIMIT 30000 /* increase this if you use large PLOT3D -+ files */ -+ -+/* -+ * For general readability -+ */ -+ -+#ifndef TRUE -+# define TRUE 1 -+#endif -+ -+#ifndef FALSE -+# define FALSE 0 -+#endif -+ -+typedef long Boolean; -+extern char *strsave(), *memalloc(); -+ -+/* -+ * image and pyramid type declarations for the pyramid routines. -+ * -+ * The pyramid utilities are derived from code originally written by -+ * Raj Hingorani at SRI/David Sarnoff Research Institute. The original -+ * Gaussian and Laplacian pyramid algorithms were designed by Peter Burt (also -+ * currently at SRI/DSRC). See: Computer Graphics and Image Processing, -+ * Volume 16, pp. 20-51, 1981, and IEEE Transactions on Communications, -+ * Volume COM-31, pp. 532-540, 1983. -+ */ -+ -+#define MAXLEV 12 -+ -+ -+typedef struct { -+ float **ptr; -+ int nr; -+ int nc; -+} FIMAGE; -+ -+typedef struct { -+ int **ptr; -+ int nr; -+ int nc; -+} IIMAGE; -+ -+typedef FIMAGE FPYR[MAXLEV]; -+typedef IIMAGE IPYR[MAXLEV]; -+ -+typedef struct { -+ float *k; -+ int taps2; /* the number of taps from the center rightward, -+ total number is 2*taps2-1 */ -+} FILTER; -+ -+/* function definitions */ -+ -+float **_read_fimgstr(); -+int **_read_iimgstr(); -+float **_alloc_fimage(); -+int **_alloc_iimage(); -+ -+/* image macros */ -+ -+#ifndef MAX -+# define MAX(A,B) ((A) > (B) ? (A) : (B)) -+#endif /* MAX */ -+#ifndef MIN -+# define MIN(A,B) ((A) < (B) ? (A) : (B)) -+#endif /* MIN */ -+#ifndef ABS -+# define ABS(A) ((A) > 0 ? (A) : (-(A))) -+#endif /* ABS */ -+#ifndef BETWEEN -+# define BETWEEN(A,B,C) (((A) < (B)) ? (B) : (((A) > (C)) ? (C) : (A))) -+#endif /* BETWEEN */ -+#ifndef SIGN -+# define SIGN(A,B) (((B) > 0) ? (A) : (-(A))) -+#endif /* SIGN */ -diff -ruN xv-3.10a-bugfixes/xvimage.c xv-3.10a-enhancements/xvimage.c ---- xv-3.10a-bugfixes/xvimage.c 2005-03-31 07:23:39.000000000 -0800 -+++ xv-3.10a-enhancements/xvimage.c 2005-04-17 23:00:10.000000000 -0700 -@@ -21,6 +21,16 @@ - * int LoadPad(pinfo, fname); - */ - -+/* The following switch should better be provided at runtime for -+ * comparison purposes. -+ * At the moment it's only compile time, unfortunately. -+ * Who can make adaptions for use as a runtime switch by a menu option? -+ * [GRR 19980607: now via do_fixpix_smooth global; macro renamed to ENABLE_] -+ * [see http://sylvana.net/fixpix/ for home page, further info] -+ */ -+/* #define ENABLE_FIXPIX_SMOOTH */ /* GRR 19980607: moved into xv.h */ -+ -+#define NEEDSDIR /* for S_IRUSR|S_IWUSR */ - #include "copyright.h" - - #include "xv.h" -@@ -36,7 +46,9 @@ - static int doAutoCrop24 PARM((void)); - static void floydDitherize1 PARM((XImage *, byte *, int, int, int, - byte *, byte *,byte *)); -+#if 0 /* NOTUSED */ - static int highbit PARM((unsigned long)); -+#endif - - static int doPadSolid PARM((char *, int, int, int, int)); - static int doPadBggen PARM((char *, int, int, int, int)); -@@ -46,6 +58,267 @@ - static int ReadImageFile1 PARM((char *, PICINFO *)); - - -+/* The following array represents the pixel values for each shade -+ * of the primary color components. -+ * If 'p' is a pointer to a source image rgb-byte-triplet, we can -+ * construct the output pixel value simply by 'oring' together -+ * the corresponding components: -+ * -+ * unsigned char *p; -+ * unsigned long pixval; -+ * -+ * pixval = screen_rgb[0][*p++]; -+ * pixval |= screen_rgb[1][*p++]; -+ * pixval |= screen_rgb[2][*p++]; -+ * -+ * This is both efficient and generic, since the only assumption -+ * is that the primary color components have separate bits. -+ * The order and distribution of bits does not matter, and we -+ * don't need additional variables and shifting/masking code. -+ * The array size is 3 KBytes total and thus very reasonable. -+ */ -+ -+static unsigned long screen_rgb[3][256]; -+ -+/* The following array holds the exact color representations -+ * reported by the system. -+ * This is useful for less than 24 bit deep displays as a base -+ * for additional dithering to get smoother output. -+ */ -+ -+static byte screen_set[3][256]; -+ -+/* The following routine initializes the screen_rgb and screen_set -+ * arrays. -+ * Since it is executed only once per program run, it does not need -+ * to be super-efficient. -+ * -+ * The method is to draw points in a pixmap with the specified shades -+ * of primary colors and then get the corresponding XImage pixel -+ * representation. -+ * Thus we can get away with any Bit-order/Byte-order dependencies. -+ * -+ * The routine uses some global X variables: theDisp, theScreen, -+ * and dispDEEP. Adapt these to your application as necessary. -+ * I've not passed them in as parameters, since for other platforms -+ * than X these may be different (see vfixpix.c), and so the -+ * screen_init() interface is unique. -+ * -+ * BUG: I've read in the "Xlib Programming Manual" from O'Reilly & -+ * Associates, that the DefaultColormap in TrueColor might not -+ * provide the full shade representation in XAllocColor. -+ * In this case one had to provide a 'best' colormap instead. -+ * However, my tests with Xaccel on a Linux-Box with a Mach64 -+ * card were fully successful, so I leave that potential problem -+ * to you at the moment and would appreciate any suggestions... -+ */ -+ -+static void screen_init() -+{ -+ static int init_flag; /* assume auto-init as 0 */ -+ Pixmap check_map; -+ GC check_gc; -+ XColor check_col; -+ XImage *check_image; -+ int ci, i; -+ -+ if (init_flag) return; -+ init_flag = 1; -+ -+ check_map = XCreatePixmap(theDisp, RootWindow(theDisp,theScreen), -+ 1, 1, dispDEEP); -+ check_gc = XCreateGC(theDisp, check_map, 0, NULL); -+ for (ci = 0; ci < 3; ci++) { -+ for (i = 0; i < 256; i++) { -+ check_col.red = 0; -+ check_col.green = 0; -+ check_col.blue = 0; -+ /* Do proper upscaling from unsigned 8 bit (image data values) -+ to unsigned 16 bit (X color representation). */ -+ ((unsigned short *)&check_col.red)[ci] = (unsigned short)((i << 8) | i); -+ if (theVisual->class == TrueColor) -+ XAllocColor(theDisp, theCmap, &check_col); -+ else -+ xvAllocColor(theDisp, theCmap, &check_col); -+ screen_set[ci][i] = -+ (((unsigned short *)&check_col.red)[ci] >> 8) & 0xff; -+ XSetForeground(theDisp, check_gc, check_col.pixel); -+ XDrawPoint(theDisp, check_map, check_gc, 0, 0); -+ check_image = XGetImage(theDisp, check_map, 0, 0, 1, 1, -+ AllPlanes, ZPixmap); -+ if (check_image) { -+ switch (check_image->bits_per_pixel) { -+ case 8: -+ screen_rgb[ci][i] = *(CARD8 *)check_image->data; -+ break; -+ case 16: -+ screen_rgb[ci][i] = *(CARD16 *)check_image->data; -+ break; -+ case 24: -+ screen_rgb[ci][i] = -+ ((unsigned long)*(CARD8 *)check_image->data << 16) | -+ ((unsigned long)*(CARD8 *)(check_image->data + 1) << 8) | -+ (unsigned long)*(CARD8 *)(check_image->data + 2); -+ break; -+ case 32: -+ screen_rgb[ci][i] = *(CARD32 *)check_image->data; -+ break; -+ } -+ XDestroyImage(check_image); -+ } -+ } -+ } -+ XFreeGC(theDisp, check_gc); -+ XFreePixmap(theDisp, check_map); -+} -+ -+ -+#ifdef ENABLE_FIXPIX_SMOOTH -+ -+/* The following code is based in part on: -+ * -+ * jquant1.c -+ * -+ * Copyright (C) 1991-1996, Thomas G. Lane. -+ * This file is part of the Independent JPEG Group's software. -+ * For conditions of distribution and use, see the accompanying README file. -+ * -+ * This file contains 1-pass color quantization (color mapping) routines. -+ * These routines provide mapping to a fixed color map using equally spaced -+ * color values. Optional Floyd-Steinberg or ordered dithering is available. -+ */ -+ -+/* Declarations for Floyd-Steinberg dithering. -+ * -+ * Errors are accumulated into the array fserrors[], at a resolution of -+ * 1/16th of a pixel count. The error at a given pixel is propagated -+ * to its not-yet-processed neighbors using the standard F-S fractions, -+ * ... (here) 7/16 -+ * 3/16 5/16 1/16 -+ * We work left-to-right on even rows, right-to-left on odd rows. -+ * -+ * We can get away with a single array (holding one row's worth of errors) -+ * by using it to store the current row's errors at pixel columns not yet -+ * processed, but the next row's errors at columns already processed. We -+ * need only a few extra variables to hold the errors immediately around the -+ * current column. (If we are lucky, those variables are in registers, but -+ * even if not, they're probably cheaper to access than array elements are.) -+ * -+ * We provide (#columns + 2) entries per component; the extra entry at each -+ * end saves us from special-casing the first and last pixels. -+ */ -+ -+typedef INT16 FSERROR; /* 16 bits should be enough */ -+typedef int LOCFSERROR; /* use 'int' for calculation temps */ -+ -+typedef struct { byte *colorset; -+ FSERROR *fserrors; -+ } FSBUF; -+ -+/* Floyd-Steinberg initialization function. -+ * -+ * It is called 'fs2_init' since it's specialized for our purpose and -+ * could be embedded in a more general FS-package. -+ * -+ * Returns a malloced FSBUF pointer which has to be passed as first -+ * parameter to subsequent 'fs2_dither' calls. -+ * The FSBUF structure does not need to be referenced by the calling -+ * application, it can be treated from the app like a void pointer. -+ * -+ * The current implementation does only require to free() this returned -+ * pointer after processing. -+ * -+ * Returns NULL if malloc fails. -+ * -+ * NOTE: The FSBUF structure is designed to allow the 'fs2_dither' -+ * function to work with an *arbitrary* number of color components -+ * at runtime! This is an enhancement over the IJG code base :-). -+ * Only fs2_init() specifies the (maximum) number of components. -+ */ -+ -+static FSBUF *fs2_init(width) -+int width; -+{ -+ FSBUF *fs; -+ FSERROR *p; -+ -+ fs = (FSBUF *) -+ malloc(sizeof(FSBUF) * 3 + ((size_t)width + 2) * sizeof(FSERROR) * 3); -+ if (fs == 0) return fs; -+ -+ fs[0].colorset = screen_set[0]; -+ fs[1].colorset = screen_set[1]; -+ fs[2].colorset = screen_set[2]; -+ -+ p = (FSERROR *)(fs + 3); -+ memset(p, 0, ((size_t)width + 2) * sizeof(FSERROR) * 3); -+ -+ fs[0].fserrors = p; -+ fs[1].fserrors = p + 1; -+ fs[2].fserrors = p + 2; -+ -+ return fs; -+} -+ -+/* Floyd-Steinberg dithering function. -+ * -+ * NOTE: -+ * (1) The image data referenced by 'ptr' is *overwritten* (input *and* -+ * output) to allow more efficient implementation. -+ * (2) Alternate FS dithering is provided by the sign of 'nc'. Pass in -+ * a negative value for right-to-left processing. The return value -+ * provides the right-signed value for subsequent calls! -+ * (3) This particular implementation assumes *no* padding between lines! -+ * Adapt this if necessary. -+ */ -+ -+static int fs2_dither(fs, ptr, nc, num_rows, num_cols) -+FSBUF *fs; -+byte *ptr; -+int nc, num_rows, num_cols; -+{ -+ int abs_nc, ci, row, col; -+ LOCFSERROR delta, cur, belowerr, bpreverr; -+ byte *dataptr, *colsetptr; -+ FSERROR *errorptr; -+ -+ if ((abs_nc = nc) < 0) abs_nc = -abs_nc; -+ for (row = 0; row < num_rows; row++) { -+ for (ci = 0; ci < abs_nc; ci++, ptr++) { -+ dataptr = ptr; -+ colsetptr = fs[ci].colorset; -+ errorptr = fs[ci].fserrors; -+ if (nc < 0) { -+ dataptr += (num_cols - 1) * abs_nc; -+ errorptr += (num_cols + 1) * abs_nc; -+ } -+ cur = belowerr = bpreverr = 0; -+ for (col = 0; col < num_cols; col++) { -+ cur += errorptr[nc]; -+ cur += 8; cur >>= 4; -+ if ((cur += *dataptr) < 0) cur = 0; -+ else if (cur > 255) cur = 255; -+ *dataptr = cur & 0xff; -+ cur -= colsetptr[cur]; -+ delta = cur << 1; cur += delta; -+ bpreverr += cur; cur += delta; -+ belowerr += cur; cur += delta; -+ errorptr[0] = (FSERROR)bpreverr; -+ bpreverr = belowerr; -+ belowerr = delta >> 1; -+ dataptr += nc; -+ errorptr += nc; -+ } -+ errorptr[0] = (FSERROR)bpreverr; -+ } -+ ptr += (num_cols - 1) * abs_nc; -+ nc = -nc; -+ } -+ return nc; -+} -+ -+#endif /* ENABLE_FIXPIX_SMOOTH */ -+ - - #define DO_CROP 0 - #define DO_ZOOM 1 -@@ -1348,7 +1621,7 @@ - SetISTR(ISTR_WARNING, "Invalid image dimensions for dithering"); - return (byte *)NULL; - } -- -+ - outpic = (byte *) malloc((size_t) npixels); - if (!outpic) return outpic; - -@@ -1838,7 +2111,7 @@ - unsigned int wide, high; - { - /* -- * this has to do the none-to-simple bit of converting the data in 'pic24' -+ * This has to do the none-too-simple bit of converting the data in 'pic24' - * into something usable by X. - * - * There are two major approaches: if we're displaying on a TrueColor -@@ -1852,7 +2125,7 @@ - * mode. (In that by this point, a 3/3/2 standard colormap has been - * created for our use (though all 256 colors may not be unique...), and - * we're just going to display the 24-bit picture by dithering with those -- * colors -+ * colors.) - * - */ - -@@ -1890,33 +2163,17 @@ - /* Non-ColorMapped Visuals: TrueColor, DirectColor */ - /************************************************************************/ - -- unsigned long r, g, b, rmask, gmask, bmask, xcol; -- int rshift, gshift, bshift, bperpix, bperline, border, cshift; -- int maplen; -+ unsigned long xcol; -+ int bperpix, bperline; - byte *imagedata, *lip, *ip, *pp; - - -- /* compute various shifting constants that we'll need... */ -- -- rmask = theVisual->red_mask; -- gmask = theVisual->green_mask; -- bmask = theVisual->blue_mask; -- -- rshift = 7 - highbit(rmask); -- gshift = 7 - highbit(gmask); -- bshift = 7 - highbit(bmask); -- -- maplen = theVisual->map_entries; -- if (maplen>256) maplen=256; -- cshift = 7 - highbit((u_long) (maplen-1)); -- - xim = XCreateImage(theDisp, theVisual, dispDEEP, ZPixmap, 0, NULL, - wide, high, 32, 0); - if (!xim) FatalError("couldn't create X image!"); - - bperline = xim->bytes_per_line; - bperpix = xim->bits_per_pixel; -- border = xim->byte_order; - - imagedata = (byte *) malloc((size_t) (high * bperline)); - if (!imagedata) FatalError("couldn't malloc imagedata"); -@@ -1930,85 +2187,141 @@ - FatalError(buf); - } - -+ screen_init(); - -- lip = imagedata; pp = pic24; -- for (i=0; i<high; i++, lip+=bperline) { -- for (j=0, ip=lip; j<wide; j++) { -- r = *pp++; g = *pp++; b = *pp++; -- -- /* shift r,g,b so that high bit of 8-bit color specification is -- * aligned with high bit of r,g,b-mask in visual, -- * AND each component with its mask, -- * and OR the three components together -- */ -- -- if (theVisual->class == DirectColor) { -- r = (u_long) directConv[(r>>cshift) & 0xff] << cshift; -- g = (u_long) directConv[(g>>cshift) & 0xff] << cshift; -- b = (u_long) directConv[(b>>cshift) & 0xff] << cshift; -- } -- -- -- /* shift the bits around */ -- if (rshift<0) r = r << (-rshift); -- else r = r >> rshift; -- -- if (gshift<0) g = g << (-gshift); -- else g = g >> gshift; -- -- if (bshift<0) b = b << (-bshift); -- else b = b >> bshift; -- -- r = r & rmask; -- g = g & gmask; -- b = b & bmask; -- -- xcol = r | g | b; -- -- if (bperpix == 32) { -- if (border == MSBFirst) { -- *ip++ = (xcol>>24) & 0xff; -- *ip++ = (xcol>>16) & 0xff; -- *ip++ = (xcol>>8) & 0xff; -- *ip++ = xcol & 0xff; -- } -- else { /* LSBFirst */ -- *ip++ = xcol & 0xff; -- *ip++ = (xcol>>8) & 0xff; -- *ip++ = (xcol>>16) & 0xff; -- *ip++ = (xcol>>24) & 0xff; -- } -- } -- -- else if (bperpix == 24) { -- if (border == MSBFirst) { -- *ip++ = (xcol>>16) & 0xff; -- *ip++ = (xcol>>8) & 0xff; -- *ip++ = xcol & 0xff; -- } -- else { /* LSBFirst */ -- *ip++ = xcol & 0xff; -- *ip++ = (xcol>>8) & 0xff; -- *ip++ = (xcol>>16) & 0xff; -- } -- } -+#ifdef ENABLE_FIXPIX_SMOOTH -+ if (do_fixpix_smooth) { -+#if 0 -+ /* If we wouldn't have to save the original pic24 image data, -+ * the following code would do the dither job by overwriting -+ * the image data, and the normal render code would then work -+ * without any change on that data. -+ * Unfortunately, this approach would hurt the xv assumptions... -+ */ -+ if (bperpix < 24) { -+ FSBUF *fs = fs2_init(wide); -+ if (fs) { -+ fs2_dither(fs, pic24, 3, high, wide); -+ free(fs); -+ } -+ } -+#else -+ /* ...so we have to take a different approach with linewise -+ * dithering/rendering in a loop using a temporary line buffer. -+ */ -+ if (bperpix < 24) { -+ FSBUF *fs = fs2_init(wide); -+ if (fs) { -+ byte *row_buf = malloc((size_t)wide * 3); -+ if (row_buf) { -+ int nc = 3; -+ byte *picp = pic24; lip = imagedata; -+ -+ switch (bperpix) { -+ case 8: -+ for (i=0; i<high; i++, lip+=bperline, picp+=(size_t)wide*3) { -+ memcpy(row_buf, picp, (size_t)wide * 3); -+ nc = fs2_dither(fs, row_buf, nc, 1, wide); -+ for (j=0, ip=lip, pp=row_buf; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+ *ip++ = xcol & 0xff; -+ } -+ } -+ break; -+ -+ case 16: -+ for (i=0; i<high; i++, lip+=bperline, picp+=(size_t)wide*3) { -+ CARD16 *ip16 = (CARD16 *)lip; -+ memcpy(row_buf, picp, (size_t)wide * 3); -+ nc = fs2_dither(fs, row_buf, nc, 1, wide); -+ for (j=0, pp=row_buf; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+ *ip16++ = (CARD16)xcol; -+ } -+ } -+ break; -+ } /* end switch */ -+ -+ free(row_buf); -+ free(fs); - -- else if (bperpix == 16) { -- if (border == MSBFirst) { -- *ip++ = (xcol>>8) & 0xff; -- *ip++ = xcol & 0xff; -- } -- else { /* LSBFirst */ -- *ip++ = xcol & 0xff; -- *ip++ = (xcol>>8) & 0xff; -+ return xim; - } -- } -- -- else if (bperpix == 8) { -- *ip++ = xcol & 0xff; -- } -+ free(fs); -+ } - } -+#endif /* 0? */ - } -+#endif /* ENABLE_FIXPIX_SMOOTH */ -+ -+ lip = imagedata; pp = pic24; -+ -+ switch (bperpix) { -+ case 8: -+ for (i=0; i<high; i++, lip+=bperline) { -+ for (j=0, ip=lip; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+ *ip++ = xcol & 0xff; -+ } -+ } -+ break; -+ -+ case 16: -+ for (i=0; i<high; i++, lip+=bperline) { -+ CARD16 *ip16 = (CARD16 *)lip; -+ for (j=0; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+ *ip16++ = (CARD16)xcol; -+ } -+ } -+ break; -+ -+ case 24: -+ for (i=0; i<high; i++, lip+=bperline) { -+ for (j=0, ip=lip; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+#ifdef USE_24BIT_ENDIAN_FIX -+ if (border == MSBFirst) { -+ *ip++ = (xcol>>16) & 0xff; -+ *ip++ = (xcol>>8) & 0xff; -+ *ip++ = xcol & 0xff; -+ } -+ else { /* LSBFirst */ -+ *ip++ = xcol & 0xff; -+ *ip++ = (xcol>>8) & 0xff; -+ *ip++ = (xcol>>16) & 0xff; -+ } -+#else /* GRR: this came with the FixPix patch, but I don't think it's right */ -+ *ip++ = (xcol >> 16) & 0xff; /* (no way to test, however, so */ -+ *ip++ = (xcol >> 8) & 0xff; /* it's left enabled by default) */ -+ *ip++ = xcol & 0xff; -+#endif -+ } -+ } -+ break; -+ -+ case 32: -+ for (i=0; i<high; i++, lip+=bperline) { -+ CARD32 *ip32 = (CARD32 *)lip; -+ for (j=0; j<wide; j++) { -+ xcol = screen_rgb[0][*pp++]; -+ xcol |= screen_rgb[1][*pp++]; -+ xcol |= screen_rgb[2][*pp++]; -+ *ip32++ = (CARD32)xcol; -+ } -+ } -+ break; -+ } /* end switch */ - } - - else { -@@ -2458,6 +2771,7 @@ - - - /***********************/ -+#if 0 /* NOTUSED */ - static int highbit(ul) - unsigned long ul; - { -@@ -2470,6 +2784,7 @@ - for (i=31; ((ul & hb) == 0) && i>=0; i--, ul<<=1); - return i; - } -+#endif /* 0 - NOTUSED */ - - - -@@ -2680,6 +2995,9 @@ - char *str; - int wide, high, opaque,omode; - { -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif - int i; - byte *bgpic24; - char syscmd[512], fname[128], errstr[512]; -@@ -2705,6 +3023,13 @@ - close(mkstemp(fname)); - #else - mktemp(fname); -+ tmpfd = open(fname, O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) { -+ sprintf(errstr, "Error: can't create temporary file %s", fname); -+ ErrPopUp(errstr, "\nDoh!"); -+ return 0; -+ } -+ close(tmpfd); - #endif - - /* run bggen to generate the background */ -@@ -2978,7 +3303,7 @@ - - ftype = ReadFileType(name); - -- if (ftype == RFT_COMPRESS) { /* handle compressed/gzipped files */ -+ if ((ftype == RFT_COMPRESS) || (ftype == RFT_BZIP2)) { /* handle .Z,gz,bz2 */ - #ifdef VMS - basefname[0] = '\0'; - strcpy(basefname, name); /* remove trailing .Z */ -@@ -2988,7 +3313,7 @@ - uncName = name; - #endif - -- if (UncompressFile(uncName, uncompname)) { -+ if (UncompressFile(uncName, uncompname, ftype)) { - ftype = ReadFileType(uncompname); - readname = uncompname; - } -@@ -3029,9 +3354,3 @@ - - return 1; - } -- -- -- -- -- -- -diff -ruN xv-3.10a-bugfixes/xvinfo.c xv-3.10a-enhancements/xvinfo.c ---- xv-3.10a-bugfixes/xvinfo.c 2004-05-16 18:03:43.000000000 -0700 -+++ xv-3.10a-enhancements/xvinfo.c 2005-05-01 00:05:53.000000000 -0700 -@@ -265,7 +265,7 @@ - if (stnum == ISTR_WARNING && !ctrlUp && !infoUp && !anyBrowUp && - strlen(istrs[stnum])) { - OpenAlert(istrs[stnum]); -- sleep(3); -+ sleep(1); /* was 3, but _really_ slow for TIFFs with unknown tags... */ - CloseAlert(); - } - } -diff -ruN xv-3.10a-bugfixes/xvjpeg.c xv-3.10a-enhancements/xvjpeg.c ---- xv-3.10a-bugfixes/xvjpeg.c 2005-03-27 16:23:06.000000000 -0800 -+++ xv-3.10a-enhancements/xvjpeg.c 2005-04-17 14:45:28.000000000 -0700 -@@ -51,11 +51,21 @@ - static void clickJD PARM((int, int)); - static void doCmd PARM((int)); - static void writeJPEG PARM((void)); -+#if JPEG_LIB_VERSION > 60 -+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)); -+#else - 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)); -+#endif - static unsigned int j_getc PARM((j_decompress_ptr)); -+#if JPEG_LIB_VERSION > 60 -+METHODDEF(boolean) xv_process_comment PARM((j_decompress_ptr)); -+#else - METHODDEF boolean xv_process_comment PARM((j_decompress_ptr)); -+#endif - static int writeJFIF PARM((FILE *, byte *, int,int,int)); - - -@@ -85,10 +95,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, -@@ -415,7 +425,11 @@ - - - /**************************************************/ --METHODDEF void xv_error_exit(cinfo) -+#if JPEG_LIB_VERSION > 60 -+METHODDEF(void) xv_error_exit(cinfo) -+#else -+METHODDEF void xv_error_exit(cinfo) -+#endif - j_common_ptr cinfo; - { - my_error_ptr myerr; -@@ -427,7 +441,11 @@ - - - /**************************************************/ --METHODDEF void xv_error_output(cinfo) -+#if JPEG_LIB_VERSION > 60 -+METHODDEF(void) xv_error_output(cinfo) -+#else -+METHODDEF void xv_error_output(cinfo) -+#endif - j_common_ptr cinfo; - { - my_error_ptr myerr; -@@ -441,7 +459,11 @@ - - - /**************************************************/ --METHODDEF void xv_prog_meter(cinfo) -+#if JPEG_LIB_VERSION > 60 -+METHODDEF(void) xv_prog_meter(cinfo) -+#else -+METHODDEF void xv_prog_meter(cinfo) -+#endif - j_common_ptr cinfo; - { - struct jpeg_progress_mgr *prog; -@@ -706,7 +728,11 @@ - - - /**************************************************/ --METHODDEF boolean xv_process_comment(cinfo) -+#if JPEG_LIB_VERSION > 60 -+METHODDEF(boolean) xv_process_comment(cinfo) -+#else -+METHODDEF boolean xv_process_comment(cinfo) -+#endif - j_decompress_ptr cinfo; - { - int length, hasnull; -@@ -794,8 +820,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); -@@ -804,7 +830,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; -@@ -866,4 +892,27 @@ - - - -+ -+/*******************************************/ -+void -+VersionInfoJPEG() /* GRR 19980605, 19980607 */ -+{ -+ int major = JPEG_LIB_VERSION / 10; -+ int minor = JPEG_LIB_VERSION % 10; -+ char minoralpha[2]; -+ -+ if (minor) { -+ minoralpha[0] = (char)(minor - 1 + 'a'); -+ minoralpha[1] = '\0'; -+ } else -+ minoralpha[0] = '\0'; -+ -+/* fprintf(stderr, " Compiled with libjpeg %d.%d.\n", major, minor); */ -+ fprintf(stderr, " Compiled with libjpeg %d%s.\n", major, minoralpha); -+} -+ -+ -+ -+ -+ - #endif /* HAVE_JPEG */ -diff -ruN xv-3.10a-bugfixes/xvmag.c xv-3.10a-enhancements/xvmag.c ---- xv-3.10a-bugfixes/xvmag.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvmag.c 2005-04-17 22:56:58.000000000 -0700 -@@ -0,0 +1,866 @@ -+/* -+ * xvmag.c - load routine for `MAG' format pictures. -+ * -+ * The `MAG' format is used by many Japanese personal computer users. -+ * This program is based on MAGBIBLE.DOC which is the specification -+ * for `MAG' format written by Woody RINN. It is written in Japanese, -+ * and exists in some anon-ftp sites. -+ */ -+ -+#include "xv.h" -+#include <setjmp.h> -+ -+#ifdef HAVE_MAG -+ -+typedef unsigned short data16; -+ -+struct mag { -+ jmp_buf jmp; -+ FILE *fp; -+ long fsize; -+ int m_256, m_dig, m_8, m_200; -+ int x1, y1, x2, y2, left_pad, right_pad; -+ int p_width, p_height, width, height; -+ long h_off, a_off, a_size, b_off, b_size, p_off, p_size; -+ byte *a, *b, *p; -+}; -+ -+static void mag_open_file PARM((struct mag*, char*)); -+static void mag_read_check_data PARM((struct mag*)); -+static void mag_read_comment PARM((struct mag*, char**)); -+static void mag_read_header PARM((struct mag*)); -+static void mag_read_palette PARM((struct mag*, byte*, byte*, byte*)); -+static void mag_read_flags PARM((struct mag*)); -+static void mag_read_pixel_data PARM((struct mag*)); -+static void mag_expand_body PARM((struct mag*, byte**)); -+ -+static void mag_compress_data PARM((struct mag*, byte*)); -+static void mag_write_check_data PARM((struct mag*)); -+static void mag_write_comment PARM((struct mag*, char *)); -+static void mag_write_palette PARM((struct mag*, int, -+ byte*, byte*, byte*, int)); -+static void mag_write_flags PARM((struct mag*)); -+static void mag_write_pixel_data PARM((struct mag*)); -+static void mag_write_header PARM((struct mag*)); -+static void mag_set_double_word PARM((long, byte *)); -+ -+static void mag_init_info PARM((struct mag*)); -+static void mag_cleanup_mag_info PARM((struct mag*, int)); -+static void mag_cleanup_pinfo PARM((PICINFO*)); -+static void mag_memory_error PARM((char*, char*)); -+static void mag_error PARM((struct mag*, int)); -+static void mag_file_error PARM((struct mag*, int)); -+static void mag_file_warning PARM((struct mag*, int)); -+static void mag_show_struct PARM((struct mag*)); -+static void *mag_malloc PARM((size_t, char*)); -+static void *mag_realloc PARM((void*, size_t, char*)); -+ -+ -+static char *mag_id = "MAKI02 "; -+static struct{ -+ int dx, dy; -+}points[16] = { -+ { 0, 0}, { 1, 0}, { 2, 0}, { 4, 0}, -+ { 0, 1}, { 1, 1}, -+ { 0, 2}, { 1, 2}, { 2, 2}, -+ { 0, 4}, { 1, 4}, { 2, 4}, -+ { 0, 8}, { 1, 8}, { 2, 8}, -+ { 0, 16}, -+}; -+static int try[15] = {1, 4, 5, 6, 7, 9, 10, 2, 8, 11, 12, 13, 14, 3, 15}; -+ -+static char *mag_msgs[] = { -+ NULL, -+#define MAG_OPEN 1 -+ "can't open file", -+#define MAG_CORRUPT 2 -+ "file currupted.", -+#define MAG_FORMAT 3 -+ "not MAG format.", -+#define MAG_WRITE 4 -+ "write failed.", -+}; -+ -+ -+#define H4(x) (((int) (x) >> 4) & 0x0f) /* operates on a byte */ -+#define L4(x) ((x) & 0x0f) -+#define H8(x) (((x) >> 8) & 0xff) /* operates on a data16 */ -+#define L8(x) ((x) & 0xff) -+ -+#define error(msgnum) longjmp(mi->jmp, msgnum) -+ -+ -+/* The main routine to load a MAG file. */ -+int LoadMAG(fname, pinfo) -+ char *fname; -+ PICINFO *pinfo; -+{ -+ struct mag mag; -+ int e; -+ -+ if(DEBUG) fputs("LoadMAG:\n", stderr); -+ -+ pinfo->comment = NULL; -+ mag_init_info(&mag); -+ if((e = setjmp(mag.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ mag_cleanup_mag_info(&mag, 0); -+ mag_cleanup_pinfo(pinfo); -+ return 0; -+ } -+ -+ mag_open_file(&mag, fname); -+ mag_read_check_data(&mag); -+ mag_read_comment(&mag, &pinfo->comment); -+ mag_read_header(&mag); -+ mag_read_palette(&mag, pinfo->r, pinfo->g, pinfo->b); -+ mag_read_flags(&mag); -+ mag_read_pixel_data(&mag); -+ mag_expand_body(&mag, &pinfo->pic); -+ -+ pinfo->w = pinfo->normw = mag.width; -+ pinfo->h = pinfo->normh = mag.height; -+ pinfo->type = PIC8; -+ pinfo->frmType = F_MAG; -+ pinfo->colType = F_FULLCOLOR; -+ sprintf(pinfo->fullInfo, "MAG, %d colors%s (%ld bytes)", -+ mag.m_256 ? 256 : (mag.m_8 ? 8 : 16), -+ mag.m_200 ? ", aspect 0.5" : "", mag.fsize); -+ sprintf(pinfo->shrtInfo, "%dx%d MAG", mag.width, mag.height); -+ if(mag.m_200) -+ normaspect = 0.5; -+ -+ mag_cleanup_mag_info(&mag, 0); -+ return 1; -+} -+ -+static void mag_open_file(mi, fname) -+ struct mag *mi; -+ char *fname; -+{ -+ if((mi->fp = fopen(fname, "rb")) == NULL) -+ mag_file_error(mi, MAG_OPEN); -+ fseek(mi->fp, (size_t) 0, SEEK_END); -+ mi->fsize = ftell(mi->fp); -+ fseek(mi->fp, (size_t) 0, SEEK_SET); -+} -+ -+static void mag_read_check_data(mi) -+ struct mag *mi; -+{ -+ char buffer[8]; -+ -+ if(fread(buffer, (size_t) 8, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_CORRUPT); -+ if(strncmp(buffer, mag_id, (size_t) 8) != 0) -+ mag_error(mi, MAG_FORMAT); -+} -+ -+static void mag_read_comment(mi, p) -+ struct mag *mi; -+ char **p; -+{ -+ int max = -1, i = 0; -+ int c; -+ -+ while((c = fgetc(mi->fp)) != EOF){ -+ if(c == 0x1a) -+ break; -+ if(max < i){ -+ max += 16; -+ *p = mag_realloc(*p, (size_t) max + 1, "mag_read_comment#1"); -+ } -+ (*p)[i++] = c; -+ } -+ -+ if(c == EOF) -+ mag_file_error(mi, MAG_CORRUPT); -+ -+ if(max < i){ -+ *p = mag_realloc(*p, (size_t) max + 2, "mag_read_comment#2"); -+ } -+ if(i > 24){ -+ (*p)[i] = '\0'; -+ strcpy(*p, &(*p)[24]); -+ }else{ -+ (*p)[0] = '\0'; -+ } -+} -+ -+static void mag_read_header(mi) -+ struct mag *mi; -+{ -+ byte buf[32]; -+ -+ mi->h_off = ftell(mi->fp); -+ -+ if(fread(buf, (size_t) 32, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_CORRUPT); -+ -+ mi->m_256 = buf[3] & 0x80; -+ mi->m_dig = buf[3] & 0x04; -+ mi->m_8 = buf[3] & 0x02; -+ mi->m_200 = buf[3] & 0x01; -+ -+ mi->x1 = buf[ 4] + buf[ 5] * 256; -+ mi->y1 = buf[ 6] + buf[ 7] * 256; -+ mi->x2 = buf[ 8] + buf[ 9] * 256; -+ mi->y2 = buf[10] + buf[11] * 256; -+ -+#define get_dword(a, b, c, d) \ -+ ((long)(a) << 24 | (long)(b) << 16 | (long)(c) << 8 | (long)(d)) -+ -+ mi->a_off = get_dword(buf[15], buf[14], buf[13], buf[12]); -+ mi->b_off = get_dword(buf[19], buf[18], buf[17], buf[16]); -+ mi->b_size = get_dword(buf[23], buf[22], buf[21], buf[20]); -+ mi->p_off = get_dword(buf[27], buf[26], buf[25], buf[24]); -+ mi->p_size = get_dword(buf[31], buf[30], buf[29], buf[28]); -+#undef get_dword -+ -+ mi->a_size = mi->b_off - mi->a_off; -+ mi->a_off += mi->h_off; -+ mi->b_off += mi->h_off; -+ mi->p_off += mi->h_off; -+ -+ mi->width = mi->x2 - mi->x1 + 1; -+ mi->height = mi->y2 - mi->y1 + 1; -+ mi->left_pad = mi->x1 & 07; -+ mi->right_pad = 07 - (mi->x2 & 07); -+ mi->x1 -= mi->left_pad; /* x1 = 8m */ -+ mi->x2 += mi->right_pad; /* x2 = 8n+7 */ -+ mi->p_width = ((mi->x2 + 1) - mi->x1) / (mi->m_256 ? 2 : 4); -+ mi->p_height = (mi->y2 + 1) - mi->y1; -+ -+ if(DEBUG) mag_show_struct(mi); -+} -+ -+static void mag_read_palette(mi, r, g, b) -+ struct mag *mi; -+ byte *r, *g, *b; -+{ -+ int num_palettes; -+ byte *buf; -+ -+ if(mi->m_256) -+ num_palettes = 256; -+ else -+ num_palettes = 16; -+ -+ buf = mag_malloc((size_t)num_palettes * 3, "mag_read_palette"); -+ -+ if(fread(buf, (size_t) 3, (size_t) num_palettes, mi->fp) != num_palettes){ -+ free(buf); -+ mag_file_error(mi, MAG_CORRUPT); -+ } -+ -+ for(num_palettes--; num_palettes >= 0; num_palettes--){ -+ g[num_palettes] = buf[num_palettes * 3 ]; -+ r[num_palettes] = buf[num_palettes * 3 + 1]; -+ b[num_palettes] = buf[num_palettes * 3 + 2]; -+ } -+ -+ free(buf); -+} -+ -+static void mag_read_flags(mi) -+ struct mag *mi; -+{ -+ mi->a = mag_malloc((size_t) mi->a_size, "mag_read_flags#1"); -+ mi->b = mag_malloc((size_t) mi->b_size, "mag_read_flags#2"); -+ -+ fseek(mi->fp, mi->a_off, SEEK_SET); -+ if(fread(mi->a, (size_t) mi->a_size, (size_t) 1, mi->fp) != 1) -+ mag_file_warning(mi, MAG_CORRUPT); -+ if(fread(mi->b, (size_t) mi->b_size, (size_t) 1, mi->fp) != 1) -+ mag_file_warning(mi, MAG_CORRUPT); -+} -+ -+static void mag_read_pixel_data(mi) -+ struct mag *mi; -+{ -+ mi->p = mag_malloc((size_t) mi->p_size, "mag_read_pixel_data"); -+ -+ fseek(mi->fp, mi->p_off, SEEK_SET); -+ if(fread(mi->p, (size_t) mi->p_size, (size_t) 1, mi->fp) != 1) -+ mag_file_warning(mi, MAG_CORRUPT); -+} -+ -+/* MAG expanding routine */ -+static void mag_expand_body(mi, pic0) -+ struct mag *mi; -+ byte **pic0; -+{ -+ int ai, bi, fi, pi; -+ int px, py, x, y; -+ byte *flag; -+ byte mask; -+ data16 *pixel0; -+ -+ flag = mag_malloc((size_t) mi->p_width / 2, "mag_expand_body#1"); -+ *pic0 = mag_malloc((size_t) mi->width * mi->height, "mag_expand_body#2"); // GRR POSSIBLE OVERFLOW / FIXME -+ pixel0 = mag_malloc((size_t) 2 * mi->p_width * 17, "mag_expand_body#3"); // GRR POSSIBLE OVERFLOW / FIXME -+ -+#define pixel(x, y) pixel0[(y) % 17 * mi->p_width + (x)] -+ -+ ai = bi = pi = 0; -+ mask = 0x80; -+ for(y = py = 0; py < mi->p_height; py++){ -+ for(fi = 0; fi < mi->p_width / 2; fi++){ -+ if(py == 0){ -+ if(mi->a[ai] & mask) -+ flag[fi] = mi->b[bi++]; -+ else -+ flag[fi] = 0; -+ }else{ -+ if(mi->a[ai] & mask) -+ flag[fi] ^= mi->b[bi++]; -+ } -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ ai++; -+ } -+ } -+ -+ for(px = fi = 0; fi < mi->p_width / 2; fi++){ -+ int f = H4(flag[fi]); -+ if(f == 0){ -+ pixel(px, py) = mi->p[pi] + mi->p[pi + 1] * 256; -+ px++; -+ pi+=2; -+ }else{ -+ int dx = points[f].dx, dy = points[f].dy; -+ pixel(px, py) = pixel(px - dx, py - dy); -+ px++; -+ } -+ -+ f = L4(flag[fi]); -+ if(f == 0){ -+ pixel(px, py) = mi->p[pi] + mi->p[pi + 1] * 256; -+ px++; -+ pi+=2; -+ }else{ -+ int dx = points[f].dx, dy = points[f].dy; -+ pixel(px, py) = pixel(px - dx, py - dy); -+ px++; -+ } -+ } -+ -+#define inside(x) ((unsigned int)(x) < mi->width) -+#define pic(x, y) (*pic0)[(y) * mi->width + (x)] -+ for(x = -mi->left_pad, px = 0; px < mi->p_width; px++){ -+ data16 p = pixel(px, py); -+ if(mi->m_256){ -+ if(inside(x)) -+ pic(x, y) = L8(p); -+ x++; -+ if(inside(x)) -+ pic(x, y) = H8(p); -+ x++; -+ }else{ -+ if(inside(x)) -+ pic(x, y) = H4(L8(p)); -+ x++; -+ if(inside(x)) -+ pic(x, y) = L4(L8(p)); -+ x++; -+ if(inside(x)) -+ pic(x, y) = H4(H8(p)); -+ x++; -+ if(inside(x)) -+ pic(x, y) = L4(H8(p)); -+ x++; -+ } -+ } -+ y++; -+ } -+#undef pic -+#undef inside -+#undef pixel -+ -+ free(flag); -+ free(pixel0); -+} -+ -+ -+/* The main routine to write a MAG file. */ -+int WriteMAG(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle, -+ comment) -+ FILE *fp; -+ byte *pic; -+ int ptype, w, h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+ char *comment; -+{ -+ byte rtemp[256], gtemp[256], btemp[256]; -+ struct mag mag; -+ int e; -+ -+ if(DEBUG) fputs("WriteMag\n", stderr); -+ -+ mag_init_info(&mag); -+ mag.fp = fp; -+ -+ if(ptype == PIC24){ -+ if(!(pic = Conv24to8(pic, w, h, 256, rtemp, gtemp, btemp))) -+ mag_memory_error("Conv24to8", "WriteMAG"); -+ rmap = rtemp; -+ gmap = gtemp; -+ bmap = btemp; -+ numcols = 256; -+ mag.m_256 = 1; -+ }else{ -+ if(numcols > 16) -+ mag.m_256 = 1; -+ } -+ -+ if((e = setjmp(mag.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ mag_cleanup_mag_info(&mag, 1); -+ return -1; -+ } -+ -+ mag.x2 = w - 1; -+ mag.y2 = h - 1; -+ mag.right_pad = 07 - (mag.x2 & 07); -+ mag.p_width = (w + mag.right_pad) / (mag.m_256 ? 2 : 4); -+ mag.p_height = h; -+ mag.width = w; -+ mag.height = h; -+ mag.a_size = (mag.p_width * mag.p_height + 15) / 16; /* x/2/8 */ // GRR POSSIBLE OVERFLOW / FIXME -+ if(mag.a_size % 2) -+ mag.a_size++; -+ -+ mag_compress_data(&mag, pic); -+ mag_write_check_data(&mag); -+ mag_write_comment(&mag, comment); -+ -+ mag.h_off = ftell(mag.fp); -+ -+ mag_write_palette(&mag, numcols, rmap, gmap, bmap, -+ colorstyle == F_GREYSCALE); -+ mag_write_flags(&mag); -+ mag_write_pixel_data(&mag); -+ mag_write_header(&mag); -+ -+ mag_cleanup_mag_info(&mag, 1); -+ return 0; -+} -+ -+/* MAG compressing routine */ -+static void mag_compress_data(mi, pic0) -+ struct mag *mi; -+ byte *pic0; -+{ -+ int ai, bi, pi, i; -+ int bmax, pmax; -+ byte mask; -+ byte *flag0; -+ data16 *pixel0; -+ int px, py, x, y; -+ -+ pixel0 = mag_malloc((size_t) 2 * mi->p_width * mi->p_height, // GRR POSSIBLE OVERFLOW / FIXME -+ "mag_compress_data#1"); -+ flag0 = mag_malloc((size_t) mi->p_width * mi->p_height, // GRR POSSIBLE OVERFLOW / FIXME -+ "mag_compress_data#2"); -+ -+#define pic(x, y) pic0[(y) * mi->width + (x)] -+ /* convert dots to pixels */ -+ i = 0; -+ for(y = py = 0; py < mi->p_height; py++){ -+ for(x = px = 0; px < mi->p_width; px++){ -+ data16 p = 0; -+ if(mi->m_256){ -+ if(x < mi->width) -+ p += pic(x, y); -+ x++; -+ if(x < mi->width) -+ p += pic(x, y) * 256; -+ x++; -+ }else{ -+ if(x < mi->width) -+ p += pic(x, y) * 16; -+ x++; -+ if(x < mi->width) -+ p += pic(x, y); -+ x++; -+ if(x < mi->width) -+ p += pic(x, y) * 4096; -+ x++; -+ if(x < mi->width) -+ p += pic(x, y) * 256; -+ x++; -+ } -+ pixel0[i++] = p; -+ } -+ y++; -+ } -+#undef pic -+ -+#define pixel(x, y) pixel0[(y) * mi->p_width + (x)] -+#define flag(x, y) flag0[(y) * mi->p_width + (x)] -+ /* get flags */ -+ pmax = pi = 0; -+ for(py = 0; py < mi->p_height; py++){ -+ for(px = 0; px < mi->p_width; px++){ -+ int t; -+ for(t = 0; t < 15; t++){ -+ int dx = points[try[t]].dx, dy = points[try[t]].dy; -+ if(dx <= px && dy <= py){ -+ if(pixel(px - dx, py - dy) == pixel(px, py)) -+ break; -+ } -+ } -+ if(t < 15){ -+ flag(px, py) = try[t]; -+ }else{ -+ flag(px, py) = 0; -+ if(pmax <= pi + 1){ -+ pmax += 128; -+ mi->p = mag_realloc(mi->p, (size_t) pmax, -+ "mag_compress_data#3"); -+ } -+ mi->p[pi++] = L8(pixel(px, py)); -+ mi->p[pi++] = H8(pixel(px, py)); -+ } -+ } -+ } -+#undef flag -+#undef pixel -+ -+ /* pack 2 flags into 1 byte */ -+ for(i = 0; i < mi->p_width / 2 * mi->p_height; i++) -+ flag0[i] = flag0[i * 2] * 16 + flag0[i * 2 + 1]; -+ -+#define flag(x, y) flag0[(y) * mi->p_width / 2 + (x)] -+ for(py = mi->p_height - 1; py >= 1; py--){ -+ for(px = 0; px < mi->p_width / 2; px++) -+ flag(px, py) ^= flag(px, py - 1); -+ } -+#undef flag -+ -+ mask = 0x80; -+ ai = bi = bmax = 0; -+ mi->a = mag_malloc((size_t) mi->a_size, "mag_compress_data#4"); // GRR POSSIBLE OVERFLOW / FIXME -+ for(i = 0; i < mi->p_width / 2 * mi->p_height; i++){ -+ if(flag0[i] == 0){ -+ mi->a[ai] &= ~mask; -+ }else{ -+ if(bmax == bi){ -+ bmax += 128; -+ mi->b = mag_realloc(mi->b, (size_t) bmax, -+ "mag_compress_data#4"); -+ } -+ mi->b[bi++] = flag0[i]; -+ mi->a[ai] |= mask; -+ } -+ -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ ai++; -+ } -+ } -+ -+ if(bi % 2) -+ bi++; -+ mi->b_size = bi; -+ -+ mi->p_size = pi; -+ -+ free(pixel0); -+ free(flag0); -+} -+ -+static void mag_write_check_data(mi) -+ struct mag *mi; -+{ -+ if(fwrite(mag_id, (size_t) 8, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_WRITE); -+} -+ -+static void mag_write_comment(mi, comment) -+ struct mag *mi; -+ char *comment; -+{ -+ char *p; -+ int i; -+ -+ if(fputs("XV ", mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ -+ if((p = (char *) getenv("USER")) == NULL) -+ p = "????????"; -+ for(i = 5; i < 24; i++){ -+ if(*p == '\0') -+ break; -+ if(fputc(*p++, mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ for( ; i < 24; i++){ -+ if(fputc(' ', mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ -+ if(comment){ -+ int l = strlen(comment); -+ if(l > 0){ -+ int i; -+ for(i = 0; i < l; i++){ -+ if(comment[i] == 0x1a) -+ comment[i] = ' '; -+ } -+ if(fwrite(comment, (size_t) l, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ } -+ -+ if(fputc(0x1a, mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+} -+ -+static void mag_write_palette(mi, num, r, g, b, grey) -+ struct mag *mi; -+ int num; -+ byte *r, *g, *b; -+ int grey; -+{ -+ int i, left; -+ char buf[3]; -+ -+ fseek(mi->fp, 32L, SEEK_CUR); /* skip header area */ -+ for(i = 0; i < num; i++){ -+ buf[0] = *g++; -+ buf[1] = *r++; -+ buf[2] = *b++; -+ if(grey) -+ buf[0] = buf[1] = buf[2] = MONO(buf[1], buf[0], buf[2]); -+ if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ if(num < 16){ -+ left = 16 - num; -+ }else if(num == 16){ -+ left = 0; -+ }else if(num < 256){ -+ left = 256 - num; -+ }else if(num == 256){ -+ left = 0; -+ }else -+ left = 0; /* shouldn't happen */ -+ -+ if(left > 0){ -+ for(i = 0; i < left; i++){ -+ if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ } -+} -+ -+static void mag_write_flags(mi) -+ struct mag *mi; -+{ -+ int i; -+ -+ mi->a_off = ftell(mi->fp); -+ for(i = 0; i < mi->a_size; i++){ -+ if(fputc(mi->a[i], mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ } -+ -+ mi->b_off = ftell(mi->fp); -+ for(i = 0; i < mi->b_size; i++){ -+ if(fputc(mi->b[i], mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ } -+} -+ -+static void mag_write_pixel_data(mi) -+ struct mag *mi; -+{ -+ int i; -+ -+ mi->p_off = ftell(mi->fp); -+ for(i = 0; i < mi->p_size; i++){ -+ if(fputc(mi->p[i], mi->fp) == EOF) -+ mag_file_error(mi, MAG_WRITE); -+ } -+} -+ -+static void mag_write_header(mi) -+ struct mag *mi; -+{ -+ byte buf[32]; -+ -+ if(DEBUG) mag_show_struct(mi); -+ -+ mi->a_off -= mi->h_off; -+ mi->b_off -= mi->h_off; -+ mi->p_off -= mi->h_off; -+ -+ buf[ 0] = buf[1] = buf[2] = 0; -+ buf[ 3] = (mi->m_256 ? 0x80 : 0); -+ buf[ 4] = buf[5] = 0; -+ buf[ 6] = buf[7] = 0; -+ buf[ 8] = L8(mi->x2); -+ buf[ 9] = H8(mi->x2); -+ buf[10] = L8(mi->y2); -+ buf[11] = H8(mi->y2); -+ mag_set_double_word(mi->a_off, &buf[12]); -+ mag_set_double_word(mi->b_off, &buf[16]); -+ mag_set_double_word(mi->b_size, &buf[20]); -+ mag_set_double_word(mi->p_off, &buf[24]); -+ mag_set_double_word(mi->p_size, &buf[28]); -+ -+ fseek(mi->fp, mi->h_off, SEEK_SET); -+ if(fwrite(buf, (size_t) 32, (size_t) 1, mi->fp) != 1) -+ mag_file_error(mi, MAG_WRITE); -+} -+ -+static void mag_set_double_word(n, p) -+ long n; -+ byte *p; -+{ -+ p[0] = n % 256; /* ugly...anything wrong with shift/mask operations? */ -+ p[1] = n / 256 % 256; /* (n >> 8) & 0xff */ -+ p[2] = n / 256 / 256 % 256; /* (n >> 16) & 0xff */ -+ p[3] = n / 256 / 256 / 256 % 256; /* (n >> 24) & 0xff */ -+} -+ -+/* -+ * The routines to initialize or clean up. -+ * mag_init_info: -+ * initializes a mag structure. -+ * mag_cleanup_mag_info: -+ * cleans up a mag structure. -+ * mag_cleanup_pinfo: -+ * cleans up a PICINFO structure. -+ */ -+static void mag_init_info(mi) -+ struct mag *mi; -+{ -+ mi->fp = NULL; -+ mi->fsize = 0; -+ mi->m_256 = mi->m_dig = mi->m_8 = mi->m_200 = 0; -+ mi->x1 = mi->y1 = mi->x2 = mi->y2 = 0; -+ mi->left_pad = mi->right_pad = 0; -+ mi->p_width = mi->p_height = mi->width = mi->height = 0; -+ mi->h_off = mi->p_off = mi->p_size = 0; -+ mi->a_off = mi->a_size = mi->b_off = mi->b_size = 0; -+ mi->a = NULL; -+ mi->b = NULL; -+ mi->p = NULL; -+} -+ -+static void mag_cleanup_mag_info(mi, writing) -+ struct mag *mi; -+ int writing; -+{ -+ if(mi->fp && !writing) -+ fclose(mi->fp); -+ if(mi->a) -+ free(mi->a); -+ if(mi->b) -+ free(mi->b); -+ if(mi->p) -+ free(mi->p); -+} -+ -+static void mag_cleanup_pinfo(pinfo) -+ PICINFO *pinfo; -+{ -+ if(pinfo->comment){ -+ free(pinfo->comment); -+ pinfo->comment = NULL; -+ } -+ if(pinfo->pic){ -+ free(pinfo->pic); -+ pinfo->pic = NULL; -+ } -+} -+ -+/* -+ * Error handler. -+ * mag_memory_error: -+ * shows an error message, and terminates. -+ * mag_error: -+ * shows an non-file error message, and jumps to the entry for errors. -+ * mag_file_error: -+ * shows an file error message, and jumps to the entry for errors. -+ * mag_file_warning: -+ * shows an file warning message. -+ */ -+static void mag_memory_error(scm, fn) -+ char *scm, *fn; -+{ -+ char buf[128]; -+ sprintf(buf, "%s: can't allocate memory. (%s)", scm, fn); -+ FatalError(buf); -+} -+ -+static void mag_error(mi, mn) -+ struct mag *mi; -+ int mn; -+{ -+ SetISTR(ISTR_WARNING, "%s", mag_msgs[mn]); -+ longjmp(mi->jmp, 1); -+} -+ -+static void mag_file_error(mi, mn) -+ struct mag *mi; -+ int mn; -+{ -+ if(feof(mi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", mag_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", mag_msgs[mn], ERRSTR(errno)); -+ longjmp(mi->jmp, 1); -+} -+ -+static void mag_file_warning(mi, mn) -+ struct mag *mi; -+ int mn; -+{ -+ if(feof(mi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", mag_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", mag_msgs[mn], ERRSTR(errno)); -+} -+ -+static void mag_show_struct (mi) -+ struct mag *mi; -+{ -+ fprintf(stderr, " 256 colors: %s\n", mi->m_256 ? "true" : "false"); -+ fprintf(stderr, " 8 colors: %s\n", mi->m_8 ? "true" : "false"); -+ fprintf(stderr, " digital colors: %s\n", mi->m_dig ? "true" : "false"); -+ fprintf(stderr, " aspect ratio: %f\n", mi->m_200 ? 0.5 : 1.0); -+ fprintf(stderr, " image size: %dx%d\n", mi->width, mi->height); -+ fprintf(stderr, " left pad: %d\n", mi->left_pad); -+ fprintf(stderr, " right pad: %d\n", mi->right_pad); -+ fprintf(stderr, " h_off: %ld\n", mi->h_off); -+ fprintf(stderr, " A: off:%ld, size:%ld\n", mi->a_off, mi->a_size); -+ fprintf(stderr, " B: off:%ld, size:%ld\n", mi->b_off, mi->b_size); -+ fprintf(stderr, " P: off:%ld, size:%ld\n", mi->p_off, mi->p_size); -+} -+ -+/* Memory related routines. */ -+static void *mag_malloc(n, fn) -+ size_t n; -+ char *fn; -+{ -+ void *r = (void *) malloc(n); -+ if(r == NULL) -+ mag_memory_error("malloc", fn); -+ return r; -+} -+ -+static void *mag_realloc(p, n, fn) -+ void *p; -+ size_t n; -+ char *fn; -+{ -+ void *r = (p == NULL) ? (void *) malloc(n) : (void *) realloc(p, n); -+ if(r == NULL) -+ mag_memory_error("realloc", fn); -+ return r; -+} -+#endif /* HAVE_MAG */ -diff -ruN xv-3.10a-bugfixes/xvmaki.c xv-3.10a-enhancements/xvmaki.c ---- xv-3.10a-bugfixes/xvmaki.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvmaki.c 2005-04-17 22:57:01.000000000 -0700 -@@ -0,0 +1,794 @@ -+/* -+ * xvmaki.c - load routine for `MAKI' format pictures. -+ * -+ * The `MAKI' format was used by some Japanese personal computer users. -+ */ -+ -+#include "xv.h" -+#include <setjmp.h> -+ -+#ifdef HAVE_MAKI -+ -+typedef unsigned short data16; -+typedef unsigned int data32; -+ -+struct maki_info { -+ jmp_buf jmp; -+ FILE *fp; -+ long fsize; -+ int x0, y0, x1, y1; -+ int width, height; -+ float aspect; -+ long fb_size; -+ long pa_size, pb_size; -+ int m_maki01b, m_200, m_dig8; -+ data16 ext_flag; -+ byte *fa, *fb, *pa, *pb; -+ byte *vs; -+ int numcols; -+ byte *forma, *formb; -+}; -+ -+ -+static void maki_open_file PARM((struct maki_info*, char*)); -+static void maki_check_id PARM((struct maki_info*)); -+static void maki_skip_comment PARM((struct maki_info*)); -+static void maki_read_header PARM((struct maki_info*)); -+static void maki_read_palette PARM((struct maki_info*, -+ byte*, byte*, byte*)); -+static void maki_read_flags PARM((struct maki_info*)); -+static void maki_read_pixel_data PARM((struct maki_info*)); -+static void maki_expand_virtual_screen PARM((struct maki_info*)); -+static void maki_expand_pixel_data PARM((struct maki_info*, byte**)); -+static void maki_init_info PARM((struct maki_info*)); -+ -+static void maki_make_pixel_data PARM((struct maki_info*, byte*)); -+static void maki_make_virtual_screen PARM((struct maki_info*)); -+static void maki_make_flags PARM((struct maki_info*)); -+static void maki_write_check_id PARM((struct maki_info*)); -+static void maki_write_comment PARM((struct maki_info*)); -+static void maki_write_header PARM((struct maki_info*)); -+static void maki_write_palette PARM((struct maki_info*, -+ byte*, byte*, byte*, int)); -+static void maki_write_flags PARM((struct maki_info*)); -+static void maki_write_pixel_data PARM((struct maki_info*)); -+ -+static void maki_cleanup_maki_info PARM((struct maki_info*, int)); -+static void maki_cleanup_pinfo PARM((PICINFO*)); -+static void maki_memory_error PARM((char*, char*)); -+static void maki_error PARM((struct maki_info*, int)); -+static void maki_file_error PARM((struct maki_info*, int)); -+static void maki_file_warning PARM((struct maki_info*, int)); -+static void maki_show_maki_info PARM((struct maki_info*)); -+static void *maki_malloc PARM((size_t, char*)); -+static void *maki_realloc PARM((void *, size_t, char*)); -+ -+static char maki_id_a[] = "MAKI01A "; -+static char maki_id_b[] = "MAKI01B "; -+ -+static char *maki_msgs[] = { -+ NULL, -+#define MAKI_OPEN 1 -+ "can't open file.", -+#define MAKI_CORRUPT 2 -+ "file corrupted.", -+#define MAKI_FORMAT 3 -+ "not MAKI format.", -+#define MAKI_BAD_DATA 4 -+ "bad data.", -+#define MAKI_COMMENT 5 -+ "no '^Z' after comment.", -+#define MAKI_SIZE 6 -+ "bad size.", -+#define MAKI_WRITE 7 -+ "write failed.", -+}; -+ -+#define H4(b) ((b) >> 4 & 0xf) -+#define L4(b) ((b) & 0xf) -+#define error(msg_num) longjmp(mi->jmp, msg_num) -+ -+int LoadMAKI(fname, pinfo) -+ char *fname; -+ PICINFO *pinfo; -+{ -+ struct maki_info maki; -+ int e; -+ -+ if(DEBUG) fputs("LoadMAKI:\n", stderr); -+ -+ pinfo->comment = NULL; -+ maki_init_info(&maki); -+ if((e = setjmp(maki.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ maki_cleanup_maki_info(&maki, 0); -+ maki_cleanup_pinfo(pinfo); -+ return 0; -+ } -+ -+ maki_open_file(&maki, fname); -+ maki_check_id(&maki); -+ maki_skip_comment(&maki); -+ maki_read_header(&maki); -+ maki_read_palette(&maki, pinfo->r, pinfo->g, pinfo->b); -+ maki_read_flags(&maki); -+ maki_read_pixel_data(&maki); -+ maki_expand_virtual_screen(&maki); -+ maki_expand_pixel_data(&maki, &pinfo->pic); -+ -+ pinfo->w = pinfo->normw = maki.width; -+ pinfo->h = pinfo->normh = maki.height; -+ pinfo->type = PIC8; -+ pinfo->frmType = F_MAKI; -+ pinfo->colType = F_FULLCOLOR; -+ sprintf(pinfo->fullInfo, "MAKI, 16 colors (%ld bytes)", maki.fsize); -+ sprintf(pinfo->shrtInfo, "%dx%d MAKI", maki.width, maki.height); -+ normaspect = maki.aspect; -+ -+ maki_cleanup_maki_info(&maki, 0); -+ return 1; -+} -+ -+static void maki_open_file(mi, fname) -+ struct maki_info *mi; -+ char *fname; -+{ -+ if((mi->fp = fopen(fname, "rb")) == NULL) -+ maki_file_error(mi, MAKI_OPEN); -+ fseek(mi->fp, (size_t) 0, SEEK_END); -+ mi->fsize = ftell(mi->fp); -+ fseek(mi->fp, (size_t) 0, SEEK_SET); -+} -+ -+static void maki_check_id(mi) -+ struct maki_info *mi; -+{ -+ char buf[8]; -+ if(fread(buf, (size_t) 8, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_CORRUPT); -+ if(strncmp(buf, maki_id_a, (size_t) 8) != 0 && -+ strncmp(buf, maki_id_b, (size_t) 8) != 0) -+ maki_error(mi, MAKI_FORMAT); -+ mi->m_maki01b = (buf[6] == 'B'); -+} -+ -+static void maki_skip_comment(mi) -+ struct maki_info *mi; -+{ -+ int i; -+ int c; -+ -+ for(i = 0; i < 24; i++){ -+ if((c = fgetc(mi->fp)) == EOF) -+ maki_file_error(mi, MAKI_CORRUPT); -+ if(c == '\032') /* ^Z, 0x1a */ -+ break; -+ } -+ if(c != '\032') -+ maki_file_error(mi, MAKI_COMMENT); -+ -+ fseek(mi->fp, 32L, SEEK_SET); -+} -+ -+static void maki_read_header(mi) -+ struct maki_info *mi; -+{ -+ byte buf[16]; -+ -+ if(fread(buf, (size_t) 16, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_CORRUPT); -+ -+ mi->fb_size = (long)buf[ 0] << 8 | (long)buf[ 1]; -+ mi->pa_size = (long)buf[ 2] << 8 | (long)buf[ 3]; -+ mi->pb_size = (long)buf[ 4] << 8 | (long)buf[ 5]; -+ mi->ext_flag = (long)buf[ 6] << 8 | (long)buf[ 7]; -+ mi->x0 = (long)buf[ 8] << 8 | (long)buf[ 9]; -+ mi->y0 = (long)buf[10] << 8 | (long)buf[11]; -+ mi->x1 = (long)buf[12] << 8 | (long)buf[13]; -+ mi->y1 = (long)buf[14] << 8 | (long)buf[15]; -+ -+ mi->width = mi->x1-- - mi->x0; -+ mi->height = mi->y1-- - mi->y0; -+ mi->m_200 = mi->ext_flag & 1; -+ mi->m_dig8 = mi->ext_flag & 2; -+ mi->aspect = mi->m_200 ? 0.5 : 1.0; -+ -+ if(DEBUG) maki_show_maki_info(mi); -+} -+ -+static void maki_read_palette(mi, r, g, b) -+ struct maki_info *mi; -+ byte *r, *g, *b; -+{ -+ byte buf[48], *p; -+ -+ if(fread(buf, (size_t) 48, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_CORRUPT); -+ -+ for(p = buf; p < &buf[48]; ){ -+ *g++ = *p++; -+ *r++ = *p++; -+ *b++ = *p++; -+ } -+} -+ -+static void maki_read_flags(mi) -+ struct maki_info *mi; -+{ -+ mi->fa = maki_malloc((size_t) 1000 , "maki_read_flags#1"); -+ mi->fb = maki_malloc((size_t) mi->fb_size, "maki_read_flags#2"); -+ -+ if(fread(mi->fa, (size_t) 1000, (size_t) 1, mi->fp) != 1) -+ maki_file_warning(mi, MAKI_CORRUPT); -+ if(fread(mi->fb, (size_t) mi->fb_size, (size_t) 1, mi->fp) != 1) -+ maki_file_warning(mi, MAKI_CORRUPT); -+} -+ -+static void maki_read_pixel_data(mi) -+ struct maki_info *mi; -+{ -+ mi->pa = maki_malloc((size_t) mi->pa_size, "maki_read_pixel_data#1"); -+ mi->pb = maki_malloc((size_t) mi->pb_size, "maki_read_pixel_data#2"); -+ -+ if(fread(mi->pa, (size_t) mi->pa_size, (size_t) 1, mi->fp) != 1) -+ maki_file_warning(mi, MAKI_CORRUPT); -+ if(fread(mi->pb, (size_t) mi->pb_size, (size_t) 1, mi->fp) != 1) -+ maki_file_warning(mi, MAKI_CORRUPT); -+} -+ -+static void maki_expand_virtual_screen(mi) -+ struct maki_info *mi; -+{ -+ int x, y, fai, fbi; -+ int bpl = mi->width / 2 / 8; /* bytes per line */ -+ byte mask; -+ mi->vs = maki_malloc((size_t) bpl * mi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "maki_expand_virtual_screen"); -+ -+ fai = fbi = 0; -+ mask = 0x80; -+ for(y = 0; y < mi->height; y += 4){ -+ for(x = 0; x < mi->width / 2; x += 4){ -+ if(mi->fa[fai] & mask){ -+ byte bh, bl; -+ bh = mi->fb[fbi++]; -+ bl = mi->fb[fbi++]; -+ if(x % 8 == 0){ -+ mi->vs[ y * bpl + x / 8] = H4(bh) << 4; -+ mi->vs[(y + 1) * bpl + x / 8] = L4(bh) << 4; -+ mi->vs[(y + 2) * bpl + x / 8] = H4(bl) << 4; -+ mi->vs[(y + 3) * bpl + x / 8] = L4(bl) << 4; -+ }else{ -+ mi->vs[ y * bpl + x / 8] |= H4(bh); -+ mi->vs[(y + 1) * bpl + x / 8] |= L4(bh); -+ mi->vs[(y + 2) * bpl + x / 8] |= H4(bl); -+ mi->vs[(y + 3) * bpl + x / 8] |= L4(bl); -+ } -+ }else{ -+ if(x % 8 == 0){ -+ mi->vs[ y * bpl + x / 8] = 0; -+ mi->vs[(y + 1) * bpl + x / 8] = 0; -+ mi->vs[(y + 2) * bpl + x / 8] = 0; -+ mi->vs[(y + 3) * bpl + x / 8] = 0; -+ }else{ -+/* mi->vs[ y * bpl + x / 8] |= 0; -+ mi->vs[(y + 1) * bpl + x / 8] |= 0; -+ mi->vs[(y + 2) * bpl + x / 8] |= 0; -+ mi->vs[(y + 3) * bpl + x / 8] |= 0; */ -+ } -+ } -+ -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ fai++; -+ } -+ } -+ } -+} -+ -+static void maki_expand_pixel_data(mi, pic) -+ struct maki_info *mi; -+ byte **pic; -+{ -+ int x, y; -+ int vsi, pi, max_pi; -+ byte *p; -+ byte mask; -+ int gap; -+ *pic = maki_malloc((size_t) mi->width * mi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "maki_expand_pixel_data"); -+ -+ vsi = pi = 0; -+ p = mi->pa; -+ max_pi = mi->pa_size - 1; -+ mask = 0x80; -+ for(y = 0; y < mi->height; y++){ -+ for(x = 0; x < mi->width; x += 2){ -+ if(mi->vs[vsi] & mask){ -+ if(pi > max_pi){ -+ if(p == mi->pb) -+ maki_error(mi, MAKI_BAD_DATA); -+ pi = 0; -+ p = mi->pb; -+ max_pi = mi->pb_size - 1; -+ } -+ (*pic)[y * mi->width + x ] = H4(p[pi]); -+ (*pic)[y * mi->width + x + 1] = L4(p[pi]); -+ pi++; -+ }else{ -+ (*pic)[y * mi->width + x ] = 0; -+ (*pic)[y * mi->width + x + 1] = 0; -+ } -+ -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ vsi++; -+ } -+ } -+ } -+ -+ gap = mi->m_maki01b ? 4 : 2; -+ -+ for(y = gap; y < mi->height; y++){ -+ for(x = 0; x < mi->width; x++) -+ (*pic)[y * mi->width + x] ^= (*pic)[(y - gap) * mi->width + x]; -+ } -+} -+ -+ -+int WriteMAKI(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle) -+ FILE *fp; -+ byte *pic; -+ int ptype, w, h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+{ -+ byte rtemp[256], gtemp[256], btemp[256]; -+ struct maki_info maki, *mi = &maki; -+ int e; -+ -+ if(DEBUG) fputs("WriteMAKI:\n", stderr); -+ -+ maki_init_info(&maki); -+ if((e = setjmp(maki.jmp)) != 0){ -+ /* An error occurs */ -+ maki_cleanup_maki_info(&maki, 1); -+ return -1; -+ } -+ -+ if(w != 640 || h != 400) { -+ char str[512]; -+ sprintf(str,"MAKI: %s Should be 640x400", maki_msgs[MAKI_SIZE]); -+ ErrPopUp(str, "\nBummer!"); -+ maki_error(mi, MAKI_SIZE); -+ } -+ -+ maki.fp = fp; -+ maki.width = w; -+ maki.height = h; -+ maki.x1 = w - 1; -+ maki.y1 = h - 1; -+ -+ if(ptype == PIC24){ -+ if(!(pic = Conv24to8(pic, w, h, 16, rtemp, gtemp, btemp))) -+ maki_memory_error("Conv24to8#1", "WriteMAKI"); -+ rmap = rtemp; -+ gmap = gtemp; -+ bmap = btemp; -+ }else if(numcols > 16){ -+ if(!(pic = Conv8to24(pic, w, h, rmap, gmap, bmap))) -+ maki_memory_error("Conv8to24", "WriteMAKI"); -+ if(!(pic = Conv24to8(pic, w, h, 16, rtemp, gtemp, btemp))) -+ maki_memory_error("Conv24to8#2", "WriteMAKI"); -+ rmap = rtemp; -+ gmap = gtemp; -+ bmap = btemp; -+ }else -+ maki.numcols = numcols; -+ -+ maki_make_pixel_data(&maki, pic); -+ maki_make_virtual_screen(&maki); -+ maki_make_flags(&maki); -+ maki_write_check_id(&maki); -+ maki_write_comment(&maki); -+ maki_write_header(&maki); -+ maki_write_palette(&maki, rmap, gmap, bmap, colorstyle == F_GREYSCALE); -+ maki_write_flags(&maki); -+ maki_write_pixel_data(&maki); -+ -+ maki_cleanup_maki_info(&maki, 1); -+ return 0; -+} -+ -+static void maki_make_pixel_data(mi, pic) -+ struct maki_info *mi; -+ byte *pic; -+{ -+ int x, y, i; -+ int nza, nzb; -+ -+ mi->forma = maki_malloc((size_t) mi->width / 2 * mi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "maki_make_pixel_data#1"); -+ mi->formb = maki_malloc((size_t) mi->width / 2 * mi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "maki_make_pixel_data#2"); -+ -+ for(y = 0; y < mi->height; y++){ -+ for(x = 0; x < mi->width; x += 2){ -+ byte b; -+ b = pic[y * mi->width + x] << 4 | pic[y * mi->width + x + 1]; -+ mi->forma[y * mi->width / 2 + x / 2] = b; -+ mi->formb[y * mi->width / 2 + x / 2] = b; -+ } -+ } -+ -+ for(y = mi->height - 1; y >= 2; y--){ -+ for(x = 0; x < mi->width / 2; x++){ -+ mi->forma[y * mi->width / 2 + x] ^= -+ mi->forma[(y - 2) * mi->width / 2 + x]; -+ } -+ } -+ -+ for(y = mi->height - 1; y >= 4; y--){ -+ for(x = 0; x < mi->width / 2; x++){ -+ mi->formb[y * mi->width / 2 + x] ^= -+ mi->formb[(y - 4) * mi->width / 2 + x]; -+ } -+ } -+ -+ nza = nzb = 0; -+ for(i = 0; i < mi->width / 2 * mi->height; i++){ -+ if(mi->forma[i] != 0) -+ nza++; -+ if(mi->formb[i] != 0) -+ nzb++; -+ } -+ if(nza > nzb){ -+ mi->m_maki01b = 1; -+ free(mi->forma); -+ mi->forma = NULL; -+ }else{ -+ mi->m_maki01b = 0; -+ free(mi->formb); -+ mi->formb = NULL; -+ } -+} -+ -+static void maki_make_virtual_screen(mi) -+ struct maki_info *mi; -+{ -+ int bpl = mi->width / 2 / 8; -+ int vsi, pai, pbi, max_pai, max_pbi; -+ byte mask; -+ byte *pixels; -+ int x, y; -+ -+ mi->vs = maki_malloc((size_t) bpl * mi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "maki_make_virtual_screen#1"); -+ -+ if(mi->m_maki01b) -+ pixels = mi->formb; -+ else -+ pixels = mi->forma; -+ -+ vsi = pai = pbi = 0; -+ max_pai = max_pbi = -1; -+ mask = 0x80; -+ for(y = 0; y < mi->height; y++){ -+ for(x = 0; x < mi->width / 2; x++){ -+ if(pixels[y * mi->width / 2 + x] == 0){ -+ mi->vs[vsi] &= ~mask; -+ }else{ -+ mi->vs[vsi] |= mask; -+ if(y < 200){ -+ if(pai > max_pai){ -+ max_pai += 1024; -+ mi->pa = maki_realloc(mi->pa, (size_t) max_pai + 1, -+ "maki_make_virtual_screen#2"); -+ } -+ mi->pa[pai++] = pixels[y * mi->width / 2 + x]; -+ }else{ -+ if(pbi > max_pbi){ -+ max_pbi += 1024; -+ mi->pb = maki_realloc(mi->pb, (size_t) max_pbi + 2, -+ "maki_make_virtual_screen#3"); -+ } -+ mi->pb[pbi++] = pixels[y * mi->width / 2 + x]; -+ } -+ } -+ -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ vsi++; -+ } -+ } -+ } -+ -+ mi->pa_size = pai; -+ mi->pb_size = pbi; -+} -+ -+static void maki_make_flags(mi) -+ struct maki_info *mi; -+{ -+ int bpl = mi->width / 2 / 8; -+ int fbi, max_fbi; -+ int fai; -+ int x, y; -+ byte mask; -+ -+ mi->fa = maki_malloc((size_t) bpl * mi->height, "maki_make_flags#1"); // GRR POSSIBLE OVERFLOW / FIXME -+ -+ fbi = fai = 0; -+ max_fbi = -1; -+ mask = 0x80; -+ for(y = 0; y < mi->height; y += 4){ -+ for(x = 0; x < mi->width / 2; x += 4){ -+ if(x % 8 == 0){ -+ if(H4(mi->vs[ y * bpl + x / 8]) == 0 && -+ H4(mi->vs[(y + 1) * bpl + x / 8]) == 0 && -+ H4(mi->vs[(y + 2) * bpl + x / 8]) == 0 && -+ H4(mi->vs[(y + 3) * bpl + x / 8]) == 0){ -+ mi->fa[fai] &= ~mask; -+ }else{ -+ mi->fa[fai] |= mask; -+ if(fbi + 1 > max_fbi){ -+ max_fbi += 1024; -+ mi->fb = maki_realloc(mi->fb, (size_t) max_fbi + 1, -+ "maki_make_flags#2"); -+ } -+ mi->fb[fbi++] = H4(mi->vs[ y * bpl + x / 8]) << 4 -+ | H4(mi->vs[(y + 1) * bpl + x / 8]); -+ mi->fb[fbi++] = H4(mi->vs[(y + 2) * bpl + x / 8]) << 4 -+ | H4(mi->vs[(y + 3) * bpl + x / 8]); -+ } -+ }else{ -+ if(L4(mi->vs[ y * bpl + x / 8]) == 0 && -+ L4(mi->vs[(y + 1) * bpl + x / 8]) == 0 && -+ L4(mi->vs[(y + 2) * bpl + x / 8]) == 0 && -+ L4(mi->vs[(y + 3) * bpl + x / 8]) == 0){ -+ mi->fa[fai] &= ~mask; -+ }else{ -+ mi->fa[fai] |= mask; -+ if(fbi + 1 > max_fbi){ -+ max_fbi += 1024; -+ mi->fb = maki_realloc(mi->fb, (size_t) max_fbi + 1, -+ "maki_make_flags#3"); -+ } -+ mi->fb[fbi++] = L4(mi->vs[ y * bpl + x / 8]) << 4 -+ | L4(mi->vs[(y + 1) * bpl + x / 8]); -+ mi->fb[fbi++] = L4(mi->vs[(y + 2) * bpl + x / 8]) << 4 -+ | L4(mi->vs[(y + 3) * bpl + x / 8]); -+ } -+ } -+ -+ if((mask >>= 1) == 0){ -+ mask = 0x80; -+ fai++; -+ } -+ } -+ } -+ -+ mi->fb_size = fbi; -+} -+ -+static void maki_write_check_id(mi) -+ struct maki_info *mi; -+{ -+ char *id = mi->m_maki01b ? maki_id_b : maki_id_a; -+ if(fwrite(id, (size_t) 8, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+} -+ -+static void maki_write_comment(mi) -+ struct maki_info *mi; -+{ -+ char buf[24]; -+ char *p; -+ int i = 0; -+ -+ strcpy(buf, "XV "); -+ -+ if((p = (char *) getenv("USER")) == NULL) -+ p = "????????"; -+ for(i = 5; i < 23; i++){ -+ if(*p == '\0') -+ break; -+ buf[i] = *p++; -+ } -+ for( ; i < 23; i++) -+ buf[i] = ' '; -+ -+ buf[i] = '\032'; /* ^Z, 0x1a */ -+ -+ if(fwrite(buf, (size_t) 24, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+} -+ -+static void maki_write_header(mi) -+ struct maki_info *mi; -+{ -+ byte buf[16]; -+ -+ if(DEBUG) maki_show_maki_info(mi); -+ -+#define set_word(i, v) {buf[i]=(v)>>8&0xff;buf[i+1]=(v)&0xff;} -+ set_word(0, mi->fb_size); -+ set_word(2, mi->pa_size); -+ set_word(4, mi->pb_size); -+ set_word(6, mi->ext_flag); -+ set_word(8, mi->x0); -+ set_word(10, mi->y0); -+ set_word(12, mi->x1 + 1); -+ set_word(14, mi->y1 + 1); -+#undef set_word -+ -+ if(fwrite(buf, (size_t) 16, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+} -+ -+static void maki_write_palette(mi, r, g, b, grey) -+ struct maki_info *mi; -+ byte *r, *g, *b; -+ int grey; -+{ -+ int i; -+ char buf[3]; -+ for(i = 0; i < mi->numcols; i++){ -+ buf[0] = *g++; -+ buf[1] = *r++; -+ buf[2] = *b++; -+ if(grey) -+ buf[0] = buf[1] = buf[2] = MONO(buf[1], buf[0], buf[2]); -+ if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+ } -+ for( ; i < 16; i++){ -+ if(fwrite(buf, (size_t) 3, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+ } -+} -+ -+static void maki_write_flags(mi) -+ struct maki_info *mi; -+{ -+ int bpl = mi->width / 2 / 8; -+ if(fwrite(mi->fa, (size_t) bpl * mi->height / 16, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+ -+ if(fwrite(mi->fb, (size_t) mi->fb_size, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+} -+ -+static void maki_write_pixel_data(mi) -+ struct maki_info *mi; -+{ -+ if(fwrite(mi->pa, (size_t) mi->pa_size, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+ -+ if(fwrite(mi->pb, (size_t) mi->pb_size, (size_t) 1, mi->fp) != 1) -+ maki_file_error(mi, MAKI_WRITE); -+} -+ -+ -+ -+static void maki_init_info(mi) -+ struct maki_info *mi; -+{ -+ xvbzero((char *)mi, sizeof(struct maki_info)); -+ mi->fp = NULL; -+ mi->fsize = 0; -+ mi->x0 = mi->y0 = mi->x1 = mi->y1 = 0; -+ mi->width = mi->height = 0; -+ mi->aspect = 1.0; -+ mi->fb_size = mi->pa_size = mi->pb_size = 0; -+ mi->m_maki01b = mi->m_200 = mi->m_dig8 = 0; -+ mi->ext_flag = 0; -+ mi->fa = mi->fb = mi->pa = mi->pb = NULL; -+ mi->vs = NULL; -+ mi->numcols = 16; -+ mi->forma = mi->formb = NULL; -+} -+ -+static void maki_cleanup_maki_info(mi, writing) -+ struct maki_info *mi; -+ int writing; -+{ -+ if(mi->fp && !writing) -+ fclose(mi->fp); -+ if(mi->fa) -+ free(mi->fa); -+ if(mi->fb) -+ free(mi->fb); -+ if(mi->pa) -+ free(mi->pa); -+ if(mi->pb) -+ free(mi->pb); -+ if(mi->vs) -+ free(mi->vs); -+ if(mi->forma) -+ free(mi->forma); -+ if(mi->formb) -+ free(mi->formb); -+} -+ -+static void maki_cleanup_pinfo(pi) -+ PICINFO *pi; -+{ -+ if(pi->pic){ -+ free(pi->pic); -+ pi->pic = NULL; -+ } -+} -+ -+static void maki_memory_error(scm, fn) -+ char *scm, *fn; -+{ -+ char buf[128]; -+ sprintf(buf, "%s: coulndn't allocate memory. (%s)", scm, fn); -+ FatalError(buf); -+} -+ -+static void maki_error(mi, mn) -+ struct maki_info *mi; -+ int mn; -+{ -+ SetISTR(ISTR_WARNING, "%s", maki_msgs[mn]); -+ longjmp(mi->jmp, 1); -+} -+ -+static void maki_file_error(mi, mn) -+ struct maki_info *mi; -+ int mn; -+{ -+ if(feof(mi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", maki_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", maki_msgs[mn], ERRSTR(errno)); -+ longjmp(mi->jmp, 1); -+} -+ -+static void maki_file_warning(mi, mn) -+ struct maki_info *mi; -+ int mn; -+{ -+ if(feof(mi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", maki_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", maki_msgs[mn], ERRSTR(errno)); -+} -+ -+static void maki_show_maki_info(mi) -+ struct maki_info *mi; -+{ -+ fprintf(stderr, " file size: %ld.\n", mi->fsize); -+ fprintf(stderr, " image size: %dx%d.\n", mi->width, mi->height); -+ fprintf(stderr, " aspect: %f.\n", mi->aspect); -+ fprintf(stderr, " flag B size: %ld.\n", mi->fb_size); -+ fprintf(stderr, " pixel data size: A:%ld, B:%ld.\n", -+ mi->pa_size, mi->pb_size); -+ fprintf(stderr, " MAKI01B: %s.\n", mi->m_maki01b ? "true" : "false"); -+ fprintf(stderr, " 200 line mode: %s.\n", mi->m_200 ? "true" : "false"); -+ fprintf(stderr, " digital 8 colors: %s.\n", mi->m_dig8 ? "true" : "false"); -+} -+ -+static void *maki_malloc(n, fn) -+ size_t n; -+ char *fn; -+{ -+ void *r = (void *) malloc(n); -+ if(r == NULL) -+ maki_memory_error("malloc", fn); -+ return r; -+} -+ -+static void *maki_realloc(p, n, fn) -+ void *p; -+ size_t n; -+ char *fn; -+{ -+ void *r = (p == NULL) ? (void *) malloc(n) : (void *) realloc(p, n); -+ if(r == NULL) -+ maki_memory_error("realloc", fn); -+ return r; -+} -+#endif /* HAVE_MAKI */ -diff -ruN xv-3.10a-bugfixes/xvmgcsfx.c xv-3.10a-enhancements/xvmgcsfx.c ---- xv-3.10a-bugfixes/xvmgcsfx.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvmgcsfx.c 2005-05-01 10:20:12.000000000 -0700 -@@ -0,0 +1,2276 @@ -+/* -+ * $Id: xvmgcsfx.c,v 1.23 95/11/27 19:03:36 tin329 Exp Locker: tin329 $ -+ * xvmgcsfx.c - Use the filters as input and output method. -+ * -+ * Features -+ * ======== -+ * Use the filters as input and output method for load and save unsupported -+ * image format file. The filter command is recognized by definition of -+ * magic number or suffix in "~/.xv_mgcsfx" . -+ * -+ * Bugs -+ * ==== -+ * There are many bugs. -+ * Let's go hunting for insects with an insect net. (it's all joke.) -+ * -+ * Author -+ * ====== -+ * Tetsuya INOUE <tin329@chino.it.okayama-u.ac.jp> -+ */ -+ -+/* -+ * Known Bugs and Todo / $B$"$l$3$l5$$K$J$k$3$H(B -+ * -+ * ~/.xv_mgcsfx $BFb(B -+ * $B!&Dj5A$,IT40A4$@$H%(%i!<(B (':'$B$N?t(B)$B!#(B -+ * $B!&%G%j%_%?$H$7$F(B ':' $B$r;H$&$N$G!"%9%?!<%H%"%C%W%U%!%$%kFb$G(B -+ * ':' $B$rMQ$$$FDj5A$O$G$-$J$$!#(B'\:'$B$G$b%@%a!#(B -+ * $B!&(B magic $B%?%$%W$G!"#8?J?t$O#37eJ,#0!A#7$rD4$Y!"#1#6?J?t$O(B -+ * isxdigit $B$,??$rJV$94VCf=hM}$5$l$k!#$7$+$7!"#1#b#y#t#e$H(B -+ * $B$7$F$7$+I>2A$5$l$J$$!#(B -+ * $B!&%W%j%W%m%;%C%5$r;H$&$H$-$O!"%3%a%s%H$N=q$-J}$KCm0U$7$J$1$l$P$J(B -+ * $B$i$J$$!#%W%j%W%m%;%C%5$K$h$C$F$O%3%a%s%H$,%(%i!<$K$J$k!#(B -+ * $B!&%Q%$%W$X$NF~=PNO$N%U%)!<%^%C%H$N<oN`$,(B PNM $B$N$_(B -+ * $BF~NO(B -+ * $B%U%!%$%k%]%$%s%?$r(B seek $B$7$F$O$$$1$J$$(B -+ * $B%U%!%$%k%5%$%:$rMQ$$$F$O$$$1$J$$(B -+ * $B=PNO(B -+ * $B%U%!%$%k%]%$%s%?$r(B seek $B$7$F$O$$$1$J$$(B -+ * exec $B$G$-$J$/$F=*N;$7$?%W%m%;%9$K=q$-9~$_IT2D(B -+ * $B!&%5%U%#%C%/%9$H%^%8%C%/%J%s%P!<$N;H$$J,$1$r$I$&$9$k$+!#(B -+ * $B%^%8%C%/%J%s%P!<$,F1$8$G!"%5%U%#%C%/%9$,0[$J$k>l9g$rG'$a$k$+!)(B -+ * $B!&(Bcompress(gzip)$B$N%U%!%$%k$O%F%s%]%i%j$G$O(B xvtmp??? $B$H$$$&L>A0$J(B -+ * $B$N$G(B suffix $B$G$O<1JL$G$-$J$$!#(B -+ * -+ * $BG'<1$9$k;~$K(B MACBINARY $B$K$OIi$1$k(B(in xv.c)$B!#(B -+ * -+ * $BB?=E$K(B pipe $B$rDL$9$3$H$,$G$-$J$$!#(B(pipe $B$,(B seek $B$G$-$J$$$+$i(B) -+ * $B!&(Bsocketpair $B$G!"(Brecv $B$K(B MSG_PEEK $B%U%i%0$r$D$+$C$F6uFI$_$9$k!#(B -+ * $B!&$3$l$r$d$k$H%U%!%$%k$NG'<1$,$a$A$c$a$A$cCY$/$J$k!#(B -+ * -+ * $B%j%=!<%9$G@_Dj(B -+ * $B!&%j%=!<%9$G@_Dj$9$kJ}$,LLE]$/$5$$(B -+ * -+ * $B%^%8%C%/%J%s%P!<$N@_Dj$K@55,I=8=(B -+ * -+ * $B%;!<%VMQ%W%m%;%9$,<:GT$9$k>l9g$NBP:v$,:#0l$D(B -+ * -+ * DEC OSF/1 V3.0 $B$G$O!"%Q%$%W$K%G!<%?$,$^$@$J$$;~$KFI$_9~$b$&$H$9$k$H!"(B -+ * read $B$,IT40A4$K$J$k!#(B(in xvpbm.c) -+ * $BF1MM$K=q$-9~$_;~$K$bLdBj$,@8$8$k$+$b$7$l$J$$!#(B -+ */ -+ -+#define NEEDSDIR /* for stat() */ -+#include "xv.h" -+ -+ -+#ifdef HAVE_MGCSFX -+ -+ -+#ifdef __osf__ -+# ifdef __alpha -+# define ARCHITECTURE64 1 -+# endif /* __alpha */ -+#endif /* __osf__ */ -+ -+#ifdef ARCHITECTURE64 -+typedef short int16; -+typedef int int32; -+typedef long int64; -+#else -+typedef short int16; -+typedef long int32; -+#endif /* ARCHITECTURE64 */ -+ -+#ifdef sgi -+# define vfork fork -+#endif -+ -+#define USE_SIGCHLD -+#if 0 -+# undef USE_SIGCHLD -+#endif -+ -+#ifdef USE_SIGCHLD -+# include <sys/wait.h> -+#endif -+ -+typedef struct _mgcsfxtab -+{ -+ struct _mgcsfxtab *next; -+ char *description; -+ int mgcsfx_type; -+ int offset; -+ union{ -+ int16 int16_data; -+ int32 int32_data; -+ char *string_data; -+ } dt; -+ int string_len; -+ char *suffix; -+ int input_image_type; -+ char *input_command; -+ int output_image_type; -+ char *output_command; -+} mgcsfxtab; -+ -+ -+#ifndef MGCSFXDIR -+# define MGCSFXDIR "/usr/local/lib" -+#endif -+#ifndef SYSCONFDIR -+# define SYSCONFDIR MGCSFXDIR -+#endif -+#ifndef MGCSFX_SITE_RC -+# define MGCSFX_SITE_RC "xv_mgcsfx" -+#endif -+#ifndef MGCSFX_RC -+# define MGCSFX_RC ".xv_mgcsfx" -+#endif -+ -+#ifdef USE_MGCSFX_PREPROCESSOR -+# ifndef MGCSFX_PREPROCESSOR -+# define MGCSFX_PREPROCESSOR "/usr/lib/cpp" -+# endif -+#endif -+ -+ -+/* Check type for Magic number and Suffix */ -+enum {T_UNKNOWN, -+ T_MAGIC, T_SUFFIX, -+ T_BEINT16, T_BEINT32, T_BEINT64, -+ T_LEINT16, T_LEINT32, T_LEINT64}; -+ -+/* Image Type for input and output format */ -+enum {IT_UNKNOWN, -+#ifdef HAVE_MGCSFX_AUTO -+ IT_AUTO, -+#endif /* HAVE_MGCSFX_AUTO */ -+ IT_PNM, IT_PPM, IT_PGM, IT_PBM, -+ IT_PNM_RAW, IT_PPM_RAW, IT_PGM_RAW, IT_PBM_RAW, -+ IT_PNM_ASCII, IT_PPM_ASCII, IT_PGM_ASCII, IT_PBM_ASCII, -+ IT_GIF, IT_JPEG, IT_TIFF, IT_JFIF, /* IT_PS, IT_COMPRESS,*/ -+ IT_XBM, IT_XPM, IT_BMP, IT_SUNRAS, IT_IRIS, IT_XWD, -+ /* IT_TARGA, IT_FITS, IT_PM, IT_UTAHRLE, IT_PCX, IT_PDSVICAR, IT_IFF, */ -+ IT_MAG, IT_MAKI, IT_PI, IT_PIC, IT_PIC2 /* , IT_PCD */}; -+ -+ -+/*--------------------------------------------------------------------------*/ -+void mgcsfx_handler PARM((int)); -+void mgcsfx_handler_setup PARM((void)); -+ -+#ifdef USE_MGCSFX_PREPROCESSOR -+static char *get_tmp_fname PARM((void)); -+static char *make_preprocessed_file PARM((char *)); -+#endif /* USE_MGCSFX_PREPROCESSOR */ -+ -+int is_mgcsfx PARM((char *, unsigned char *, int)); -+ -+char *mgcsfx_auto_input_com PARM((char *)); -+ -+ -+static mgcsfxtab *free_mgcsfx PARM((mgcsfxtab *)); -+static char *fgettoken PARM((FILE*, int)); -+static int string_fin PARM((char *)); -+static int type_mgcsfx PARM((char *)); -+static int type_image PARM((char *)); -+ -+static void read_mgcsfx PARM((mgcsfxtab **, char *)); -+static void init_mgcsfx PARM((void)); -+static mgcsfxtab *find_mgcsfx PARM((char *, unsigned char *, int)); -+ -+int LoadMGCSFX PARM((char *, PICINFO *)); -+ -+#ifdef SVR4 -+typedef void Sigfunc(int); -+static Sigfunc *xv_signal PARM((int , Sigfunc *)); -+#endif -+ -+/*--------------------------------------------------------------------------*/ -+mgcsfxtab *mgcsfx_table = NULL; -+int mgcsfx_setup_flag = 0; -+ -+int nitem_mgcsfx = 0; -+int desc_width = 0; -+ -+int max_offset_mgcsfx = 0; -+int max_length_mgcsfx = 0; -+int need_buf_size = 0; -+ -+static char input_command_ex[1024]; -+static int input_command_ex_flag = 0; -+ -+#ifdef USE_SIGCHLD -+static int w_p_fail=0; -+#endif -+ -+/*--------------------------------------------------------------------------*/ -+ -+/***************************************************/ -+void mgcsfx_handler(sig) -+ int sig; -+{ -+#ifdef USE_SIGCHLD -+ int pid, pst; -+#endif -+ -+#if defined(SYSV) || defined(SVR4) -+ sighold(sig); -+#else -+ sigblock(sigmask(sig)); -+#endif -+ -+#ifdef USE_SIGCHLD -+ if(w_p_fail == 1){ -+ /* -+ * At this point, process write to broken pipe. -+ * Probably external command was can't exec. -+ */ -+ w_p_fail = 2; -+ pid = wait(&pst); -+ } -+#endif -+ -+ return; -+ -+ /* Quit(1); */ /*exit(1);*/ -+} -+ -+void mgcsfx_handler_setup() -+{ -+#ifdef SVR4 -+ xv_signal(SIGPIPE, (void (*)PARM((int))) mgcsfx_handler); -+ xv_signal(SIGCHLD, (void (*)PARM((int))) mgcsfx_handler); -+#else -+# ifdef SYSV -+ sigset(SIGPIPE, (void (*)PARM((int))) mgcsfx_handler); -+ sigset(SIGCHLD, (void (*)PARM((int))) mgcsfx_handler); -+# else -+ signal(SIGPIPE, (void (*)PARM((int))) mgcsfx_handler); -+ signal(SIGCHLD, (void (*)PARM((int))) mgcsfx_handler); -+# endif -+#endif -+} -+ -+/***************************************************/ -+#ifdef USE_MGCSFX_PREPROCESSOR -+static char *get_tmp_fname() -+{ -+ static char tmp[MAXPATHLEN+1]; -+ -+#ifndef VMS -+ sprintf(tmp, "%s/xvmgcsfxXXXXXX",tmpdir); -+#else -+ /* sprintf(tmp, "Sys$Scratch:xvmgcsfxXXXXXX"); */ -+ strcpy(tmp, "[]xvmgcsfxXXXXXX"); -+#endif /* VMS */ -+ -+#ifdef USE_MKSTEMP -+ close(mkstemp(tmp)); -+#else -+ mktemp(tmp); -+#endif -+ -+ return tmp; -+} -+ -+static char *make_preprocessed_file(fname) -+ char *fname; -+{ -+ char buf[512]; -+ char *tmp_name; -+ -+ tmp_name = get_tmp_fname(); -+ -+#ifndef VMS -+ sprintf(buf,"%s %s > %s", MGCSFX_PREPROCESSOR, fname, tmp_name); -+#else -+ sprintf(buf,"%s %s > %s", MGCSFX_PREPROCESSOR, fname, tmp_name); /* really OK? */ -+#endif -+ -+ SetISTR(ISTR_INFO, "Preprocessing '%s'...", BaseName(fname)); -+#ifndef VMS -+ if (system(buf)) -+#else -+ if (!system(buf)) -+#endif -+ { -+ SetISTR(ISTR_INFO, "Unable to preprocess '%s'.", BaseName(fname)); -+ Warning(); -+ return NULL; -+ } -+ -+ return tmp_name; -+} -+#endif /* USE_MGCSFX_PREPROCESSOR */ -+ -+/***************************************************/ -+/* $BG'<1$G$-$k%U%!%$%k$+$I$&$+D4$Y$k(B */ -+int is_mgcsfx(fname,buffer,size) -+ char *fname; -+ unsigned char *buffer; -+ int size; -+{ -+ mgcsfxtab *magic; -+ FILE *fp; -+ unsigned char *buf; -+ int s; -+ -+ if(nomgcsfx){ -+ return 0; -+ }else{ -+ if(size < need_buf_size){ -+ if((buf = (unsigned char *)calloc(need_buf_size, sizeof(char)))==NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ return 0; -+ } -+ if((fp = xv_fopen(fname, "r"))==NULL){ -+ fprintf(stderr,"Can't open file %s\n", fname); -+ free(buf); -+ return 0; -+ } -+ s = fread(buf, 1, need_buf_size, fp); -+ if((magic = find_mgcsfx(fname, buf, s))!=NULL && -+ magic->input_command != NULL){ -+ free(buf); -+ fclose(fp); -+ return 1; -+ }else{ -+ free(buf); -+ fclose(fp); -+ return 0; -+ } -+ }else{ -+ if((magic = find_mgcsfx(fname, buffer, size))!=NULL && -+ magic->input_command != NULL){ -+ return 1; -+ }else{ -+ return 0; -+ } -+ } -+ } -+} -+ -+#ifdef HAVE_MGCSFX_AUTO -+char *mgcsfx_auto_input_com(fname) -+char *fname; -+{ -+ static char command[1024]; -+ mgcsfxtab *magic; -+ char *ptr; -+ -+ FILE *fp; -+ unsigned char *buf; -+ int s; -+ -+ if((buf = (unsigned char *)calloc(need_buf_size, sizeof(char)))==NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ return NULL; -+ } -+ if((fp = xv_fopen(fname, "r"))==NULL){ -+ fprintf(stderr,"Can't open file %s\n", fname); -+ free(buf); -+ return NULL; -+ } -+ s = fread(buf, 1, need_buf_size, fp); -+ if((magic = find_mgcsfx(fname, buf, s))!=NULL && -+ magic->input_command != NULL && magic->input_image_type == IT_AUTO){ -+ if ((ptr = strstr(magic->input_command, "%s"))){ -+ sprintf(command, magic->input_command, fname); -+ }else{ -+ sprintf(command, "%s < %s", magic->input_command, fname); -+ } -+ free(buf); -+ fclose(fp); -+ return command; -+ }else{ -+ free(buf); -+ fclose(fp); -+ return NULL; -+ } -+} -+#endif /* HAVE_MGCSFX_AUTO */ -+ -+/***************************************************/ -+static mgcsfxtab *free_mgcsfx(m) -+ mgcsfxtab *m; -+{ -+ mgcsfxtab *next; -+ if(m == NULL) return NULL; -+ next = m->next; -+ if(m->description != NULL) free(m->description); -+ if(m->mgcsfx_type == T_MAGIC && m->dt.string_data != NULL) -+ free(m->dt.string_data); -+ if(m->suffix != NULL) free(m->suffix); -+ if(m->input_command != NULL) free(m->input_command); -+ if(m->output_command != NULL) free(m->output_command); -+ free(m); -+ return next; -+} -+ -+ -+ -+/***************************************************/ -+/* char c $B$^$?$O(B '\n' $B$G6h@Z$i$l$?J8;zNs$r<h$j=P$9(B -+ * $B%U%!%$%k$N:G8e$^$GFI$s$@$i(B NULL $B$rJV$9(B -+ * $B2~9T$J$i2~9T$rJV$9(B($B2~9T$G6h@Z$i$l$?>l9g$O(B '\n' $B$r%9%H%j!<%`$KLa$9(B) -+ */ -+#define CBUF_SIZE 1024 -+static char *fgettoken(fp, c) -+ FILE *fp; -+ int c; /* Real mean is char */ -+{ -+ char *buf; -+ char *buf2; -+ int i; -+ int n=0; -+ int max=0; -+ int count = 1; -+ -+ char *ss; -+ char *se; -+ -+ if((buf = (char *)calloc(CBUF_SIZE, sizeof(char))) == NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ exit(1); -+ } -+ max = CBUF_SIZE; -+ count = 2; -+ -+ do{ -+ if((i = getc(fp))==EOF || i == '\n' || i == c) break; -+ -+ buf[n] = (char)i; -+ -+ if(i != c && n == max-1){ -+ buf[max] = '\0'; -+ if((buf2 = (char *)calloc(CBUF_SIZE * count, sizeof(char))) == NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ exit(1); -+ } -+ strcpy(buf2, buf); -+ free(buf); -+ buf = buf2; -+ buf2 = NULL; -+ max = CBUF_SIZE * count; -+ count++; -+ } -+ -+ n++; -+ }while(i != c); -+ -+ buf[n] = '\0'; -+ -+ /* $B:G=i$H:G8e$N6uGrJ8;z$r@Z$j5M$a$k(B */ -+ ss = buf + strspn(buf, " \t\b\r\n"); /* find the first non-white space */ -+ se = buf + strlen(buf); /* find the end of the string */ -+ -+ /* strip from the end first */ -+ while ((--se >= ss) && strchr(" \t\b\r\n", *se)); -+ *(++se) = '\0'; -+ -+ if(i == EOF && strlen(ss)==0){ /* EOF $B$J$i(B NULL $B$rJV$9(B */ -+ free(buf); -+ return NULL; -+ }else if(i == '\n' && strlen(ss)==0){ /* $B2~9T$N$_$N>l9g(B */ -+ static char cr[2] = {'\n','\0'}; -+ buf2 = strdup(cr); -+ free(buf); -+ return buf2; -+ }else{ /* $BDL>o(B */ -+ if(i == '\n' && strlen(ss)>0) ungetc(i,fp); -+ buf2 = strdup(ss); -+ free(buf); -+ return buf2; -+ } -+} -+ -+ -+ -+/***************************************************/ -+/* $BJ8;zNsCf$NFC<l5-9f(B(\)$B$r@5$7$$$b$N$K$9$k(B -+ */ -+static int string_fin(string_data) -+ char *string_data; -+{ -+ char *cptr; -+ char *ptr; -+ int length; -+ -+ /* Change all the \xx sequences into a single character */ -+ cptr = string_data; -+ -+ for (ptr = cptr; *ptr; ++ptr){ -+ if (*ptr != '\\'){ -+ *cptr = *ptr; -+ }else{ -+ switch (*(++ptr)){ -+#if defined(__STDC__) -+ case 'a': /* Audible alert (terminal bell) */ -+ *cptr = '\007'; -+ break; -+ case '?': /* Question mark */ -+ *cptr = '\?'; -+ break; -+#endif -+ case 'b': /* Backspace */ -+ *cptr = '\b'; -+ break; -+ case 'f': /* Form feed */ -+ *cptr = '\f'; -+ break; -+ case 'n': /* Line feed */ -+ *cptr = '\n'; -+ break; -+ case 'r': /* Carriage return */ -+ *cptr = '\r'; -+ break; -+ case 't': /* Horizontal tab */ -+ *cptr = '\t'; -+ break; -+ case 'v': /* Vertical tab */ -+ *cptr = '\v'; -+ break; -+ case '\\': /* Backslash */ -+ *cptr = '\\'; -+ break; -+ case '\'': /* Single quote */ -+ *cptr = '\''; -+ break; -+ case '"': /* Double quote */ -+ *cptr = '\"'; -+ break; -+ case '0': /* Octal constant \0 ... \377 */ -+ case '1': -+ case '2': -+ case '3': -+ case '4': -+ case '5': -+ case '6': -+ case '7': -+ if ((ptr[1] >= '0') && (ptr[1] <= '7')){ -+ if ((ptr[2] >= '0') && (ptr[2] <= '7')){ /* \000 ...\377 */ -+ *cptr = ((*ptr - '0') * 64) +((ptr[1] - '0') * 8) +(ptr[1] - '0'); -+ ptr += 2; -+ }else{ /* \00 ...\77 */ -+ *cptr = ((*ptr - '0') * 8) + (ptr[1] - '0'); -+ ++ptr; -+ } -+ }else{ /* \0 ...\7 */ -+ *cptr = *ptr - '0'; -+ } -+ break; -+ case 'x': /* Hexadecimal constant \x0 .. \xff */ -+ if (isxdigit (ptr[1])){ -+ *cptr = 0; -+ while (isxdigit (*(++ptr))) -+ *cptr = (*cptr * 16) + -+ (*ptr > '9' ? tolower (*ptr) - ('a' - 10) : *ptr - '0'); -+ --ptr; -+ break; -+ } -+ default: -+ /* *(cptr++) = '\\'; No use for treat '\z' as 'z' */ -+ *cptr = *ptr; -+ break; -+ } -+ } -+ ++cptr; -+ } -+ *cptr = '\0'; -+ length = cptr - string_data; -+ return length; -+} -+ -+/***************************************************/ -+static int type_mgcsfx(str) -+ char *str; -+{ -+ if(str == NULL){ -+ return T_UNKNOWN; -+ }else if(!strcmp(str, "magic") || !strcmp(str, "MAGIC")){ -+ return T_MAGIC; -+ }else if(!strcmp(str, "string") || !strcmp(str, "STRING")){ -+ return T_MAGIC; -+ }else if(!strcmp(str, "suffix") || !strcmp(str, "SUFFIX")){ -+ return T_SUFFIX; -+ }else if(!strcmp(str, "beint16") || !strcmp(str, "BEINT16")){ -+ return T_BEINT16; -+ }else if(!strcmp(str, "leint16") || !strcmp(str, "LEINT16")){ -+ return T_LEINT16; -+ }else if(!strcmp(str, "beint32") || !strcmp(str, "BEINT32")){ -+ return T_BEINT32; -+ }else if(!strcmp(str, "leint32") || !strcmp(str, "LEINT32")){ -+ return T_LEINT32; -+ }else{ -+ return T_UNKNOWN; -+ } -+} -+ -+/***************************************************/ -+static int type_image(str) -+ char *str; -+{ -+ if(str == NULL){ -+ return IT_UNKNOWN; -+#ifdef HAVE_MGCSFX_AUTO -+ }else if(!strcmp(str, "auto") || !strcmp(str, "AUTO")){ -+ return IT_AUTO; -+#endif /* HAVE_MGCSFX_AUTO */ -+ }else if(!strcmp(str, "pnm") || !strcmp(str, "PNM")){ -+ return IT_PNM; -+ }else if(!strcmp(str, "ppm") || !strcmp(str, "PPM")){ -+ return IT_PPM; -+ }else if(!strcmp(str, "pgm") || !strcmp(str, "PGM")){ -+ return IT_PGM; -+ }else if(!strcmp(str, "pbm") || !strcmp(str, "PBM")){ -+ return IT_PBM; -+ }else if(!strcmp(str, "pnm_raw") || !strcmp(str, "PNM_RAW")){ -+ return IT_PNM_RAW; -+ }else if(!strcmp(str, "ppm_raw") || !strcmp(str, "PPM_RAW")){ -+ return IT_PPM_RAW; -+ }else if(!strcmp(str, "pgm_raw") || !strcmp(str, "PGM_RAW")){ -+ return IT_PGM_RAW; -+ }else if(!strcmp(str, "pbm_raw") || !strcmp(str, "PBM_RAW")){ -+ return IT_PBM_RAW; -+ }else if(!strcmp(str, "pnm_ascii") || !strcmp(str, "PNM_ASCII")){ -+ return IT_PNM_ASCII; -+ }else if(!strcmp(str, "ppm_ascii") || !strcmp(str, "PPM_ASCII")){ -+ return IT_PPM_ASCII; -+ }else if(!strcmp(str, "pgm_ascii") || !strcmp(str, "PGM_ASCII")){ -+ return IT_PGM_ASCII; -+ }else if(!strcmp(str, "pbm_ascii") || !strcmp(str, "PBM_ASCII")){ -+ return IT_PBM_ASCII; -+ -+ }else if(!strcmp(str, "gif") || !strcmp(str, "GIF")){ -+ return IT_GIF; -+ }else if(!strcmp(str, "jpeg") || !strcmp(str, "JPEG")){ -+ return IT_JPEG; -+ }else if(!strcmp(str, "tiff") || !strcmp(str, "TIFF")){ -+ return IT_TIFF; -+ }else if(!strcmp(str, "jfif") || !strcmp(str, "JFIF")){ -+ return IT_JFIF; -+ -+ }else if(!strcmp(str, "xbm") || !strcmp(str, "XBM")){ -+ return IT_XBM; -+ }else if(!strcmp(str, "xpm") || !strcmp(str, "XPM")){ -+ return IT_XPM; -+ }else if(!strcmp(str, "bmp") || !strcmp(str, "BMP")){ -+ return IT_BMP; -+ }else if(!strcmp(str, "sunras") || !strcmp(str, "SUNRAS")){ -+ return IT_SUNRAS; -+ }else if(!strcmp(str, "iris") || !strcmp(str, "IRIS")){ -+ return IT_IRIS; -+ }else if(!strcmp(str, "xwd") || !strcmp(str, "XWD")){ -+ return IT_XWD; -+ -+ }else if(!strcmp(str, "mag") || !strcmp(str, "MAG")){ -+ return IT_MAG; -+ }else if(!strcmp(str, "maki") || !strcmp(str, "MAKI")){ -+ return IT_MAKI; -+ }else if(!strcmp(str, "pi") || !strcmp(str, "PI")){ -+ return IT_PI; -+ }else if(!strcmp(str, "pic") || !strcmp(str, "PIC")){ -+ return IT_PIC; -+ }else if(!strcmp(str, "pic2") || !strcmp(str, "PIC2")){ -+ return IT_PIC2; -+ -+ }else{ -+ return IT_UNKNOWN; -+ } -+} -+ -+/*--------------------------------------------------------------------------*/ -+#define mgcsfx_read_error(FILENAME, LINENUM, AFTERFIELD) \ -+fprintf (stderr,\ -+"%s: line %d: missing fields of %s field\n",\ -+FILENAME, LINENUM, AFTERFIELD); -+ -+#define magic_type_error(FILENAME, LINENUM, MAGICNUMBER) \ -+fprintf (stderr,\ -+"%s: line %d: invalid <magic type> field '%s'\n",\ -+FILENAME, LINENUM, MAGICNUMBER); -+/*--------------------------------------------------------------------------*/ -+ -+/***************************************************/ -+static void read_mgcsfx(mgcsfx_table, fname) -+ mgcsfxtab **mgcsfx_table; -+ char *fname; -+{ -+ FILE *fp; -+ char *s; -+ int line_number = 0; -+ int str_len; -+ int reach_end; -+ int def_err; -+ -+ char *description; -+ char *mgcsfx_type; -+ char *offset; -+ char *magic; -+ char *suffix; -+ char *i_img; -+ char *i_com; -+ char *o_img; -+ char *o_com; -+ -+ mgcsfxtab *ent; -+ mgcsfxtab **entry; -+ -+ -+ if((fp=fopen(fname, "r"))==NULL){ -+ /* fprintf(stderr, "Can't open %s\n",fname); */ -+ return; -+ } -+ -+ while(1){ -+retry: -+ line_number++; -+ def_err = 0; -+ -+ s= NULL; -+ description = mgcsfx_type = offset = magic = suffix -+ = i_img = i_com = o_img = o_com = NULL; -+ reach_end = 0; -+ -+ if((s = fgettoken(fp, ':'))==NULL) break; /* EOF $B$J$i=*$j(B */ -+ if(*s == '#'){/* $B@hF,$,(B '#' $B$J$iFI$_$H$P$9(B */ -+ while((s = fgettoken(fp, '\n'))!=NULL){ -+ if(*s == '\n'){ -+ free(s); -+ goto retry; -+ } -+ free(s); -+ } -+ if(s == NULL) break; -+ }else if(*s == '\n'){/* $B6u9T$OL5;k(B */ -+ free(s); -+ goto retry; -+ } -+ if(strlen(s) > 0) description = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "data type"); -+ goto next; -+ } -+ if(strlen(s) > 0) mgcsfx_type = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "byte offset"); -+ goto next; -+ } -+ if(strlen(s) > 0) offset = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "magic number"); -+ goto next; -+ } -+ if(strlen(s) > 0) magic = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "suffix"); -+ goto next; -+ } -+ if(strlen(s) > 0) suffix = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "input image type"); -+ goto next; -+ } -+ if(strlen(s) > 0) i_img = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "input command"); -+ goto next; -+ } -+ if(strlen(s) > 0) i_com = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, ':'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ if(s != NULL) free(s); -+ mgcsfx_read_error(fname, line_number, "output image type"); -+ goto next; -+ } -+ if(strlen(s) > 0) o_img = s; -+ else free(s); -+ -+ if((s = fgettoken(fp, '#'))==NULL || *s == '\n'){/* $B2?$b$J$$$J$i@_Dj%_%9(B */ -+ /* -+ free(s); -+ mgcsfx_read_error(fname, line_number, "output command"); -+ goto next; -+ */ -+ if(s != NULL){ -+ *s = '\0'; -+ reach_end = 1; -+ } -+ } -+ if(s != NULL){ -+ if(strlen(s) > 0) o_com = s; -+ else free(s); -+ } -+ -+ if(reach_end == 0){ -+ while((s = fgettoken(fp, '\n'))!=NULL){/* $B9TKv$N%4%_$r<N$F$k(B */ -+ if(*s == '\n'){ -+ free(s); -+ break; /* goto next; */ -+ } -+ free(s); -+ } -+ }else{ -+ reach_end = 0; -+ } -+ -+ -+ -+ /* --------------------------------------------------------------------- */ -+next:; -+ -+ if(DEBUG){ -+ fprintf(stderr,"Read: file %s: line %d.\n", fname, line_number); -+ fprintf(stderr,"Description : %s\n", -+ description ? description : "-- error --"); -+ fprintf(stderr,"Type : %s\n", -+ mgcsfx_type ? mgcsfx_type : "-- error --"); -+ fprintf(stderr,"Offset : %s\n", offset ? offset : "--+--"); -+ fprintf(stderr,"Magic : %s\n", magic ? magic : "--+--"); -+ fprintf(stderr,"Suffix : %s\n", suffix ? suffix : "--+--"); -+ fprintf(stderr,"i Image : %s\n", i_img ? i_img : "--+--"); -+ fprintf(stderr,"i Command : %s\n", i_com ? i_com : "--+--"); -+ fprintf(stderr,"o Image : %s\n", o_img ? o_img : "--+--"); -+ fprintf(stderr,"o Command : %s\n", o_com ? o_com : "--+--"); -+ fprintf(stderr,"\n"); -+ } -+ -+ /* create mgcsfxtab */ -+ if((ent = (mgcsfxtab *) malloc (sizeof (mgcsfxtab)))==NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ exit(1); -+ } -+ ent->next = NULL; -+ ent->description = NULL; -+ ent->mgcsfx_type = T_UNKNOWN; -+ ent->offset = 0; -+ ent->string_len = 0; -+ ent->suffix = NULL; -+ ent->input_image_type = IT_UNKNOWN; -+ ent->input_command = NULL; -+ ent->output_image_type = IT_UNKNOWN; -+ ent->output_command = NULL; -+ -+ if(description != NULL){ -+ ent->description = description; -+ description = NULL; -+ }else{ -+ fprintf (stderr,"%s: line %d: undefined <description> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ -+ if(mgcsfx_type == NULL){ -+ fprintf (stderr,"%s: line %d: undefined <mgcsfx type> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ ent->mgcsfx_type = type_mgcsfx(mgcsfx_type); -+ switch(ent->mgcsfx_type){ -+ case T_SUFFIX: -+ if(suffix == NULL){ -+ fprintf (stderr, -+ "%s: line %d: conflict definition : undefined <suffix> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ break; -+ case T_BEINT16: -+ if (sscanf(magic, "%hi", &(ent->dt.int16_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+ case T_LEINT16: -+ if (sscanf(magic, "%hi", &(ent->dt.int16_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+#ifdef ARCHITECTURE64 -+ case T_BEINT32: -+ if (sscanf(magic, "%i", &(ent->dt.int32_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+ case T_LEINT32: -+ if (sscanf(magic, "%i", &(ent->dt.int32_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+#else -+ case T_BEINT32: -+ if (sscanf(magic, "%li", &(ent->dt.int32_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+ case T_LEINT32: -+ if (sscanf(magic, "%li", &(ent->dt.int32_data)) != 1){ -+ magic_type_error(fname, line_number, magic); -+ def_err ++; -+ goto next2; -+ } -+ break; -+#endif /* ARCHITECTURE64 */ -+ case T_MAGIC: -+ if(magic == NULL){ -+ fprintf (stderr,"%s: line %d: undefined <magic> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ if((str_len = string_fin(magic))<=0){ -+ fprintf (stderr,"%s: line %d: invalid <magic> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ -+ ent->string_len = str_len; -+ if((ent->dt.string_data = (char *)malloc(str_len + 1))==NULL){ -+ fprintf(stderr,"Can't allocate memory\n"); -+ exit(1); -+ } -+ memcpy(ent->dt.string_data, magic, str_len + 1); -+ break; -+ case T_UNKNOWN: -+ default: -+ fprintf (stderr,"%s: line %d: invalid <mgcsfx type> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ break; -+ }; -+ -+ -+ if(offset == NULL){ -+ if(ent->mgcsfx_type == T_MAGIC || -+ ent->mgcsfx_type == T_BEINT16 || -+ ent->mgcsfx_type == T_LEINT16 || -+ ent->mgcsfx_type == T_BEINT32 || -+ ent->mgcsfx_type == T_LEINT32){ -+ fprintf (stderr, -+ "%s: line %d: conflict definition : undefined <offset> field.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ }else{ -+ if(ent->mgcsfx_type != T_SUFFIX) sscanf(offset, "%i", &(ent->offset)); -+ } -+ -+ if(suffix != NULL){ -+ ent->suffix = suffix; -+ suffix = NULL; -+ } -+ -+ if((i_img == NULL && i_com == NULL) && (o_img == NULL || o_com == NULL)){ -+ fprintf (stderr,"%s: line %d: invalid definition.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ if((o_img == NULL && o_com == NULL) && (i_img == NULL || i_com == NULL)){ -+ fprintf (stderr,"%s: line %d: invalid definition.\n", -+ fname, line_number); -+ def_err ++; -+ goto next2; -+ } -+ -+ if(i_img != NULL && i_com != NULL){ -+ ent->input_image_type = type_image(i_img); -+ ent->input_command = i_com; -+ i_com = NULL; -+ }else{ -+ ent->input_image_type = IT_UNKNOWN; -+ ent->input_command = NULL; -+ } -+ -+ if(o_img != NULL && o_com != NULL){ -+ ent->output_image_type = type_image(o_img); -+ ent->output_command = o_com; -+ o_com = NULL; -+ }else{ -+ ent->output_image_type = IT_UNKNOWN; -+ ent->output_command = NULL; -+ } -+ /* end of create mgcsfxtab */ -+ -+ -+next2:; -+ -+ if(def_err != 0 || DEBUG){ -+ fprintf(stderr,"Description : %s \t -> %s\n", -+ description ? description : "--+--", -+ ent->description ? ent->description : "-- error --"); -+ fprintf(stderr,"Type : %s \t -> %d\n", -+ mgcsfx_type ? mgcsfx_type : "--+--", -+ ent->mgcsfx_type); -+ fprintf(stderr,"Offset : %s \t -> %d\n", -+ offset ? offset : "--+--", -+ ent->offset); -+ -+ fprintf(stderr,"Magic : %s", magic ? magic : "--+--"); -+ switch(ent->mgcsfx_type){ -+ case T_BEINT16: -+ case T_LEINT16: -+ fprintf(stderr," \t -> %d\n",ent->dt.int16_data); -+ break; -+ case T_BEINT32: -+ case T_LEINT32: -+ fprintf(stderr," \t -> %ld\n",ent->dt.int32_data); -+ break; -+ case T_MAGIC: -+ fprintf(stderr," \t -> %s\n",ent->dt.string_data); -+ break; -+ default: -+ fprintf(stderr,"\n"); -+ break; -+ }; -+ -+ fprintf(stderr,"Suffix : %s \t -> %s\n", -+ suffix ? suffix : "--+--", -+ ent->suffix ? ent->suffix : "--+--"); -+ fprintf(stderr,"i Image : %s \t -> %d\n", -+ i_img ? i_img : "--+--", -+ ent->input_image_type); -+ fprintf(stderr,"i Command : %s \t -> %s\n", -+ i_com ? i_com : "--+--", -+ ent->input_command ? ent->input_command : "--+--"); -+ fprintf(stderr,"o Image : %s \t -> %d\n", -+ o_img ? o_img : "--+--", -+ ent->output_image_type); -+ fprintf(stderr,"o Command : %s \t -> %s\n", -+ o_com ? o_com : "--+--", -+ ent->output_command ? ent->output_command : "--+--"); -+ fprintf(stderr,"\n"); -+ } -+ -+ if(description != NULL) free(description); -+ if(mgcsfx_type != NULL) free(mgcsfx_type); -+ if(offset != NULL) free(offset); -+ if(magic != NULL) free(magic); -+ if(suffix != NULL) free(suffix); -+ if(i_img != NULL) free(i_img); -+ if(i_com != NULL) free(i_com); -+ if(o_img != NULL) free(o_img); -+ if(o_com != NULL) free(o_com); -+ -+ -+ if(def_err != 0) goto next3; -+ -+ /* Override any existing entry for this magic number/file type */ -+ for(entry = mgcsfx_table; *entry; entry = &((*entry)->next)){ -+ if((ent->mgcsfx_type == (*entry)->mgcsfx_type) && -+ ( -+ ((ent->offset == (*entry)->offset) && -+ (((ent->mgcsfx_type == T_BEINT16) && -+ (ent->dt.int16_data == (*entry)->dt.int16_data)) || -+ ((ent->mgcsfx_type == T_BEINT32) && -+ (ent->dt.int32_data == (*entry)->dt.int32_data)) || -+ ((ent->mgcsfx_type == T_LEINT16) && -+ (ent->dt.int16_data == (*entry)->dt.int16_data)) || -+ ((ent->mgcsfx_type == T_LEINT32) && -+ (ent->dt.int32_data == (*entry)->dt.int32_data)) || -+ -+ ((ent->mgcsfx_type == T_MAGIC) && -+ !memcmp(ent->dt.string_data, (*entry)->dt.string_data, -+ ent->string_len)) -+ )) || -+ ((ent->mgcsfx_type == T_SUFFIX) && -+ !strcmp(ent->suffix, (*entry)->suffix)) -+ ) -+ ){ -+ -+ free ((*entry)->description); -+ (*entry)->description = ent->description; -+ ent->description = NULL; -+ -+ (*entry)->input_image_type = ent->input_image_type; -+ if ((*entry)->input_command) free ((*entry)->input_command); -+ (*entry)->input_command = ent->input_command; -+ ent->input_command = NULL; -+ -+ (*entry)->output_image_type = ent->output_image_type; -+ if ((*entry)->output_command) free ((*entry)->output_command); -+ (*entry)->output_command = ent->output_command; -+ ent->output_command = NULL; -+ -+ free_mgcsfx(ent); -+ break; -+ } -+ } -+ if (!*entry){ -+ ent->next = NULL; -+ *entry = ent; -+ } -+ -+ /* if(s == NULL) break; */ -+next3:; -+ if(def_err != 0) free_mgcsfx(ent); -+ } /* end of while(1) */ -+} -+ -+ -+/***************************************************/ -+/* $B%^%8%C%/%J%s%P!<Dj5A%U%!%$%kL>$rF@$F!"FI$_9~$^$;$k(B */ -+static void init_mgcsfx () -+{ -+ extern char *getenv (); -+ -+ char *home_dir; -+ char fname[1024]; -+ mgcsfxtab *entry; -+ int len; -+ struct stat st; -+ -+#ifdef USE_MGCSFX_PREPROCESSOR -+ char *pp_fname; -+#endif /* USE_MGCSFX_PREPROCESSOR */ -+ -+ mgcsfx_table = NULL; -+ -+ mgcsfx_handler_setup(); -+ -+ if(nomgcsfx){ -+ mgcsfx_setup_flag = 1; -+ nitem_mgcsfx = 0; -+ desc_width = 0; -+ }else{ -+ sprintf (fname, "%s/%s", SYSCONFDIR, MGCSFX_SITE_RC); -+ if(stat(fname, &st) == 0 && S_ISREG(st.st_mode)){ -+ /* Read the site MagicSuffix table into a linked list */ -+#ifdef USE_MGCSFX_PREPROCESSOR -+ if((pp_fname = make_preprocessed_file(fname)) != NULL){ -+ read_mgcsfx (&mgcsfx_table, pp_fname); -+ } -+ unlink(pp_fname); -+#else -+ read_mgcsfx (&mgcsfx_table, fname); -+#endif /* USE_MGCSFX_PREPROCESSOR */ -+ } -+ -+ /* Read the personal MgcSfx table into the list overriding site entries */ -+ if ((home_dir = getenv ("HOME"))){ -+ sprintf (fname, "%s/%s", home_dir, MGCSFX_RC); -+ if(stat(fname, &st) == 0 && S_ISREG(st.st_mode)){ -+#ifdef USE_MGCSFX_PREPROCESSOR -+ if((pp_fname = make_preprocessed_file(fname)) != NULL){ -+ read_mgcsfx (&mgcsfx_table, pp_fname); -+ } -+ unlink(pp_fname); -+#else -+ read_mgcsfx (&mgcsfx_table, fname); -+#endif /* USE_MGCSFX_PREPROCESSOR */ -+ } -+ } -+ -+ mgcsfx_setup_flag = 1; -+ -+ nitem_mgcsfx = 0; -+ desc_width = 0; -+ for (entry = mgcsfx_table; entry; entry = entry->next){ -+ nitem_mgcsfx ++; -+ len = strlen(entry->description); -+ if(len > desc_width) desc_width = len; -+ if(max_offset_mgcsfx < entry->offset) max_offset_mgcsfx = entry->offset; -+ if(entry->mgcsfx_type == T_MAGIC && -+ max_length_mgcsfx < entry->string_len) -+ max_length_mgcsfx = entry->string_len; -+ } -+ if(max_length_mgcsfx == 0) max_length_mgcsfx = sizeof(int32); -+ need_buf_size = max_offset_mgcsfx + max_length_mgcsfx + 1;/* 1 is safety */ -+ } -+} -+ -+/***************************************************/ -+/* $B%^%8%C%/%J%s%P!<$rD4$Y$F!"Dj5A$7$F$$$k%F!<%V%k$r8!:w$9$k(B -+ $B%^%8%C%/%J%s%P!<$N%F!<%V%k$rFI$_9~$s$G$$$J$$$J$iFI$_9~$`(B */ -+static mgcsfxtab *find_mgcsfx (fname, buffer, buffer_size) -+ char *fname; -+ unsigned char *buffer; -+ int buffer_size; -+{ -+ mgcsfxtab *entry; -+ int16 buf16; -+ int32 buf32; -+ char *suf; -+ -+ if (mgcsfx_setup_flag == 0) init_mgcsfx (); -+ -+ for (entry = mgcsfx_table; entry; entry = entry->next){ -+ switch (entry->mgcsfx_type){ -+ case T_BEINT16: -+ if ((buffer_size > 0) && -+ ((entry->offset + sizeof (int16)) <= buffer_size)){ -+ buf16 = ((char)*(buffer + entry->offset) << 8) | -+ ((char)*(buffer + entry->offset +1)); -+ if(entry->dt.int16_data == buf16) return entry; -+ } -+ break; -+ case T_LEINT16: -+ if ((buffer_size > 0) && -+ ((entry->offset + sizeof (int16)) <= buffer_size)){ -+ buf16 = ((char)*(buffer + entry->offset +1) << 8) | -+ ((char)*(buffer + entry->offset)); -+ if(entry->dt.int16_data == buf16) return entry; -+ } -+ break; -+ case T_BEINT32: -+ if ((buffer_size > 0) && -+ ((entry->offset + sizeof (int32)) <= buffer_size)){ -+ buf32 = ((char)*(buffer + entry->offset) << 24) | -+ ((char)*(buffer + entry->offset +1) << 16) | -+ ((char)*(buffer + entry->offset +2) << 8) | -+ ((char)*(buffer + entry->offset +3)); -+ if(entry->dt.int32_data == buf32) return entry; -+ } -+ break; -+ case T_LEINT32: -+ if ((buffer_size > 0) && -+ ((entry->offset + sizeof (int32)) <= buffer_size)){ -+ buf32 = ((char)*(buffer + entry->offset +3) << 24) | -+ ((char)*(buffer + entry->offset +2) << 16) | -+ ((char)*(buffer + entry->offset +1) << 8) | -+ ((char)*(buffer + entry->offset)); -+ if(entry->dt.int32_data == buf32) return entry; -+ } -+ break; -+ case T_MAGIC: -+ if ((buffer_size > 0) && -+ ((entry->offset + entry->string_len) -+ <= buffer_size) && -+ !memcmp (entry->dt.string_data, buffer + entry->offset, -+ entry->string_len )) -+ return entry; -+ break; -+ case T_SUFFIX: -+ if(fname != NULL && entry->suffix != NULL){ -+ if(strlen(fname) - strlen(entry->suffix) > 0){ -+ suf = fname + (strlen(fname) - strlen(entry->suffix)); -+ if(!strcmp(suf, entry->suffix)) return entry; -+ } -+ } -+ break; -+ case T_UNKNOWN: -+ default: -+ return NULL; -+ break; -+ } -+ } -+ return NULL; -+} -+ -+ -+ -+ -+ -+/***************************************************/ -+/* $B%^%8%C%/%J%s%P!<$NDj5A$rD4$Y$F!"$=$l$K$"$o$;$?%3%^%s%I$r<B9T$9$k(B */ -+/* if OK return 1, else if ERROR return 0 */ -+int -+LoadMGCSFX(file_name, pinfo) -+ char *file_name; -+ PICINFO *pinfo; -+{ -+ unsigned char *buffer; -+ int size; -+ mgcsfxtab *magic; -+ mgcsfxtab *magic_cur; -+ char *ptr; -+ char command[1024]; -+ int fd[2]; -+ int pid = -2; -+ int file; -+ char *fname; -+ int rv; -+ int pst; -+ -+ int i_it; -+ char *i_com; -+ -+ WaitCursor(); -+ -+ fname = file_name; -+ if((file = open (fname, O_RDONLY))<0){ -+ SetISTR(ISTR_WARNING, "Can't open %s",fname); -+ return 0; -+ } -+ -+ if((buffer = (unsigned char *)calloc(need_buf_size, sizeof(char))) == NULL){ -+ SetISTR(ISTR_WARNING, "Can't allocate memory"); -+ return 0; -+ } -+ -+ magic_cur = NULL; -+ -+/* do{ */ -+ size = read (file, buffer, need_buf_size); -+ -+ if (lseek (file, 0L, 0) < 0){ /* can't seek pipe !! */ -+ fprintf (stderr, "Can't lseek %s\n", file_name); -+ close(file); -+ return 0; -+ } -+ -+ magic = find_mgcsfx (fname, buffer, size); -+ -+ if ((magic != NULL && magic->input_command) || -+ (magic == NULL && mgcsfx && input_command_ex_flag)){ -+ -+ if(magic == NULL){ -+ if (fname != NULL && (ptr = strstr(input_command_ex, "%s"))){ -+ sprintf (command, input_command_ex, fname); -+ }else{ -+ strcpy (command, input_command_ex); -+ fname=NULL; -+ } -+ }else{ -+ /* Use stdin or give file name */ -+ if (fname != NULL && (ptr = strstr(magic->input_command, "%s"))){ -+ sprintf (command, magic->input_command, fname); -+ }else{ -+ strcpy (command, magic->input_command); -+ fname=NULL; -+ } -+ } -+ -+ /* Do the pipe/fork/exec here */ -+ if (pipe (fd) < 0){ -+ fprintf (stderr, "Can't pipe : %s\n", file_name); -+ close(file); -+ return 0; -+ } -+ -+ if ((pid = vfork ()) < 0){ -+ fprintf (stderr, "Can't vfork : %s\n", file_name); -+ close (fd[0]); -+ close (fd[1]); -+ close(file); -+ return 0; -+ } -+ -+ if (!pid){ -+ close(0); -+ if (fname == NULL || (open ("/dev/null", O_RDONLY) < 0)){ -+ dup(file); -+ } -+ close(file); -+ close(1); -+ dup(fd[1]); -+ close(2); -+ open("/dev/null", O_WRONLY); -+ close(fd[0]); -+ execl("/bin/sh", "/bin/sh", "-c", command, 0); -+ _exit(127); -+ } -+ -+ close (fd[1]); -+ dup2(fd[0], file); -+ close (fd[0]); -+ fname = NULL; -+ magic_cur = magic; -+ } -+/* } while(magic != NULL); */ -+ -+ free(buffer); -+ -+ if(magic_cur == NULL && mgcsfx && input_command_ex_flag){ -+ i_it = IT_PNM; -+ i_com = input_command_ex; -+ }else{ -+ i_it = magic_cur->input_image_type; -+ i_com = magic_cur->input_command; -+ } -+ -+ if((magic_cur != NULL && i_com) || -+ (magic_cur == NULL && mgcsfx && input_command_ex_flag)){ -+ switch(i_it){ -+ case IT_PNM: -+ case IT_PPM: -+ case IT_PGM: -+ case IT_PBM: -+ case IT_PNM_RAW: -+ case IT_PPM_RAW: -+ case IT_PGM_RAW: -+ case IT_PBM_RAW: -+ case IT_PNM_ASCII: -+ case IT_PPM_ASCII: -+ case IT_PGM_ASCII: -+ case IT_PBM_ASCII: -+ rv = LoadPBM(file_name, pinfo, file); -+ break; -+ case IT_GIF: -+ case IT_JPEG: -+ case IT_TIFF: -+ case IT_JFIF: -+ case IT_XBM: -+ case IT_XPM: -+ case IT_BMP: -+ case IT_SUNRAS: -+ case IT_IRIS: -+ case IT_XWD: -+ case IT_MAG: -+ case IT_MAKI: -+ case IT_PI: -+ case IT_PIC: -+ case IT_PIC2: -+ SetISTR(ISTR_WARNING, "Yet supported input image type (from filter output)"); -+ rv = 0; -+ break; -+ case IT_UNKNOWN: -+ SetISTR(ISTR_WARNING, "Unknown input image type (from filter output)"); -+ rv = 0; -+ break; -+#ifdef HAVE_MGCSFX_AUTO -+ case IT_AUTO: -+#endif -+ default: -+ SetISTR(ISTR_WARNING, "Error in input image type (from filter output)"); -+ rv = 0; -+ break; -+ } -+ }else{ -+ rv = 0; -+ } -+ -+ /* fail if pid still == -2? */ -+ while(wait(&pst) != pid); /* FIXME? pid isn't necessarily initialized... */ -+ if( *((char *)&pst) != 0 ) rv = 0; -+ -+ input_command_ex_flag = 0; -+ -+ return rv; -+ -+ /* fclose(fp); close in Load??? */ -+ /* return 0; error */ -+ /* return 1; ok */ -+} -+ -+ -+ -+ -+ -+/*--------------------------------------------------------------------------*/ -+#ifndef MGCSFX_DEFAULT_INPUT_COMMAND -+# define MGCSFX_DEFAULT_INPUT_COMMAND "tifftopnm" -+#endif -+#ifndef MGCSFX_DEFAULT_OUTPUT_COMMAND -+# define MGCSFX_DEFAULT_OUTPUT_COMMAND "pnmtotiff" -+#endif -+ -+int MSWIDE = 0; -+int MSHIGH = 0; -+ -+#define MS_NBUTTS 2 -+#define MS_BOK 0 -+#define MS_BCANC 1 -+#define BUTTW 60 /* width of buttons (OK or Cancel) */ -+#define BUTTH 24 /* height of buttons (OK or Cancel) */ -+#define RBSIZE 15 /* width and height of RB button (select, ON or OFF)*/ -+#define CWIDE 8 /* width of character */ -+/* #define CHIGH height of character defined in xv.h */ -+#define MARGIN 3 /* margin of button and label SPACING */ -+ -+#define MSD_TITLE "Save file with external command..." -+#define MSD_RBTITLE "Type of Magic and Suffix" -+#define MSD_IC_TITLE "input command" -+ -+static BUTT msbut[MS_NBUTTS]; -+static RBUTT *typeRB; -+ -+static char output_command_ex[1024]; -+static int output_command_ex_flag = 0; -+ -+static int colorType; -+ -+static int w_pid; -+static int w_pstatus; -+ -+#define MSNAMWIDE 252 /* width of 'file name' entry window */ -+#define MAXFNLEN 256 /* max len of filename being entered */ -+static char DialogFileName[MAXFNLEN+100]; /* filename being entered */ -+static int curPos, stPos, enPos; /* filename textedit stuff */ -+ -+ -+static mgcsfxtab *get_mgcsfx PARM((int)); -+static void changeSuffix PARM((int)); -+ -+static int WriteMGCSFX PARM((FILE**,byte*,int,int,int, -+ byte*,byte*,byte*,int,int,char*, -+ int, int, char*)); -+void CreateMGCSFXW PARM((void)); -+void MGCSFXDialog PARM((int)); -+int MGCSFXCheckEvent PARM((XEvent *)); -+int MGCSFXSaveParams PARM((char *, int)); -+ -+static void drawMSD PARM((int,int,int,int)); -+static void clickMSD PARM((int,int)); -+static void doCmd PARM((int)); -+static int writeMGCSFX PARM((void)); -+ -+static void changeSuffix PARM((int)); -+static void redrawNamMSD PARM((void)); -+static void showFNamMSD PARM((void)); -+static int keyinMSD PARM((int)); -+ -+int getInputCom PARM((void)); -+int getOutputCom PARM((void)); -+/*--------------------------------------------------------------------------*/ -+ -+/***************************************************/ -+/* $B$I$l$rA*$s$@$+D4$Y$k!##0$O%3%^%s%I$rF~NO$9$k$b$N$H$9$k(B */ -+static mgcsfxtab *get_mgcsfx(ms_type) -+ int ms_type; -+{ -+ mgcsfxtab *magic; -+ int i; -+ -+ magic = NULL; -+ if(ms_type != 0){ -+ i = 1; -+ for(magic = mgcsfx_table; (magic && i<ms_type); magic = magic->next){i++;} -+ } -+ return magic; -+} -+ -+/***************************************************/ -+/* $B30It%3%^%s%I$r<B9T$7$F!"$=$l$K=PNO$9$k(B */ -+/* if OK return 0, else if ERROR return -1 */ -+static -+int WriteMGCSFX(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,file_name, -+ ms_type, file, comment) -+ FILE **fp; -+ byte *pic; -+ int ptype, w,h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+ char *file_name; -+ int ms_type; -+ int file; /* file descriptor */ -+ char *comment; -+{ -+ mgcsfxtab *magic; -+ -+ int fd[2]; -+ int pid; -+ int rv; -+ -+ WaitCursor(); -+ -+#ifdef USE_SIGCHLD -+ w_p_fail = 1; -+#endif -+ -+ magic = get_mgcsfx(ms_type); -+ if(ms_type != 0 && magic == NULL) return -1; -+ -+ if ((ms_type == 0 && output_command_ex_flag) || -+ (ms_type !=0 && magic != NULL && magic->output_command)){ -+ -+ /* Do the pipe/fork/exec here */ -+ if (pipe (fd) < 0){ -+ fprintf (stderr, "Can't pipe : %s\n", file_name); -+ return -1; -+ } -+ -+ if ((pid = vfork ()) < 0){ -+ fprintf (stderr, "Can't vfork : %s\n", file_name); -+ close (fd[0]); -+ close (fd[1]); -+ return -1; -+ } -+ -+ if (!pid){ -+ close(1); -+ dup(file); -+ close(file); -+ close(0); -+ dup(fd[0]); -+ close(2); -+ open("/dev/null", O_WRONLY); -+ close(fd[1]); -+ if(ms_type == 0){ -+ execl("/bin/sh", "/bin/sh", "-c", output_command_ex, 0); -+ }else{ -+ execl("/bin/sh", "/bin/sh", "-c", magic->output_command, 0); -+ } -+ _exit(127); -+ } -+ -+ close (fd[0]); -+ dup2(fd[1], file); -+ close (fd[1]); -+ -+ }else{ -+ return -1; -+ } -+ -+ -+ *fp = fdopen(file, "w"); -+ -+ /* sleep(1); Best way is wait for checking SIGCHLD, but it's feel waist.*/ -+ -+#ifdef USE_SIGCHLD -+ if(w_p_fail != 2){ -+#endif -+ if(ms_type == 0){ -+ rv = WritePBM(*fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle, -+ 1, comment); -+ }else{ -+ switch(magic -> output_image_type){ -+ case IT_PNM: -+ case IT_PPM: -+ case IT_PGM: -+ case IT_PBM: -+ case IT_PNM_RAW: -+ case IT_PPM_RAW: -+ case IT_PGM_RAW: -+ case IT_PBM_RAW: -+ rv = WritePBM(*fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle, -+ 1, comment); -+ break; -+ case IT_PNM_ASCII: -+ case IT_PPM_ASCII: -+ case IT_PGM_ASCII: -+ case IT_PBM_ASCII: -+ rv = WritePBM(*fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle, -+ 0, comment); -+ break; -+ case IT_GIF: -+ case IT_JPEG: -+ case IT_TIFF: -+ case IT_JFIF: -+ case IT_XBM: -+ case IT_XPM: -+ case IT_BMP: -+ case IT_SUNRAS: -+ case IT_IRIS: -+ case IT_XWD: -+ case IT_MAG: -+ case IT_MAKI: -+ case IT_PI: -+ case IT_PIC: -+ case IT_PIC2: -+ SetISTR(ISTR_WARNING, "Yet supported output image type (to filter input)"); -+ rv = -1; -+ break; -+ case IT_UNKNOWN: -+ SetISTR(ISTR_WARNING, "Unknown output image type (to filter input)"); -+ rv = -1; -+ break; -+#ifdef HAVE_MGCSFX_AUTO -+ case IT_AUTO: -+#endif -+ default: -+ SetISTR(ISTR_WARNING, "Error in output image type (to filter input)"); -+ rv = -1; -+ break; -+ } -+ } -+#ifdef USE_SIGCHLD -+ }else{ -+ rv = -1; -+ } -+#endif -+ -+#ifdef USE_SIGCHLD -+ if(w_p_fail != 2){ -+#endif -+ w_pid = pid; -+#ifdef USE_SIGCHLD -+ w_p_fail = 0; -+ }else{ -+ rv = -1; -+ } -+#endif -+ -+ output_command_ex_flag = 0; -+ -+ return rv; -+ -+ /* fclose(*fp); close in CloseOutFile in writeMGCSFX */ -+ /* return 0; ok */ -+ /* return -1; error */ -+} -+ -+/***************************************************/ -+void CreateMGCSFXW() -+{ -+ int y; -+ int type_num; -+ mgcsfxtab *entry; -+ -+ if (mgcsfx_setup_flag == 0) init_mgcsfx (); -+ -+ if(desc_width < strlen(MSD_IC_TITLE)) desc_width = strlen(MSD_IC_TITLE); -+ nitem_mgcsfx ++; -+ -+ MSWIDE = desc_width * CWIDE + RBSIZE + 36; /* 36 is start of RB button */ -+ MSHIGH = nitem_mgcsfx * (RBSIZE + MARGIN); -+ -+ if(MSWIDE < strlen(MSD_TITLE) + 20) MSWIDE = strlen(MSD_TITLE) + 20; -+ if(MSWIDE < strlen(MSD_RBTITLE) + 16) MSWIDE = strlen(MSD_RBTITLE) + 16; -+ if(MSWIDE < MSNAMWIDE + 10) MSWIDE = MSNAMWIDE + 10; -+ if(MSWIDE < BUTTW * 2 + 10) MSWIDE = BUTTW * 2 + 10; -+ -+ MSHIGH += 55 + LINEHIGH + 10 + BUTTH + 10; -+ -+ MSWIDE += 20; /* right side margin */ -+ MSHIGH += 10; /* RB buttun down side margin */ -+ -+ -+ mgcsfxW = CreateWindow("xv mgcsfx", "XVmgcsfx", NULL, -+ MSWIDE, MSHIGH, infofg, infobg, 0); -+ if (!mgcsfxW) FatalError("can't create mgcsfx window!"); -+ -+ XSelectInput(theDisp, mgcsfxW, -+ ExposureMask | ButtonPressMask | KeyPressMask); -+ -+ mgcsfxNameW = XCreateSimpleWindow(theDisp, mgcsfxW, -+ 10, MSHIGH-LINEHIGH-10-BUTTH-10-1, -+ (u_int) MSNAMWIDE+6, (u_int) LINEHIGH+5, -+ 1, infofg, infobg); -+ if (!mgcsfxNameW) FatalError("can't create mgcsfx name window"); -+ XSelectInput(theDisp, mgcsfxNameW, ExposureMask); -+ -+ /* Ok $B%\%?%s(B */ -+ BTCreate(&msbut[MS_BOK], mgcsfxW, -+ MSWIDE-BUTTW-10-BUTTW-10-1, MSHIGH-BUTTH-10-1, -+ BUTTW, BUTTH, -+ "Ok", infofg, infobg, hicol, locol); -+ /* Cancel $B%\%?%s(B*/ -+ BTCreate(&msbut[MS_BCANC], mgcsfxW, -+ MSWIDE-BUTTW-10-1, MSHIGH-BUTTH-10-1, -+ BUTTW, BUTTH, -+ "Cancel", infofg, infobg, hicol, locol); -+ -+ y = 55; -+ /* User should input command to exec external command */ -+ typeRB = RBCreate(NULL, mgcsfxW, 36, y, MSD_IC_TITLE, -+ infofg, infobg,hicol,locol); -+ y += (RBSIZE + MARGIN); /* 18 */ -+ -+ type_num = 1; -+ for (entry = mgcsfx_table; entry; entry = entry->next){ -+ RBCreate(typeRB, mgcsfxW, 36, y, entry->description, -+ infofg, infobg,hicol,locol); -+ y += (RBSIZE + MARGIN); /* 18 */ -+ if(entry->output_command == NULL){ -+ RBSetActive(typeRB, type_num, 0); /* if no command, off */ -+ } -+ type_num++; -+ } -+ -+ XMapSubwindows(theDisp, mgcsfxW); -+} -+ -+ -+/***************************************************/ -+void MGCSFXDialog(vis) -+ int vis; -+{ -+ if (vis) { -+ CenterMapWindow(mgcsfxW, msbut[MS_BOK].x + msbut[MS_BOK].w/2, -+ msbut[MS_BOK].y + msbut[MS_BOK].h/2, MSWIDE, MSHIGH); -+ } -+ else XUnmapWindow(theDisp, mgcsfxW); -+ mgcsfxUp = vis; -+} -+ -+ -+/***************************************************/ -+int MGCSFXCheckEvent(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 (!mgcsfxUp) 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 == mgcsfxW) drawMSD(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 == mgcsfxW) clickMSD(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'; -+ -+ if (e->window == mgcsfxW) { -+ if (stlen) { -+ keyinMSD(buf[0]); -+ } -+ } -+ else rv = 0; -+ } -+ else rv = 0; -+ -+ if (rv == 0 && (xev->type == ButtonPress || xev->type == KeyPress)) { -+ XBell(theDisp, 50); -+ rv = 1; /* eat it */ -+ } -+ -+ return (rv); -+} -+ -+ -+/***************************************************/ -+int MGCSFXSaveParams(fname, col) -+ char *fname; -+ int col; -+{ -+ colorType = col; -+ strcpy(DialogFileName, GetDirFName()); -+ return (0); -+} -+ -+/***************************************************/ -+/* $B%@%$%"%m%0$rI=<($9$k$H$-$N=hM}(B */ -+static void drawMSD(x,y,w,h) -+ int x,y,w,h; -+{ -+ 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 < MS_NBUTTS; i++) BTRedraw(&msbut[i]); -+ -+ ULineString(mgcsfxW, typeRB->x-16, typeRB->y-3-DESCENT, -+ MSD_RBTITLE); -+ RBRedraw(typeRB, -1); -+ -+ DrawString(mgcsfxW, 20, 29, MSD_TITLE); -+ -+ XSetClipMask(theDisp, theGC, None); -+ -+ showFNamMSD(); -+} -+ -+/***************************************************/ -+/* $B%@%$%"%m%0$r%/%j%C%/$7$?$H$-$N=hM}(B */ -+static void clickMSD(x,y) -+ int x,y; -+{ -+ int i; -+ BUTT *bp; -+ -+ /* check BUTTs */ -+ -+ /* check the RBUTTS first, since they don't DO anything */ -+ if ((i = RBClick(typeRB, x,y)) >= 0) { /* $BA*Br(B(type)$B%\%?%s$N=hM}(B */ -+ (void) RBTrack(typeRB, i); /* $BA*Br(B(type)$B%\%?%s$r2!$7$?$H$-(B */ -+ changeSuffix(i); -+ return; -+ } -+ -+ for (i = 0; i < MS_NBUTTS; i++) { /* Ok,Cancel $B%\%?%s$N=hM}(B */ -+ bp = &msbut[i]; -+ if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) -+ break; -+ } -+ if (i < MS_NBUTTS) /* found one */ /* Ok,Cancel $B%\%?%s$r2!$7$?$H$-(B */ -+ if (BTTrack(bp)) doCmd(i); -+} -+ -+/***************************************************/ -+/* $B%\%?%s(B(Ok, Cancel) $B$N=hM}(B */ -+static void doCmd(cmd) -+ int cmd; -+{ -+ int rv; -+ -+ switch (cmd) { -+ case MS_BOK: /* Ok button */ { -+ char *fullname; -+ -+ rv = writeMGCSFX(); /* Save with filter(MGCSFX) */ -+ MGCSFXDialog(0); -+ -+ fullname = GetDirFullName(); -+ if (!ISPIPE(fullname[0])) { -+ XVCreatedFile(fullname); -+ if(!rv) StickInCtrlList(0); -+ } -+ } -+ break; -+ case MS_BCANC: /* Cancel button */ -+ DialogFileName[0] = '\0'; -+ curPos = stPos = enPos = 0; -+ MGCSFXDialog(0); -+ break; -+ default: -+ break; -+ } -+} -+ -+/*******************************************/ -+static int writeMGCSFX() -+{ -+ int rv, type; -+ int ptype, w, h, pfree, nc; -+ byte *inpix, *rmap, *gmap, *bmap; -+ -+ FILE *fp = NULL; -+ int file; -+ char *fullname; -+ -+ rv = -1; -+ type = RBWhich(typeRB); -+ -+ SetDirFName(DialogFileName); /* change filename in dir dialog */ -+ fullname = GetDirFullName(); -+ -+ if(type == 0){ -+ if(getOutputCom() == 0) return rv; -+ } -+ -+ file = OpenOutFileDesc(fullname); -+ if(file < 0) return rv; -+ -+ WaitCursor(); -+ inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap); -+ -+ rv = WriteMGCSFX(&fp, inpix, ptype, w, h, -+ rmap, gmap, bmap, nc, colorType, fullname, -+ type, file, picComments); -+ -+ SetCursors(-1); -+ -+ if (CloseOutFile(fp, fullname, rv) == 0) DirBox(0); -+ -+ WaitCursor(); -+#ifdef USE_SIGCHLD -+ if(w_p_fail == 0){ -+#endif -+ while(wait(&w_pstatus) != w_pid); /* if( *((char *)&w_pstatus) != 0 ) ; */ -+#ifdef USE_SIGCHLD -+ }else{ -+ w_p_fail = 0; -+ } -+#endif -+ w_pid = 0; -+ w_pstatus = 0; -+ -+ if (pfree) free(inpix); -+ return rv; -+} -+ -+ -+/***************************************/ -+static void changeSuffix(ms_type) -+ int ms_type; -+{ -+ /* see if there's a common suffix at the end of the DialogFileName. -+ if there is, remember what case it was (all caps or all lower), lop -+ it off, and replace it with a new appropriate suffix, in the -+ same case */ -+ -+ int allcaps; -+ char *suffix, *sp, *dp, lowsuf[512]; -+ mgcsfxtab *magic; -+ -+ /* find the last '.' in the DialogFileName */ -+ suffix = (char *) rindex(DialogFileName, '.'); -+ if (!suffix) return; -+ suffix++; /* point to first letter of the suffix */ -+ -+ /* check for all-caposity */ -+ for (sp = suffix, allcaps=1; *sp; sp++) -+ if (islower(*sp)) allcaps = 0; -+ -+ /* copy the suffix into an all-lower-case buffer */ -+ for (sp=suffix, dp=lowsuf; *sp; sp++, dp++) { -+ *dp = (isupper(*sp)) ? tolower(*sp) : *sp; -+ } -+ *dp = '\0'; -+ -+ -+ magic = get_mgcsfx(ms_type); -+ if(magic != NULL && magic->suffix != NULL){ -+ strcpy(lowsuf,(magic->suffix)+1); -+ -+ if (allcaps) { /* upper-caseify lowsuf */ -+ for (sp=lowsuf; *sp; sp++) -+ *sp = (islower(*sp)) ? toupper(*sp) : *sp; -+ } -+ -+ /* one other case: if the original suffix started with a single -+ capital letter, make the new suffix start with a single cap */ -+ if (isupper(suffix[0])) lowsuf[0] = toupper(lowsuf[0]); -+ -+ strcpy(suffix, lowsuf); /* tack onto DialogFileName */ -+ showFNamMSD(); -+ } -+} -+ -+/***************************************************/ -+/* $B%@%$%"%m%0Fb$K%U%!%$%k%M!<%`$rI=<($9$k$H$-$N=hM}(B ($B2<@A$1(B)*/ -+static void redrawNamMSD() -+{ -+ int cpos; -+ -+ /* draw substring DialogFileName[stPos:enPos] and cursor */ -+ -+ Draw3dRect(mgcsfxNameW, 0, 0, (u_int) MSNAMWIDE+5, (u_int) LINEHIGH+4, R3D_IN, 2, -+ hicol, locol, infobg); -+ -+ XSetForeground(theDisp, theGC, infofg); -+ -+ if (stPos>0) { /* draw a "there's more over here" doowah */ -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 0,0,0,LINEHIGH+5); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 1,0,1,LINEHIGH+5); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 2,0,2,LINEHIGH+5); -+ } -+ -+ if ((size_t) enPos < strlen(DialogFileName)) { -+ /* draw a "there's more over here" doowah */ -+ XDrawLine(theDisp, mgcsfxNameW, theGC, MSNAMWIDE+5,0,MSNAMWIDE+5,LINEHIGH+5); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, MSNAMWIDE+4,0,MSNAMWIDE+4,LINEHIGH+5); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, MSNAMWIDE+3,0,MSNAMWIDE+3,LINEHIGH+5); -+ } -+ -+ XDrawString(theDisp, mgcsfxNameW, theGC,3,ASCENT+3,DialogFileName+stPos, enPos-stPos); -+ -+ cpos = XTextWidth(mfinfo, &DialogFileName[stPos], curPos-stPos); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 3+cpos, 2, 3+cpos, 2+CHIGH+1); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 3+cpos, 2+CHIGH+1, 5+cpos, 2+CHIGH+3); -+ XDrawLine(theDisp, mgcsfxNameW, theGC, 3+cpos, 2+CHIGH+1, 1+cpos, 2+CHIGH+3); -+} -+ -+/***************************************************/ -+/* $B%@%$%"%m%0Fb$K%U%!%$%k%M!<%`$rI=<($9$k(B */ -+static void showFNamMSD() -+{ -+ int len; -+ -+ len = strlen(DialogFileName); -+ -+ if (curPos<stPos) stPos = curPos; -+ if (curPos>enPos) enPos = curPos; -+ -+ if (stPos>len) stPos = (len>0) ? len-1 : 0; -+ if (enPos>len) enPos = (len>0) ? len-1 : 0; -+ -+ /* while substring is shorter than window, inc enPos */ -+ -+ while (XTextWidth(mfinfo, &DialogFileName[stPos], enPos-stPos) < MSNAMWIDE -+ && enPos<len) { enPos++; } -+ -+ /* while substring is longer than window, dec enpos, unless enpos==curpos, -+ in which case, inc stpos */ -+ -+ while (XTextWidth(mfinfo, &DialogFileName[stPos], enPos-stPos) > MSNAMWIDE) { -+ if (enPos != curPos) enPos--; -+ else stPos++; -+ } -+ -+ -+ if (ctrlColor) XClearArea(theDisp, mgcsfxNameW, 2,2, (u_int) MSNAMWIDE+5-3, -+ (u_int) LINEHIGH+4-3, False); -+ else XClearWindow(theDisp, mgcsfxNameW); -+ -+ redrawNamMSD(); -+ BTSetActive(&msbut[MS_BOK], strlen(DialogFileName)!=0); -+} -+ -+/***************************************************/ -+/* $B%-!<F~NO$7$?$H$-$N=hM}(B */ -+static int keyinMSD(c) -+ int c; -+{ -+ /* got keypress in dirW. stick on end of DialogFileName */ -+ int len; -+ -+ len = strlen(DialogFileName); -+ -+ if (c>=' ' && c<'\177') { /* printable characters */ -+ /* note: only allow 'piped commands' in savemode... */ -+ -+ /* only allow spaces in 'piped commands', not filenames */ -+ if (c==' ' && (!ISPIPE(DialogFileName[0]) || curPos==0)) return (-1); -+ -+ /* only allow vertbars in 'piped commands', not filenames */ -+ if (c=='|' && curPos!=0 && !ISPIPE(DialogFileName[0])) return(-1); -+ -+ if (len >= MAXFNLEN-1) return(-1); /* max length of string */ -+ xvbcopy(&DialogFileName[curPos], &DialogFileName[curPos+1], (size_t) (len-curPos+1)); -+ DialogFileName[curPos]=c; curPos++; -+ } -+ -+ else if (c=='\010' || c=='\177') { /* BS or DEL */ -+ if (curPos==0) return(-1); /* at beginning of str */ -+ xvbcopy(&DialogFileName[curPos], &DialogFileName[curPos-1], (size_t) (len-curPos+1)); -+ curPos--; -+ } -+ -+ else if (c=='\025') { /* ^U: clear entire line */ -+ DialogFileName[0] = '\0'; -+ curPos = 0; -+ } -+ -+ else if (c=='\013') { /* ^K: clear to end of line */ -+ DialogFileName[curPos] = '\0'; -+ } -+ -+ else if (c=='\001') { /* ^A: move to beginning */ -+ curPos = 0; -+ } -+ -+ else if (c=='\005') { /* ^E: move to end */ -+ curPos = len; -+ } -+ -+ else if (c=='\004') { /* ^D: delete character at curPos */ -+ if (curPos==len) return(-1); -+ xvbcopy(&DialogFileName[curPos+1], &DialogFileName[curPos], (size_t) (len-curPos)); -+ } -+ -+ else if (c=='\002') { /* ^B: move backwards char */ -+ if (curPos==0) return(-1); -+ curPos--; -+ } -+ -+ else if (c=='\006') { /* ^F: move forwards char */ -+ if (curPos==len) return(-1); -+ curPos++; -+ } -+ -+ else if (c=='\012' || c=='\015') { /* CR(\r) or LF(\n) */ -+ FakeButtonPress(&msbut[MS_BOK]); -+ } -+ -+ else if (c=='\033') { /* ESC = Cancel */ -+ FakeButtonPress(&msbut[MS_BCANC]); -+ } -+ -+ else if (c=='\011') { /* tab = filename expansion */ -+ if (1 /* !autoComplete() */) XBell(theDisp, 0); -+ else { -+ curPos = strlen(DialogFileName); -+ } -+ } -+ -+ else return(-1); /* unhandled character */ -+ -+ showFNamMSD(); -+ -+ return(0); -+} -+ -+ -+/*******************************************/ -+int getInputCom() -+{ -+ static char *labels[] = { "\nOk", "\033Cancel" }; -+ int i; -+ -+ strcpy(input_command_ex, MGCSFX_DEFAULT_INPUT_COMMAND); -+ i = GetStrPopUp("Input External Command (Input is PNM):", labels, 2, -+ input_command_ex, 1024, "",0); -+ if (i == 0 && strlen(input_command_ex) != 0){ -+ input_command_ex_flag = 1; -+ return 1; -+ }else{ -+ input_command_ex_flag = 0; -+ return 0; -+ } -+} -+ -+int getOutputCom() -+{ -+ static char *labels[] = { "\nOk", "\033Cancel" }; -+ int i; -+ -+ strcpy(output_command_ex, MGCSFX_DEFAULT_OUTPUT_COMMAND); -+ i = GetStrPopUp("Input External Command (Output is PNM_RAW):", labels, 2, -+ output_command_ex, 1024, "",0); -+ if (i == 0 && strlen(output_command_ex) != 0){ -+ output_command_ex_flag = 1; -+ return 1; -+ }else{ -+ output_command_ex_flag = 0; -+ return 0; -+ } -+} -+ -+#ifdef SVR4 -+Sigfunc * -+xv_signal(signo, func) -+ int signo; -+ Sigfunc *func; -+{ -+ struct sigaction act, oact; -+ -+ act.sa_handler = func; -+ sigemptyset(&act.sa_mask); -+ act.sa_flags = 0; -+ act.sa_flags |= SA_RESTART; -+ -+ if (sigaction(signo, &act, &oact) < 0) -+ return SIG_ERR; -+ -+ return oact.sa_handler; -+} -+#endif -+ -+#endif /* HAVE_MGCSFX */ -diff -ruN xv-3.10a-bugfixes/xvmisc.c xv-3.10a-enhancements/xvmisc.c ---- xv-3.10a-bugfixes/xvmisc.c 2005-03-20 22:47:06.000000000 -0800 -+++ xv-3.10a-enhancements/xvmisc.c 2005-04-17 14:45:28.000000000 -0700 -@@ -103,10 +103,18 @@ - if (!usesize || !(i&WidthValue)) w = defw; - if (!usesize || !(i&HeightValue)) h = defh; - -- hints.flags |= USSize; -+ hints.flags |= USSize | PWinGravity; - -- if (i&XValue && i&XNegative) x = dispWIDE - w - abs(x); -- if (i&YValue && i&YNegative) y = dispHIGH - h - abs(y); -+ hints.win_gravity = NorthWestGravity; -+ if (i&XValue && i&XNegative) { -+ hints.win_gravity = NorthEastGravity; -+ x = dispWIDE - (w + 2 * bwidth) - abs(x); -+ } -+ if (i&YValue && i&YNegative) { -+ hints.win_gravity = (hints.win_gravity == NorthWestGravity) ? -+ SouthWestGravity : SouthEastGravity; -+ y = dispHIGH - (h + 2 * bwidth) - abs(y); -+ } - - - #define VROOT_TRANS -@@ -142,20 +150,19 @@ - if (!win) return(win); /* leave immediately if couldn't create */ - - -- XSetStandardProperties(theDisp, win, name, name, None, NULL, 0, &hints); -- - xwmh.input = True; - xwmh.flags = InputHint; - if (iconPix) { xwmh.icon_pixmap = iconPix; xwmh.flags |= IconPixmapHint; } -- XSetWMHints(theDisp, win, &xwmh); - - if (clname && strlen(clname)) { - classh.res_name = "xv"; - classh.res_class = clname; -- XSetClassHint(theDisp, win, &classh); - StoreDeleteWindowProp(win); - } - -+ XmbSetWMProperties(theDisp, win, name, name, NULL, 0, &hints, &xwmh, -+ clname ? &classh : NULL); -+ - return(win); - } - -@@ -232,28 +239,28 @@ - int i = CK_NONE; - - if (ks==XK_Up || ks==XK_KP_Up || -- ks==XK_KP_8 || ks==XK_F28) i=CK_UP; -+ ks==XK_F28) i=CK_UP; - - else if (ks==XK_Down || ks==XK_KP_Down || -- ks==XK_KP_2 || ks==XK_F34) i=CK_DOWN; -+ ks==XK_F34) i=CK_DOWN; - - else if (ks==XK_Left || ks==XK_KP_Left || -- ks==XK_KP_4 || ks==XK_F30) i=CK_LEFT; -+ ks==XK_F30) i=CK_LEFT; - - else if (ks==XK_Right || ks==XK_KP_Right || -- ks==XK_KP_6 || ks==XK_F32) i=CK_RIGHT; -+ ks==XK_F32) i=CK_RIGHT; - - else if (ks==XK_Prior || ks==XK_KP_Prior || -- ks==XK_KP_9 || ks==XK_F29) i=CK_PAGEUP; -+ ks==XK_F29) i=CK_PAGEUP; - - else if (ks==XK_Next || ks==XK_KP_Next || -- ks==XK_KP_3 || ks==XK_F35) i=CK_PAGEDOWN; -+ ks==XK_F35) i=CK_PAGEDOWN; - - else if (ks==XK_Home || ks==XK_KP_Home || -- ks==XK_KP_7 || ks==XK_F27) i=CK_HOME; -+ ks==XK_F27) i=CK_HOME; - - else if (ks==XK_End || ks==XK_KP_End || -- ks==XK_KP_1 || ks==XK_F33) i=CK_END; -+ ks==XK_F33) i=CK_END; - - else i = CK_NONE; - -@@ -503,6 +510,11 @@ - as we have to keep the alloc'd colors around, but we don't want anything - else to stay */ - -+#ifdef AUTO_EXPAND -+ chdir(initdir); -+ Vdsettle(); -+#endif -+ - if (!theDisp) exit(i); /* called before connection opened */ - - if (useroot && i==0) { /* save the root info */ -@@ -526,6 +538,26 @@ - if (tiffW) XDestroyWindow(theDisp, tiffW); - #endif - -+#ifdef HAVE_PNG -+ if (pngW) XDestroyWindow(theDisp, pngW); -+#endif -+ -+#ifdef HAVE_PCD -+ if (pcdW) XDestroyWindow(theDisp, pcdW); -+#endif -+ -+#ifdef HAVE_PIC2 -+ if (pic2W) XDestroyWindow(theDisp, pic2W); -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (mgcsfxW) XDestroyWindow(theDisp, mgcsfxW); -+#endif -+ -+#ifdef HAVE_PNG -+ if (pngW) XDestroyWindow(theDisp, pngW); -+#endif -+ - /* if NOT using stdcmap for images, free stdcmap */ - if (colorMapMode != CM_STDCMAP) { - int j; -@@ -722,6 +754,26 @@ - #ifdef HAVE_TIFF - if (tiffW) XDefineCursor(theDisp, tiffW, otherc); - #endif -+ -+#ifdef HAVE_PNG -+ if (pngW) XDefineCursor(theDisp, pngW, otherc); -+#endif -+ -+#ifdef HAVE_PNG -+ if (pngW) XDefineCursor(theDisp, pngW, otherc); -+#endif -+ -+#ifdef HAVE_PCD -+ if (pcdW) XDefineCursor(theDisp, pcdW, otherc); -+#endif -+ -+#ifdef HAVE_PIC2 -+ if (pic2W) XDefineCursor(theDisp, pic2W, otherc); -+#endif -+ -+#ifdef HAVE_MGCSFX -+ if (mgcsfxW) XDefineCursor(theDisp, mgcsfxW, otherc); -+#endif - } - - -@@ -921,7 +973,7 @@ - void XVCreatedFile(fullname) - char *fullname; - { -- /* called whenever a file has been deleted. Updates browser & dir windows, -+ /* called whenever a file has been created. Updates browser & dir windows, - if necessary */ - - BRCreatedFile(fullname); -@@ -1006,6 +1058,9 @@ - ((rv=(char *) getenv("cwd"))==NULL)) rv = "./"; - strcpy(buf, rv); - } -+#ifdef AUTO_EXPAND -+ Vdtodir(buf); -+#endif - } - - -diff -ruN xv-3.10a-bugfixes/xvml.c xv-3.10a-enhancements/xvml.c ---- xv-3.10a-bugfixes/xvml.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvml.c 2005-04-17 22:57:34.000000000 -0700 -@@ -0,0 +1,989 @@ -+/* -+ * xvml.c - makes text item structure for multi-lingual textviewer. -+ * -+ * Entry Points: -+ * struct ml_text *ml_draw_text() -+ * struct context *ml_create_context() -+ * int ml_set_charsets() -+ * void get_monofont_size() -+ */ -+ -+#include "xv.h" -+#include <X11/Xresource.h> -+ -+#ifdef TV_MULTILINGUAL /* whole this file. */ -+ -+#include "xvml.h" -+#define HAVE_STRDUP 1 -+#define USE_MULE_EXTENSION -+ -+#ifndef __STDC__ -+#define CHAR char -+#else -+#define CHAR int -+#endif -+ -+#define CODE_SI 0x0e /* LS0 */ -+#define CODE_SO 0x0f /* LS1 */ -+#define CODE_SS2 ((unsigned char) 0x8e) -+#define CODE_SS3 ((unsigned char) 0x8f) -+ -+int ml_tab_width = 64; /* dots */ -+ -+struct charset { -+ int bpc; /* bytes per char */ -+ int noc; /* number of chars */ -+ char designator; -+ char *registry; -+ int bit7; -+ -+ int loaded; -+ char *fontname; -+ -+ XFontStruct *fs; -+} charset[] = { -+ { 1, 94, 'B', "iso8859-1", 0, 0, NULL, NULL}, -+ { 1, 96, 'A', "iso8859-1", 1, 0, NULL, NULL}, -+ { 1, 94, '0', "omron_udc_zh-0", 0, 0, NULL, NULL}, -+ { 1, 94, '2', "mulearabic-0", 0, 0, NULL, NULL}, -+ { 1, 94, '3', "mulearabic-1", 0, 0, NULL, NULL}, -+ { 1, 94, '4', "mulearabic-2", 0, 0, NULL, NULL}, -+ { 1, 94, 'J', "jisx0201.1976-0", 0, 0, NULL, NULL}, -+ { 1, 96, '0', "muleipa-1", 1, 0, NULL, NULL}, -+ { 1, 96, '1', "viscii1.1-1", 1, 0, NULL, NULL}, -+ { 1, 96, '2', "viscii1.1-1", 1, 0, NULL, NULL}, -+ { 1, 96, 'B', "iso8859-2", 1, 0, NULL, NULL}, -+ { 1, 96, 'C', "iso8859-3", 1, 0, NULL, NULL}, -+ { 1, 96, 'D', "iso8859-4", 1, 0, NULL, NULL}, -+ { 1, 96, 'T', "tis620.1986-0", 1, 0, NULL, NULL}, -+ { 1, 96, 'F', "iso8859-7", 1, 0, NULL, NULL}, -+ { 1, 96, 'G', "iso8859-6", 1, 0, NULL, NULL}, -+ { 1, 96, 'H', "iso8859-8", 1, 0, NULL, NULL}, -+ { 1, 94, 'I', "jisx0201.1976-0", 1, 0, NULL, NULL}, -+ { 1, 96, 'L', "iso8859-5", 1, 0, NULL, NULL}, -+ { 1, 96, 'M', "iso8859-9", 1, 0, NULL, NULL}, -+ { 2, 94, '2', "ethio-0", 0, 0, NULL, NULL}, -+ { 2, 94, '@', "jisx0208.1978", 0, 0, NULL, NULL}, -+ { 2, 94, 'A', "gb2312.1980-0", 0, 0, NULL, NULL}, -+ { 2, 94, 'B', "jisx0208.1983-0", 0, 0, NULL, NULL}, -+ { 2, 94, 'C', "ksc5601.1987-0", 0, 0, NULL, NULL}, -+ { 2, 94, 'D', "jisx0212.1990-0", 0, 0, NULL, NULL}, -+ { 2, 94, '0', "big5.eten-0", 0, 0, NULL, NULL}, -+ { 2, 94, '1', "big5.hku-0", 0, 0, NULL, NULL}, -+ /* End Mark */ -+ { 0, 0, 0, NULL, 0, 0, NULL, NULL}, -+}; -+#define NR_CHARSETS ((int) (sizeof charset / sizeof charset[0])) -+ -+static struct charset *ascii = NULL; -+ -+struct context { -+ struct charset *g[4]; -+ struct charset **gl, **gr; -+ struct charset **ss; -+ int eol; /* 0: \n, 1: \r\n, 2: \r, 3: any */ -+ int valid[4]; /* g[i] is valid? */ -+ int short_form; /* allow shortened designator sequence? */ -+ int lock_shift; /* allow locking shift? */ -+ -+ unsigned char *cbuf, *cbp; -+ struct ml_text text; -+ int line; -+ int delta; -+ int toolong; -+ -+ Display *dpy; -+ Screen *scr; -+ Window root_win; -+}; -+#define DPY (context->dpy) -+#define SCR (context->scr) -+#define ROOT_WIN (context->root_win) -+ -+static unsigned char *escape_sequence PARM((unsigned char *)); -+static unsigned char *designator_sequence PARM((unsigned char *)); -+static void locking_shift PARM((unsigned CHAR)); -+static void single_shift PARM((unsigned CHAR)); -+static void put_unknown_char PARM((unsigned CHAR)); -+static struct charset *search_charset PARM((int, int, int)); -+static void pack_string PARM((struct charset *, -+ unsigned char *, int)); -+static void init_xrm PARM((void)); -+static void init_xrm_fonts PARM((void)); -+static void init_xrm_tab PARM((void)); -+#ifndef HAVE_STRDUP -+static char *strdup PARM((char *)); -+#endif -+ -+static char *default_fonts[] = { /* default for xrm_fonts */ -+ "-sony-fixed-medium-r-normal--16-*-*-*-*-*-iso8859-1", -+ "-jis-fixed-medium-r-normal--16-*-*-*-*-*-jisx0208.1983-0", -+}; -+static int xrm_nfonts; -+static char **xrm_fonts; -+ -+static struct context *context; /* current context */ -+ -+struct ml_text *ml_draw_text(ctx, string, len) -+ struct context *ctx; -+ char *string; -+ int len; -+{ -+ unsigned char *str = (unsigned char *) string; -+ unsigned char *estr = str + len; -+ -+ context = ctx; -+ -+ if(ascii == NULL){ -+ fputs("ml_draw_text: call ml_set_charsets, first.\n", stderr); -+ return NULL; -+ } -+ -+ if(!str) -+ return &context->text; -+ -+ WaitCursor(); -+ -+ if (context->text.maxlines != 0) { -+ struct ml_text *tp = &context->text; -+ struct ml_line *lp; -+ int i; -+ for (i = tp->nlines, lp = tp->lines; i > 0; i--, lp++) { -+ if (lp->maxitems != 0) -+ free((char *) lp->items); -+ } -+ free((char *) tp->lines); -+ tp->maxlines = tp->nlines = 0; -+ } -+ if (context->cbuf != NULL) -+ free((char *) context->cbuf); -+ context->cbp = (unsigned char *) malloc((size_t) len * 8);/* all \xxx */ -+ context->cbuf = context->cbp; -+ context->line = 0; -+ context->delta = 0; -+ context->ss = NULL; -+ -+ while(str < estr){ -+ if((*str & 0x80) == 0){ /* left half */ -+ struct charset *cs = context->ss ? *context->ss : *context->gl; -+ unsigned char min_char, max_char; -+ if (cs != NULL) { -+ if(cs->noc == 94){ -+ min_char = 0x21; -+ max_char = 0x7e; -+ }else{ -+ min_char = 0x20; -+ max_char = 0x7f; -+ } -+ } -+ -+ if (cs == NULL) -+ put_unknown_char(*str++); -+ else if(*str < min_char || *str > max_char){ /* C1 */ -+ switch(*str){ -+ case ' ': -+ { -+ unsigned char *p = str + 1; -+ while (*p == ' ' && p < estr) -+ p++; -+ pack_string(ascii, str, (int) (p - str)); -+ str = p; -+ } -+ break; -+ -+ case '\t': -+ pack_string(ascii, str++, 0); -+ break; -+ -+ case '\n': -+ switch (context->eol) { -+ case 0: /* unix type eol */ -+ pack_string(ascii, str, 0); -+ WaitCursor(); -+ str++; -+ break; -+ case 1: /* dos type eol */ -+ case 2: /* mac type eol */ -+ put_unknown_char('\n'); -+ str++; -+ break; -+ case 3: /* any type eol */ -+ pack_string(ascii, str++, 0); -+ while (*str == '\n' || *str == '\r') -+ str++; -+ WaitCursor(); -+ break; -+ } -+ break; -+ -+ case '\r': -+ switch (context->eol) { -+ case 0: -+ put_unknown_char('\r'); -+ str++; -+ break; -+ case 1: -+ str++; -+ if (*str == '\n') -+ pack_string(ascii, str++, 0); -+ else -+ put_unknown_char('\r'); -+ break; -+ case 2: -+ pack_string(ascii, str, 0); -+ WaitCursor(); -+ str++; -+ break; -+ case 3: -+ pack_string(ascii, str++, 0); -+ while (*str == '\n' || *str == '\r') -+ str++; -+ WaitCursor(); -+ break; -+ } -+ break; -+ -+ case '\033': -+ { -+ unsigned char *p; -+ str++; -+ if((p = escape_sequence(str)) == str) -+ put_unknown_char('\033'); -+ else -+ str = p; -+ } -+ break; -+ -+ case CODE_SI: -+ case CODE_SO: -+ if (!context->lock_shift) -+ put_unknown_char((unsigned int) *str++); -+ else -+ locking_shift((unsigned int) *str++); -+ break; -+ -+ default: -+ put_unknown_char((unsigned int) *str++); -+ } -+ }else{ /* GL */ -+ if (context->ss != NULL) { -+ pack_string(cs, str, 1); -+ str += cs->bpc; -+ context->ss = NULL; -+ } else { -+ int n; -+ -+ if (cs->bpc == 1) { -+ unsigned char *p = str; -+ for (n = 0; p < estr; n++) { -+ if (*p < min_char || *p > max_char) -+ break; -+ p++; -+ } -+ pack_string(cs, str, n); -+ str = p; -+ } else { -+ unsigned char *p = str; -+ for (n = 0; p < estr - 1; n++) { -+ if (*p < min_char || *p > max_char || -+ *(p + 1) < min_char || *(p + 1) > max_char) -+ break; -+ p += 2; -+ } -+ if (n > 0) -+ pack_string(cs, str, n); -+ else -+ put_unknown_char(*p++); -+ str = p; -+ } -+ } -+ } -+ }else{ /* right half */ -+ struct charset *cs = context->ss ? *context->ss : *context->gr; -+ unsigned char min_char, max_char; -+ if (cs != NULL) { -+ if(cs->noc == 94){ -+ min_char = 0xa1; -+ max_char = 0xfe; -+ }else{ -+ min_char = 0xa0; -+ max_char = 0xff; -+ } -+ } -+ -+ if (cs == NULL) -+ put_unknown_char(*str++); -+ else if(*str < min_char || *str > max_char){ /* C2 */ -+ unsigned char c = *str++; -+ switch(c){ -+ case CODE_SS2: -+ case CODE_SS3: -+ single_shift((unsigned CHAR) c); -+ break; -+ default: -+ put_unknown_char(c); -+ } -+ }else{ /* GR */ -+ if (context->ss != NULL) { -+ pack_string(cs, str, 1); -+ str += cs->bpc; -+ context->ss = NULL; -+ } else { -+ int n; -+ -+ if (cs->bpc == 1) { -+ unsigned char *p = str; -+ for (n = 0; p < estr; n++) { -+ if (*p < min_char || *p > max_char) -+ break; -+ p++; -+ } -+ pack_string(cs, str, n); -+ str = p; -+ } else { -+ unsigned char *p = str; -+ for (n = 0; p < estr - 1; n++) { -+ if (*p < min_char || *p > max_char || -+ *(p + 1) < min_char || *(p + 1) > max_char) -+ break; -+ p += 2; -+ } -+ if (n > 0) -+ pack_string(cs, str, n); -+ else -+ put_unknown_char(*p++); -+ str = p; -+ } -+ } -+ } -+ } -+ } -+ -+ { -+ struct ml_text *tp = &context->text; -+ struct ml_line *lp; -+ int i; -+ -+ tp->width = 0; -+ tp->height = 0; -+ for (lp = tp->lines, i = tp->nlines; i > 0; lp++, i--) { -+ if (lp->nitems == 0) { -+ lp->ascent = ascii->fs->ascent; -+ lp->descent = ascii->fs->descent; -+ } -+ if (tp->width < lp->width) -+ tp->width = lp->width; -+ tp->height += lp->ascent + lp->descent; -+ } -+ } -+ -+ SetCursors(-1); -+ return &context->text; -+} -+ -+static unsigned char *escape_sequence(str) -+ unsigned char *str; -+{ -+ unsigned char *p; -+ switch(*str){ -+ case '$': -+ case '(': case ')': case '*': case '+': -+ case '-': case '.': case '/': case ',': -+ if((p = designator_sequence(str)) == NULL) -+ return str; -+ return p; -+ case 'n': case 'o': case '~': case '}': case '|': -+ if (!context->lock_shift) -+ return str; -+ locking_shift(*str); -+ return str + 1; -+ case 'N': case 'O': -+ single_shift(*str); -+ return str + 1; -+ } -+ return str; -+ -+} -+ -+static unsigned char *designator_sequence(str) -+ unsigned char *str; -+{ -+ unsigned char *p = str; -+ int noc, bpc, n_g, shortened; -+ unsigned char des; -+ struct charset *cs; -+ -+ if(*p == '$'){ -+ bpc = 2; -+ p++; -+ }else -+ bpc = 1; -+ -+ switch(*p++){ -+ case '(': noc = 94; n_g = 0; des = *p++; shortened = 0; break; -+ case ')': noc = 94; n_g = 1; des = *p++; shortened = 0; break; -+ case '*': noc = 94; n_g = 2; des = *p++; shortened = 0; break; -+ case '+': noc = 94; n_g = 3; des = *p++; shortened = 0; break; -+#ifdef USE_MULE_EXTENSION -+ case ',': noc = 96; n_g = 0; des = *p++; shortened = 0; break; -+#endif -+ case '-': noc = 96; n_g = 1; des = *p++; shortened = 0; break; -+ case '.': noc = 96; n_g = 2; des = *p++; shortened = 0; break; -+ case '/': noc = 96; n_g = 3; des = *p++; shortened = 0; break; -+ case '@': noc = 94; n_g = 0; des = 'B'; shortened = 0; break; -+ case 'A': noc = 94; n_g = 0; des = 'A'; shortened = 1; break; -+ case 'B': noc = 94; n_g = 0; des = 'B'; shortened = 1; break; -+ default: return NULL; -+ } -+ if (!context->short_form && shortened) -+ return NULL; -+ -+ if((cs = search_charset(bpc, noc, des)) == NULL){ -+ if(DEBUG){ -+ fprintf(stderr, "designator_sequence: (%d,%d,%c) not found.\n", -+ bpc, noc, des); -+ } -+ return NULL; -+ } -+ if (!context->valid[n_g]) -+ return NULL; -+ context->g[n_g] = cs; -+ if(DEBUG){ -+ fprintf(stderr, -+ "designator_sequence: G%d is `%s'.\n", n_g, cs->registry); -+ } -+ return p; -+} -+ -+static void locking_shift(c) -+ unsigned CHAR c; -+{ -+ switch((unsigned char) c){ -+ case CODE_SI: context->gl = &context->g[0]; break; -+ case CODE_SO: context->gl = &context->g[1]; break; -+ case 'n': context->gl = &context->g[2]; break; -+ case 'o': context->gl = &context->g[3]; break; -+ case '~': context->gr = &context->g[1]; break; -+ case '}': context->gr = &context->g[2]; break; -+ case '|': context->gr = &context->g[3]; break; -+ } -+ if(DEBUG){ -+ fprintf(stderr, "locking_shift: (%d,%d).\n", -+ (int)(context->gl - context->g), -+ (int)(context->gr - context->g)); -+ } -+} -+ -+static void single_shift(c) -+ unsigned CHAR c; -+{ -+ switch((unsigned char) c){ -+ case CODE_SS2: context->ss = &context->g[2]; break; -+ case CODE_SS3: context->ss = &context->g[3]; break; -+ } -+} -+ -+ -+static void put_unknown_char(chr) -+ unsigned CHAR chr; -+{ -+ unsigned char c = chr; -+ -+ if(c < 0x20){ -+ unsigned char buf[2]; -+ buf[0] = '^'; -+ buf[1] = c + 0x40; -+ pack_string(ascii, buf, 2); -+ }else{ -+ unsigned char buf[4]; -+ buf[0] = '\\'; -+ buf[1] = ((c >> 6) & 07) + '0'; -+ buf[2] = ((c >> 3) & 07) + '0'; -+ buf[3] = ((c ) & 07) + '0'; -+ pack_string(ascii, buf, 4); -+ } -+} -+ -+struct context *ml_create_context(s) -+ Screen *s; -+{ -+ context = (struct context *) malloc(sizeof *context); -+ -+ context->g[0] = NULL; -+ context->g[1] = NULL; -+ context->g[2] = NULL; -+ context->g[3] = NULL; -+ context->gl = NULL; -+ context->gr = NULL; -+ context->ss = NULL; -+ -+ context->cbuf = NULL; -+ context->text.maxlines = context->text.nlines = 0; -+ context->line = 0; -+ context->delta = 0; -+ context->toolong = 0; -+ -+ DPY = DisplayOfScreen(s); -+ SCR = s; -+ ROOT_WIN = RootWindowOfScreen(s); -+ -+ return context; -+} -+ -+ -+int ml_set_charsets(ctx, sys) -+ struct context *ctx; -+ struct coding_system *sys; -+{ -+ int retval = 0; -+ int i; -+ -+ context = ctx; -+ -+ if(ascii == NULL){ -+ init_xrm(); -+ if((ascii = search_charset(1, 94, 'B')) == NULL){ -+ fputs("ml_set_charsets: ascii charset not found.\n", stderr); -+ Quit(1); -+ } -+ if (ascii->fs == NULL) { -+ fputs("ml_set_charsets: iso8859-1 font not found.\n", stderr); -+ Quit(1); -+ } -+ } -+ for(i = 0; i < 4; i++){ -+ switch(sys->design[i].bpc){ -+ case -1: /* make G[i] invalid */ -+ context->valid[i] = 0; -+ break; -+ -+ case 0: /* don't change */ -+ break; -+ -+ case 1: case 2: /* change it */ -+ if((context->g[i] = search_charset(sys->design[i].bpc, -+ sys->design[i].noc, -+ sys->design[i].des)) == NULL){ -+ fputs("ml_set_charsets: ", stderr); -+ fprintf(stderr, "(%d,%d,%c) is specified as G%d, ", -+ sys->design[i].bpc, sys->design[i].noc, -+ sys->design[i].des, i); -+ fputs("but not found. using `iso8859-1'.\n", stderr); -+ context->g[i] = ascii; -+ retval++; -+ } -+ context->valid[i] = 1; -+ break; -+ -+ default: /* error */ -+ fprintf(stderr,"ml_set_charsets: bad arguments of G%d. ", i); -+ fputs("using `iso8859-1'.\n", stderr); -+ context->g[i] = ascii; -+ retval++; -+ } -+ } -+ if((unsigned int) sys->gl < 4) -+ context->gl = &context->g[sys->gl]; -+ else{ -+ fprintf(stderr, "ml_set_charsets: bad number as GL. using G0.\n"); -+ context->gl = &context->g[0]; -+ } -+ if((unsigned int) sys->gr < 4) -+ context->gr = &context->g[sys->gr]; -+ else{ -+ fprintf(stderr, "ml_set_charsets: bad number as GR. using G0.\n"); -+ context->gr = &context->g[0]; -+ } -+ context->eol = sys->eol; -+ context->short_form = sys->short_form; -+ context->lock_shift = sys->lock_shift; -+ return retval; -+} -+ -+static struct charset *search_charset(bpc, noc, des) -+ int bpc, noc; -+ int des; -+{ -+ struct charset *cset; -+ for(cset = charset; cset->bpc != 0; cset++){ -+ if(cset->bpc == bpc && -+ cset->noc == noc && -+ cset->designator == (char) des){ -+ if(!cset->loaded){ -+#if 0 -+ int i, l; -+ l = strlen(cset->registry); -+ for (i = 0; i < xrm_nfonts; i++) { -+ int li = strlen(xrm_fonts[i]); -+ if (li > l) { -+ if (xrm_fonts[i][li - l - 1] == '-' && -+ strcmp(xrm_fonts[i] + li - l, -+ cset->registry) == 0) { -+ if ((cset->fs = XLoadQueryFont(DPY, xrm_fonts[i])) -+ != NULL) { -+ if (DEBUG) { -+ fprintf(stderr, "%s for %s\n", -+ xrm_fonts[i], cset->registry); -+ } -+ cset->fontname = xrm_fonts[i]; -+ break; -+ } else -+ SetISTR(ISTR_WARNING, -+ "%s: font not found.", xrm_fonts[i]); -+ } -+ } -+ } -+#else -+ int i, l; -+ l = strlen(cset->registry); -+ for (i = 0; i < xrm_nfonts && cset->fs == NULL; i++) { -+ int j, nfnts = 0; -+ char **fnts = XListFonts(DPY, xrm_fonts[i], -+ 65535, &nfnts); -+ for (j = 0 ; j < nfnts; j++) { -+ int ll = strlen(fnts[j]); -+ if (*(fnts[j] + ll - l - 1) == '-' && -+ strcmp(fnts[j] + ll - l, cset->registry)== 0) { -+ if ((cset->fs = XLoadQueryFont(DPY, fnts[j])) -+ != NULL) { -+ if (DEBUG) { -+ fprintf(stderr, "%s for %s\n", -+ fnts[j], cset->registry); -+ } -+ cset->fontname = strdup(fnts[j]); -+ break; -+ } else -+ SetISTR(ISTR_WARNING, -+ "%s: font not found", fnts[j]); -+ } -+ } -+ if (fnts != NULL) -+ XFreeFontNames(fnts); -+ } -+#endif -+ if(cset->fs == NULL){ -+ SetISTR(ISTR_WARNING, -+ "font for %s not found.\nusing ascii font.", -+ cset->registry); -+ if (ascii != NULL) -+ cset->fs = ascii->fs; -+ } -+ -+ cset->loaded = 1; -+ } -+ return cset; -+ } -+ } -+ return NULL; -+} -+ -+static void pack_string(cs, str, len) -+ struct charset *cs; -+ unsigned char *str; -+ int len; /* number of chars(not bytes) */ -+{ -+ struct ml_text *mt = &context->text; -+ struct ml_line *lp; -+ XTextItem16 *ip; -+ -+ if (context->line == mt->maxlines) { -+ int oldmax = mt->maxlines; -+ if (mt->maxlines < 1) -+ mt->maxlines = 1; -+ else -+ mt->maxlines = 2 * mt->maxlines; -+ if (oldmax == 0) -+ mt->lines = (struct ml_line *) -+ malloc(sizeof(struct ml_line) * mt->maxlines); -+ else { -+ mt->lines = (struct ml_line *) -+ realloc(mt->lines, -+ sizeof(struct ml_line) * mt->maxlines); -+ } -+ } -+ lp = &mt->lines[context->line]; -+ if (mt->nlines == context->line) { -+ mt->nlines++; -+ lp->maxitems = 0; -+ lp->nitems = 0; -+ lp->width = 0; -+ lp->ascent = lp->descent = 0; -+ } -+ -+ if (len == 0) { -+ switch (*str) { -+ case '\n': -+ context->line++; -+ context->delta = 0; -+ context->toolong = 0; -+ break; -+ case '\t': -+ { -+ int nx, x = lp->width + context->delta; -+ nx = (x + ml_tab_width) / ml_tab_width * ml_tab_width; -+ context->delta += nx - x; -+ } -+ break; -+ } -+ return; -+ } -+ -+ if (context->toolong) -+ return; -+ if (lp->width > 30000) { -+ context->toolong = 1; -+ cs = ascii; -+ str = (unsigned char *) "..."; -+ len = 3; -+ } -+ -+ if (lp->nitems == lp->maxitems) { -+ int oldmax = lp->maxitems; -+ if (lp->maxitems < 1) -+ lp->maxitems = 1; -+ else -+ lp->maxitems = 2 * lp->maxitems; -+ if (oldmax == 0) -+ lp->items = (XTextItem16 *) -+ malloc(sizeof(XTextItem16) * lp->maxitems); -+ else -+ lp->items = (XTextItem16 *) -+ realloc(lp->items, -+ sizeof(XTextItem16) * lp->maxitems); -+ } -+ ip = &lp->items[lp->nitems++]; -+ ip->chars = (XChar2b *) context->cbp; -+ ip->nchars = len; -+ ip->delta = context->delta; -+ ip->font = cs->fs->fid; -+ context->cbp += 2 * len; -+ context->delta = 0; -+ -+ if (cs->bpc == 1) { -+ XChar2b *p; -+ unsigned char b7 = cs->bit7 ? 0x80 : 0; -+ int i; -+ for (i = len, p = ip->chars; i > 0; i--, p++) { -+ p->byte1 = '\0'; -+ p->byte2 = (*str++ & 0x7f) | b7; -+ } -+ } else { -+ XChar2b *p; -+ unsigned char b7 = cs->bit7 ? 0x80 : 0; -+ int i; -+ for (i = len, p = ip->chars; i > 0; i--, p++) { -+ p->byte1 = (*str++ & 0x7f) | b7; -+ p->byte2 = (*str++ & 0x7f) | b7; -+ } -+ } -+ -+ lp->width += XTextWidth16(cs->fs, ip->chars, ip->nchars); -+ if (lp->ascent < cs->fs->ascent) -+ lp->ascent = cs->fs->ascent; -+ if (lp->descent < cs->fs->descent) -+ lp->descent = cs->fs->descent; -+} -+ -+void get_monofont_size(wide, high) -+ int *wide, *high; -+{ -+ if (ascii == NULL) { -+ fputs("ml_draw_text: call ml_set_charsets, first.\n", stderr); -+ return; -+ } -+ *wide = ascii->fs->max_bounds.width; -+ *high = ascii->fs->ascent + ascii->fs->descent; -+} -+ -+static void init_xrm() -+{ -+ init_xrm_fonts(); -+ init_xrm_tab(); -+} -+ -+static void init_xrm_fonts() -+{ -+ char *p, *fns = XGetDefault(theDisp, "xv", "fontSet"); -+ int n; -+ if (fns == NULL) { -+ xrm_fonts = default_fonts; -+ xrm_nfonts = sizeof default_fonts / sizeof *default_fonts; -+ return; -+ } -+ while(*fns == ' ' || *fns == '\t') -+ fns++; -+ if (*fns == '\0') { -+ xrm_fonts = default_fonts; -+ xrm_nfonts = sizeof default_fonts / sizeof *default_fonts; -+ return; -+ } -+ fns = strdup(fns); -+ -+ n = 1; -+ for (p = fns; *p != '\0'; p++) { -+ if (*p == ',') -+ n++; -+ } -+ xrm_nfonts = n; -+ xrm_fonts = (char **) malloc(sizeof (char *) * xrm_nfonts); -+ for (n = 0, p = fns; n < xrm_nfonts && *p != '\0'; ) { -+ while (*p == ' ' || *p == '\t') -+ p++; -+ xrm_fonts[n++] = p; -+ while (1) { -+ char *q; -+ while (*p != ' ' && *p != '\t' && *p != ',' && *p != '\0') -+ p++; -+ q = p; -+ while (*q == ' ' || *q == '\t') -+ q++; -+ if (*q == ',' || *q == '\0') { -+ *p = '\0'; -+ p = q + 1; -+ break; -+ } else -+ p = q; -+ } -+ } -+ for ( ; n < xrm_nfonts; n++) -+ xrm_fonts[n] = ""; -+} -+ -+static void init_xrm_tab() -+{ -+ char *ts = XGetDefault(theDisp, "xv", "tabWidth"); -+ unsigned short tab; -+ if (ts == NULL) -+ tab = 64; -+ else { -+ char *ep; -+ long t; -+ int bad = 0; -+ t = strtol(ts, &ep, 0); -+ tab = (unsigned short) t; -+ if (ep != NULL) { -+ while (*ep == ' ' && *ep == '\t') -+ ep++; -+ if (*ep != '\0') -+ bad = 1; -+ } -+ if (tab != (long) (unsigned long) t) -+ bad = 1; -+ if (bad) { -+ SetISTR(ISTR_WARNING, "bad tab width."); -+ tab = 64; -+ } -+ } -+ ml_tab_width = tab; -+} -+ -+ -+#ifndef HAVE_STRDUP -+static char *strdup(str) -+ char *str; -+{ -+ return strcpy(malloc(strlen(str) + 1), str); -+} -+#endif -+ -+char *lookup_registry(d, b7) -+ struct design d; -+ int *b7; -+{ -+ int i; -+ for (i = 0; i < NR_CHARSETS; i++) { -+ if (charset[i].bpc == d.bpc && charset[i].noc == d.noc && -+ charset[i].designator == d.des) { -+ *b7 = charset[i].bit7; -+ return charset[i].registry; -+ } -+ } -+ return NULL; -+} -+ -+struct design lookup_design(registry, b7) -+ char *registry; -+ int b7; -+{ -+ struct design d; -+ int i; -+ d.bpc = 0; -+ d.noc = 0; -+ d.des = '\0'; -+ for (i = 0; i < NR_CHARSETS; i++) { -+ if (strcmp(charset[i].registry, registry) == 0 && -+ charset[i].bit7 == b7) { -+ d.bpc = charset[i].bpc; -+ d.noc = charset[i].noc; -+ d.des = charset[i].designator; -+ break; -+ } -+ } -+ return d; -+} -+ -+char *sjis_to_jis(orig, len, newlen) -+ char *orig; -+ int len, *newlen; -+{ -+ unsigned char *new; -+ unsigned char *p, *q, *endp; -+ if (len == 0) { -+ *newlen = 0; -+ return (char *) malloc((size_t) 1); -+ } -+ new = (unsigned char *) malloc((size_t) len * 4); /* big enough */ -+ for (p = (unsigned char *) orig, endp = p + len, q = new; p < endp; ) { -+ if ((*p & 0x80) == 0) /* 1 byte char */ -+ *q++ = *p++; -+ else if (*p >= 0x81 && *p <= 0x9f) { /* kanji 1st byte */ -+ unsigned char c1 = *p++; -+ unsigned char c2 = *p++; -+ if (c2 < 0x40 || c2 > 0xfc) { /* bad 2nd byte */ -+ *q++ = CODE_SS2; -+ *q++ = c1; -+ *q++ = CODE_SS2; -+ *q++ = c2; -+ } else { /* right 2nd byte */ -+ if (c2 <= 0x9e) { -+ if (c2 > 0x7f) -+ c2--; -+ c1 = (c1 - 0x81) * 2 + 1 + 0xa0; -+ c2 = (c2 - 0x40) + 1 + 0xa0; -+ } else { -+ c1 = (c1 - 0x81) * 2 + 2 + 0xa0; -+ c2 = (c2 - 0x9f) + 1 + 0xa0; -+ } -+ *q++ = c1; -+ *q++ = c2; -+ } -+ } else if (*p >= 0xe0 && *p <= 0xef) { /* kanji 1st byte */ -+ unsigned char c1 = *p++; -+ unsigned char c2 = *p++; -+ if (c2 < 0x40 || c2 > 0xfc) { /* bad 2nd byte */ -+ *q++ = CODE_SS2; -+ *q++ = c1; -+ *q++ = CODE_SS2; -+ *q++ = c2; -+ } else { /* right 2nd byte */ -+ if (c2 <= 0x9e) { -+ c1 = (c1 - 0xe0) * 2 + 63 + 0xa0; -+ c2 = (c2 - 0x40) + 1 + 0xa0; -+ } else { -+ c1 = (c1 - 0xe0) * 2 + 64 + 0xa0; -+ c2 = (c2 - 0x9f) + 1 + 0xa0; -+ } -+ *q++ = c1; -+ *q++ = c2; -+ } -+ } else { /* katakana or something */ -+ *q++ = CODE_SS2; -+ *q++ = *p++; -+ } -+ } -+ *newlen = q - new; -+ -+ return (char *) realloc(new, (size_t) *newlen); -+} -+ -+#endif /* TV_MULTILINGUAL */ -diff -ruN xv-3.10a-bugfixes/xvml.h xv-3.10a-enhancements/xvml.h ---- xv-3.10a-bugfixes/xvml.h 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvml.h 2005-04-17 22:57:45.000000000 -0700 -@@ -0,0 +1,96 @@ -+#ifndef MLVIEW_H -+#define MLVIEW_H -+ -+/* -+ * What is this? -+ * -+ * It is a package to show multi-lingual text. -+ * -+ * How to use? -+ * -+ * 1. Call ml_set_screen(Screen *scr); -+ * Tell this package the screen you use. -+ * -+ * 2. Call ml_set_charsets(struct char_spec spec[4], int gl, int gr); -+ * Tell this package the initial charsets. -+ * Gn is set to the charset specified by spec[n], respectively. -+ * GL and GR are set to G[gl] and G[gr], respectively. -+ * If first call, iso8859-1 font is loaded. -+ * -+ * 3. Call ml_draw_text(char *string); -+ * It Creates a bitmap, and returns it to you. -+ * If something goes wrong, it returns None. -+ * DON'T free the returned pixmaps!! -+ * -+ * BUGS: -+ * - Amharic and Tigrigna characters are strange. -+ * - Big5 is not supported. -+ * - Reverse direction is not supported. -+ * - Composing is not supported. -+ * - Cantonese can't be shown. -+ * - Texts which have many lines are buggy. -+ * -+ * NOTE: -+ * - Shifted JIS and Shifted GB must be converted to iso2022 in advance. -+ * -+ * Example of parameters to ml_set_charsets: -+ * - EUC-Japan -+ * spec = { {1, 94, 'B'}, G0 is US-ASCII -+ * {2, 94, 'B'}, G1 is JIS X0208 -+ * {1, 94, 'J'}, G2 is (right-half of)JIS X0201 -+ * {2, 94, 'D'} }; G3 is JIS X0212 -+ * gl = 0; GL is G0 -+ * gr = 1; GR is G1 -+ * -+ * - Compound Text -+ * spec = { {1, 94, 'B'}, G0 is US-ASCII -+ * {1, 96, 'A'}, G1 is Latin-1 -+ * {1, 94, 'B'}, G2 is US-ASCII (maybe unused) -+ * {1, 94, 'B'} }; G3 is US-ASCII (maybe unused) -+ * gl = 0; GL is G0 -+ * gr = 1; GR is G1 -+ * -+ * - Korean Mail -+ * spec = { {1, 94, 'B'}, G0 is US-ASCII -+ * {2, 94, 'C'}, G1 is KSC5601 -+ * {1, 94, 'B'}, G2 is US-ASCII (maybe unused) -+ * {1, 94, 'B'} }; G3 is US-ASCII (maybe unused) -+ * gl = 0; GL is G0 -+ * gl = 1; GR is G1 -+ */ -+ -+struct coding_system { -+ struct design { -+ int bpc; /* byte per char if 1 or 2, -+ don't touch if 0, or -+ don't use if -1.*/ -+ int noc; /* number of chars (94 or 96) */ -+ char des; /* designator ('A', 'B', ...) */ -+ } design[4]; -+ int gl, gr; -+ int eol; -+ int short_form; -+ int lock_shift; -+}; -+ -+struct ml_text { -+ int maxlines, nlines; -+ struct ml_line { -+ int maxitems, nitems; -+ int width, ascent, descent; -+ XTextItem16 *items; -+ } *lines; -+ int width, height; -+}; -+ -+struct context; -+struct ml_text *ml_draw_text PARM((struct context *, char *, int)); -+struct context *ml_create_context PARM((Screen *)); -+int ml_set_charsets PARM((struct context *, -+ struct coding_system *)); -+void get_monofont_size PARM((int *, int *)); -+char *sjis_to_jis PARM((char *, int, int *)); -+char *lookup_registry PARM((struct design, int *)); -+struct design lookup_design PARM((char *, int)); -+ -+#endif -diff -ruN xv-3.10a-bugfixes/xvpbm.c xv-3.10a-enhancements/xvpbm.c ---- xv-3.10a-bugfixes/xvpbm.c 2005-04-03 14:25:28.000000000 -0700 -+++ xv-3.10a-enhancements/xvpbm.c 2005-04-17 14:04:22.000000000 -0700 -@@ -23,6 +23,15 @@ - */ - - -+typedef unsigned short ush; -+typedef unsigned char uch; -+ -+#define alpha_composite(composite, fg, alpha, bg) { \ -+ ush temp = ((ush)(fg)*(ush)(alpha) + \ -+ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ -+ (composite) = (uch)((temp + (temp >> 8)) >> 8); \ -+} -+ - #define TRUNCSTR "File appears to be truncated." - - static int garbage; -@@ -31,6 +40,7 @@ - static int loadpbm PARM((FILE *, PICINFO *, int)); - static int loadpgm PARM((FILE *, PICINFO *, int, int)); - static int loadppm PARM((FILE *, PICINFO *, int, int)); -+static int loadpam PARM((FILE *, PICINFO *, int, int)); - static int getint PARM((FILE *, PICINFO *)); - static int getbit PARM((FILE *, PICINFO *)); - static int getshort PARM((FILE *)); -@@ -38,10 +48,83 @@ - - static char *bname; - -+ -+#ifdef HAVE_MGCSFX -+/* -+ * When file read or file write is fail, probably it's caused by -+ * reading from pipe which has no data yet, or writing to pipe -+ * which is not ready yet. -+ * Then we can use system call select() on descriptor of pipe and wait. -+ * If you want, change 'undef' to 'define' in the following line. -+ * This feature is performance-killer. -+ */ -+#undef FIX_PIPE_ERROR -+ -+#ifdef __osf__ -+# ifdef __alpha -+# define FIX_PIPE_ERROR -+# endif -+#endif -+ -+#endif /* HAVE_MGCSFX */ -+ -+ -+#ifdef FIX_PIPE_ERROR -+ -+int pipefdr; -+ -+struct timeval timeout; -+int width; -+fd_set fds; -+ -+static void ready_read() -+{ -+ if(pipefdr < 0) return; /* if file descriptor is not pipe, OK */ -+ WaitCursor(); -+ -+reselect: -+ /* setting of timeout */ -+ timeout.tv_sec = 1; /* 1 sec */ -+ timeout.tv_usec = 0; /* 0 usec */ -+ -+ FD_ZERO(&fds); /* clear bits */ -+ FD_SET(pipefdr, &fds); /* set bit of fd in fds */ -+ -+ /* number of file descriptor to want check (0 $B!A(B width-1) */ -+ width = pipefdr + 1; -+ -+ /* select returns number of file descriptors */ -+ if (select(width, &fds, NULL, NULL, &timeout) < 0){ -+ if(DEBUG){ -+ fprintf(stderr, "No file descriptors can't selected, waiting...\n"); -+ } -+ goto reselect; -+ } -+ -+ if (FD_ISSET(pipefdr, &fds)){ -+ /* Now, descriptor of pipe is ready to read */ -+ return; -+ }else{ -+ if(DEBUG){ -+ fprintf(stderr, "Can't read from pipe yet, waiting...\n"); -+ } -+ goto reselect; -+ } -+ -+} -+#endif /* FIX_PIPE_ERROR */ -+ - /*******************************************/ -+#ifdef HAVE_MGCSFX -+int LoadPBM(fname, pinfo, fd) -+ char *fname; -+ PICINFO *pinfo; -+ int fd; -+#else - int LoadPBM(fname, pinfo) - char *fname; - PICINFO *pinfo; -+#endif /* HAVE_MGCSFX */ - /*******************************************/ - { - /* returns '1' on success */ -@@ -50,6 +133,10 @@ - int c, c1; - int maxv, rv; - -+#ifdef FIX_PIPE_ERROR -+ pipefdr = fd; -+#endif -+ - garbage = maxv = rv = 0; - bname = BaseName(fname); - -@@ -57,6 +144,22 @@ - pinfo->comment = (char *) NULL; - - -+#ifdef HAVE_MGCSFX -+ if(fd < 0){ -+ /* open the file */ -+ fp = xv_fopen(fname,"r"); -+ if (!fp) return (pbmError(bname, "can't open file")); -+ -+ /* compute file length */ -+ fseek(fp, 0L, 2); -+ filesize = ftell(fp); -+ fseek(fp, 0L, 0); -+ }else{ -+ fp = fdopen(fd, "r"); -+ if (!fp) return (pbmError(bname, "can't open file")); -+ filesize = 0; /* dummy */ -+ } -+#else - /* open the file */ - fp = xv_fopen(fname,"r"); - if (!fp) return (pbmError(bname, "can't open file")); -@@ -65,6 +168,7 @@ - fseek(fp, 0L, 2); - filesize = ftell(fp); - fseek(fp, 0L, 0); -+#endif /* HAVE_MGCSFX */ - - - /* read the first two bytes of the file to determine which format -@@ -73,7 +177,8 @@ - "P6" = raw pixmap */ - - c = getc(fp); c1 = getc(fp); -- if (c!='P' || c1<'1' || c1>'6') return(pbmError(bname, "unknown format")); -+ if (c!='P' || c1<'1' || (c1>'6' && c1!='8')) /* GRR alpha */ -+ return(pbmError(bname, "unknown format")); - - /* read in header information */ - pinfo->w = getint(fp, pinfo); pinfo->h = getint(fp, pinfo); -@@ -104,6 +209,7 @@ - if (c1=='1' || c1=='4') rv = loadpbm(fp, pinfo, c1=='4' ? 1 : 0); - else if (c1=='2' || c1=='5') rv = loadpgm(fp, pinfo, c1=='5' ? 1 : 0, maxv); - else if (c1=='3' || c1=='6') rv = loadppm(fp, pinfo, c1=='6' ? 1 : 0, maxv); -+ else if (c1=='8') rv = loadpam(fp, pinfo, 1 , maxv); - - fclose(fp); - -@@ -248,7 +354,20 @@ - } - } - else { -+#ifdef FIX_PIPE_ERROR -+ reread: -+ numgot += fread(pic8 + numgot, (size_t) 1, (size_t) w*h - numgot, fp); /* read raw data */ -+ if(errno == EINTR){ -+ if(DEBUG){ -+ fprintf(stderr, -+ "Can't read all data from pipe, call select and waiting...\n"); -+ } -+ ready_read(); -+ goto reread; -+ } -+#else - numgot = fread(pic8, (size_t)1, (size_t)npixels, fp); /* read raw data */ -+#endif - } - } - -@@ -315,7 +434,20 @@ - } - } - else { -+#ifdef FIX_PIPE_ERROR -+ reread: -+ numgot += fread(pic24 + numgot, (size_t) 1, (size_t) w*h*3 - numgot, fp); /* read data */ -+ if(errno == EINTR){ -+ if(DEBUG){ -+ fprintf(stderr, -+ "Can't read all data from pipe, call select and waiting...\n"); -+ } -+ ready_read(); -+ goto reread; -+ } -+#else - numgot = fread(pic24, (size_t) 1, (size_t) bufsize, fp); /* read data */ -+#endif - } - } - -@@ -341,6 +473,122 @@ - } - - -+/*******************************************/ -+static int loadpam(fp, pinfo, raw, maxv) /* unofficial RGBA extension */ -+ FILE *fp; -+ PICINFO *pinfo; -+ int raw, maxv; -+{ -+ byte *p, *pix, *pic24, *linebuf, scale[256], bgR, bgG, bgB, r, g, b, a; -+ int i, j, bitshift, w, h, npixels, bufsize, linebufsize, holdmaxv; -+ -+ w = pinfo->w; -+ h = pinfo->h; -+ -+ npixels = w * h; -+ bufsize = 3*npixels; -+ linebufsize = 4*w; -+ if (w <= 0 || h <= 0 || npixels/w != h || bufsize/3 != npixels || -+ linebufsize/4 != w) -+ return pbmError(bname, "image dimensions too large"); -+ -+ /* allocate 24-bit image */ -+ pic24 = (byte *) calloc((size_t) bufsize, (size_t) 1); -+ if (!pic24) FatalError("couldn't malloc 'pic24' for PAM"); -+ -+ /* allocate line buffer for pre-composited RGBA data */ -+ linebuf = (byte *) malloc((size_t) linebufsize); -+ if (!linebuf) { -+ free(pic24); -+ FatalError("couldn't malloc 'linebuf' for PAM"); -+ } -+ -+ pinfo->pic = pic24; -+ pinfo->type = PIC24; -+ sprintf(pinfo->fullInfo, "PAM, %s format. (%ld bytes)", -+ (raw) ? "raw" : "ascii", filesize); -+ sprintf(pinfo->shrtInfo, "%dx%d PAM.", w, h); -+ pinfo->colType = F_FULLCOLOR; -+ -+ -+ /* if maxv>255, keep dropping bits until it's reasonable */ -+ holdmaxv = maxv; -+ bitshift = 0; -+ while (maxv>255) { maxv = maxv>>1; bitshift++; } -+ -+ -+ numgot = 0; -+ -+ if (!raw) { /* GRR: not alpha-ready */ -+ return pbmError(bname, "can't handle non-raw PAM image"); -+/* -+ for (i=0, pix=pic24; i<h; i++) { -+ if ((i&0x3f)==0) WaitCursor(); -+ for (j=0; j<w*3; j++, pix++) -+ *pix = (byte) (getint(fp, pinfo) >> bitshift); -+ } -+ */ -+ } -+ else { /* raw */ -+ if (holdmaxv>255) { /* GRR: not alpha-ready */ -+ return pbmError(bname, "can't handle PAM image with maxval > 255"); -+/* -+ for (i=0, pix=pic24; i<h; i++) { -+ if ((i&0x3f)==0) WaitCursor(); -+ for (j=0; j<w*3; j++,pix++) -+ *pix = (byte) (getshort(fp) >> bitshift); -+ } -+ */ -+ } -+ else { -+ if (have_imagebg) { /* GRR: alpha-ready */ -+ bgR = (imagebgR >> 8); -+ bgG = (imagebgG >> 8); -+ bgB = (imagebgB >> 8); -+ } else { -+ bgR = bgG = bgB = 0; -+ } -+ for (i=0, pix=pic24; i<h; i++) { -+ numgot += fread(linebuf, (size_t) 1, (size_t) linebufsize, fp); /* read data */ -+ if ((i&0x3f)==0) WaitCursor(); -+ for (j=0, p=linebuf; j<w; j++) { -+ r = *p++; -+ g = *p++; -+ b = *p++; -+ a = *p++; -+ alpha_composite(*pix++, r, a, bgR) -+ alpha_composite(*pix++, g, a, bgG) -+ alpha_composite(*pix++, b, a, bgB) -+ } -+ } -+ } -+ } -+ -+ free(linebuf); -+ -+ /* in principle this could overflow, but not critical */ -+ if (numgot != w*h*4) pbmError(bname, TRUNCSTR); -+ -+ if (garbage) -+ return(pbmError(bname, "Garbage characters in image data.")); -+ -+ -+ /* have to scale up all RGB values (Conv24to8 expects RGB values to -+ range from 0-255) */ -+ -+ if (maxv<255) { -+ for (i=0; i<=maxv; i++) scale[i] = (i * 255) / maxv; -+ -+ for (i=0, pix=pic24; i<h; i++) { -+ if ((i&0x3f)==0) WaitCursor(); -+ for (j=0; j<w*3; j++, pix++) *pix = scale[*pix]; -+ } -+ } -+ -+ return 1; -+} -+ -+ - - /*******************************************/ - static int getint(fp, pinfo) -diff -ruN xv-3.10a-bugfixes/xvpcd.c xv-3.10a-enhancements/xvpcd.c ---- xv-3.10a-bugfixes/xvpcd.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvpcd.c 2005-04-26 00:25:13.000000000 -0700 -@@ -0,0 +1,1307 @@ -+/* -+ * 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. -+ */ -+ -+#include "xv.h" -+#include <memory.h> -+ -+#ifdef HAVE_PCD -+ -+#define TRACE 0 -+#if TRACE -+# define trace(x) fprintf x -+#else -+# define trace(x) -+#endif -+ -+/* Comments on error-handling: -+ A truncated file is not considered a Major Error. The file is loaded, -+ and 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) -+{ -+ long offset; -+ int mag; -+ int rotate; -+ byte header[3*0x800]; -+ byte *pic24, *luma, *chroma1, *chroma2, *ptr, *lptr, *c1ptr, *c2ptr; -+ int w, h, npixels, bufsize; -+ 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 -+ */ -+ npixels = pinfo->w * pinfo->h; -+ bufsize = 3 * npixels; -+ if (pinfo->w <= 0 || pinfo->h <= 0 || npixels/pinfo->w != pinfo->h || -+ bufsize/3 != npixels) -+ FatalError("image dimensions out of range"); -+ -+ pinfo->pic = (byte *)malloc((size_t) bufsize); -+ 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) { -+ free(pinfo->pic); -+ return pcdError(bname,"Can't find start of data."); -+ } -+ -+ pic24 = pinfo->pic; -+ -+ luma=(byte *)calloc(npixels,1); -+ if(!luma) { -+ free(pinfo->pic); -+ FatalError("couldn't malloc 'luma plane'"); -+ } -+ -+ chroma1=(byte *)calloc(npixels/4,1); -+ if(!chroma1) { -+ free(pinfo->pic); -+ free(luma); -+ FatalError("couldn't malloc 'chroma1 plane'"); -+ } -+ -+ chroma2=(byte *)calloc(npixels/4,1); -+ if(!chroma2) { -+ free(pinfo->pic); -+ free(luma); -+ free(chroma1); -+ 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 %ld.%ld)\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 %ld.%ld)\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, bufsize, huffptr, hufftop; -+ byte *huf; -+ -+ /* -+ * absorb the entirety of the table in one chunk (for better -+ * dumps in case of error) -+ */ -+ trace((stderr, "hufftab 0x%08lx ", ftell(fp))); -+ num = 1 + fgetc(fp); /* 256 max */ -+ huf = (byte *)alloca(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)); -+ N = 2*num; /* 512 max */ -+ bufsize = N * sizeof(int); -+/* this case can't happen, but added for symmetry with loop below -+ if (N/2 != num || bufsize/N != sizeof(int)) { -+ SetISTR(ISTR_WARNING, "Huffman table size out of range"); -+ return NULL; -+ } -+ */ -+ if((hufftab = (int *)malloc(bufsize)) == NULL) -+ FatalError("couldn't malloc initial Huffman table"); -+ 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, num); -+ 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) { -+ int oldN = N; -+#if TRACE -+ dumphufftab(num, huf, hufftop/2, hufftab); -+#endif -+ N *= 2; -+ bufsize = N*sizeof(int); -+ if (N/2 != oldN || bufsize/N != sizeof(int)) { -+ SetISTR(ISTR_WARNING, -+ "new Huffman table is too large"); -+ free(hufftab); -+ return NULL; -+ } -+ h = (int *)realloc(hufftab, bufsize); -+ if(h == NULL) { -+ fprintf(stderr, -+ "Table overflow %d/%d\n", -+ i, num); -+ dumphufftab(num, huf, -+ hufftop/2, hufftab); -+ free(hufftab); -+ FatalError( -+ "couldn't realloc Huffman table"); -+ } -+ 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; -+ -+#if 0 -+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"); -+ } -+} -+#endif /* 0 */ -+ -+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; -+ int row, col, plane, i, result = 1; -+#if TRACE -+ int uflow = 0, oflow = 0; -+#endif -+ byte *pixelptr = NULL; -+ -+ trace((stderr,"gethuffdata: start @ 0x%08lx (sector %ld.%ld)\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 %ld.%d)\n", -+ ftell(fp), ftell(fp)/0x800, 0x800 - bytesleft)); -+ return result; -+} -+ -+#endif /* HAVE_PCD */ -diff -ruN xv-3.10a-bugfixes/xvpds.c xv-3.10a-enhancements/xvpds.c ---- xv-3.10a-bugfixes/xvpds.c 2005-04-03 11:31:30.000000000 -0700 -+++ xv-3.10a-enhancements/xvpds.c 2005-04-17 21:40:40.000000000 -0700 -@@ -77,8 +77,7 @@ - * Huffman-encoded, and the encoding histogram follows the ASCII headers. - * To decode these, we use a slightly modified version of "vdcomp.c" from the - * NASA Viking CD-ROMS. For xv to work, you need to have vdcomp compiled -- * and in your search path. vdcomp.c should be included with this --distribution. -+ * and in your search path. vdcomp.c should be included with this distribution. - * - * I've heard that newer discs have FITS images on them. If they do, support - * for them will be added when I get one. Until then, you can use fitstopgm. -@@ -102,7 +101,7 @@ - * This software is provided "as is" without any express or implied warranty. - */ - -- -+#define NEEDSDIR /* for S_IRUSR|S_IWUSR */ - #include "xv.h" - - #ifdef HAVE_PDS -@@ -129,27 +128,32 @@ - - /* This is arbitrary. Everything I've seen so far fits in 50 chars */ - #define COMMENTSIZE 50 -+#define INOTESIZE 1000 - - - static int lastwasinote = FALSE; --static char scanbuff [MAX_SIZE], -- rtbuff [RTBUFFSIZE], -- inote [20*COMMENTSIZE], -- infobuff [COMMENTSIZE], -- spacecraft [COMMENTSIZE], -- target [COMMENTSIZE], -- filtname [COMMENTSIZE], -- gainmode [COMMENTSIZE], -- editmode [COMMENTSIZE], -- scanmode [COMMENTSIZE], -- exposure [COMMENTSIZE], -- shuttermode [COMMENTSIZE], -- mphase [COMMENTSIZE], -- iname [COMMENTSIZE], -- itime [COMMENTSIZE], -- garbage [1020], -+static char scanbuff [MAX_SIZE+1], -+ rtbuff [RTBUFFSIZE+1], -+ inote [INOTESIZE+1], -+ infobuff [COMMENTSIZE+1], -+ spacecraft [COMMENTSIZE+1], -+ target [COMMENTSIZE+1], -+ filtname [COMMENTSIZE+1], -+ gainmode [COMMENTSIZE+1], -+ editmode [COMMENTSIZE+1], -+ scanmode [COMMENTSIZE+1], -+ exposure [COMMENTSIZE+1], -+ shuttermode [COMMENTSIZE+1], -+ mphase [COMMENTSIZE+1], -+ iname [COMMENTSIZE+1], -+ itime [COMMENTSIZE+1], -+ garbage [1024], - *tmptmp, - pdsuncompfname[FNAMESIZE]; -+ -+#define SSTR(l) "%" #l "s" -+#define S(l) SSTR(l) -+ - byte *image; - static int elaphe; - -@@ -251,6 +255,9 @@ - /* returns '1' on success, '0' on failure */ - - int tempnum, bytewidth, bufsize; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif - FILE *zf; - static int isfixed,teco,i,j,itype,vaxbyte, - recsize,hrecsize,irecsize,isimage,labelrecs,labelsofar, -@@ -397,7 +404,7 @@ - - if (strcmp(scanbuff,"END") == 0) { - break; -- } else if (sscanf(scanbuff," RECORD_TYPE = %s",rtbuff) == 1) { -+ } else if (sscanf(scanbuff, " RECORD_TYPE = " S(RTBUFFSIZE), rtbuff) == 1) { - if (strncmp(rtbuff,"VARIABLE_LENGTH", (size_t) 15) == 0) { - /* itype=PDSVARIABLE; */ - } else if (strncmp(rtbuff,"FIXED_LENGTH", (size_t) 12) == 0) { -@@ -416,7 +423,7 @@ - if (irecsize == 0) irecsize=recsize; - lastwasinote=FALSE; - continue; -- } else if (sscanf(scanbuff," FILE_TYPE = %s", rtbuff) != 0) { -+ } else if (sscanf(scanbuff, " FILE_TYPE = " S(RTBUFFSIZE), rtbuff) != 0) { - lastwasinote=FALSE; - if (strncmp(rtbuff,"IMAGE", (size_t) 5) == 0) { - isimage=TRUE; -@@ -445,74 +452,74 @@ - lastwasinote=FALSE; continue; - } else if (sscanf(scanbuff," SAMPLE_BITS = %d", &samplesize) == 1) { - lastwasinote=FALSE; continue; -- } else if (sscanf(scanbuff," SAMPLE_TYPE = %s", sampletype) == 1) { -+ } else if (sscanf(scanbuff, " SAMPLE_TYPE = " S(64), sampletype) == 1) { - lastwasinote=FALSE; continue; -- } else if (sscanf(scanbuff," SPACECRAFT_NAME = %s %s", -+ } else if (sscanf(scanbuff," SPACECRAFT_NAME = " S(COMMENTSIZE) " " S(1023), - spacecraft,garbage) == 2 ) { -- strcat(spacecraft,xv_strstr(scanbuff, spacecraft)+strlen(spacecraft)); -+ const char *tmp = xv_strstr(scanbuff, spacecraft) + strlen(spacecraft); -+ strncat(spacecraft, tmp, COMMENTSIZE - strlen(spacecraft)); - lastwasinote=FALSE; continue; -- } else if (sscanf(scanbuff," SPACECRAFT_NAME = %s", spacecraft) == 1) { -+ } else if (sscanf(scanbuff, " SPACECRAFT_NAME = " S(COMMENTSIZE), spacecraft) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," TARGET_NAME = %s", target) == 1) { -+ } else if (sscanf(scanbuff, " TARGET_NAME = " S(COMMENTSIZE), target) == 1) { - lastwasinote=FALSE; continue; -- } else if (sscanf(scanbuff," TARGET_BODY = %s", target) == 1) { -+ } else if (sscanf(scanbuff, " TARGET_BODY = " S(COMMENTSIZE), target) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," MISSION_PHASE_NAME = %s", mphase) == 1) { -+ } else if (sscanf(scanbuff, " MISSION_PHASE_NAME = " S(COMMENTSIZE), mphase) == 1) { - lastwasinote=FALSE; continue; -- } else if (sscanf(scanbuff," MISSION_PHASE = %s", mphase) == 1) { -+ } else if (sscanf(scanbuff, " MISSION_PHASE = " S(COMMENTSIZE), mphase) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_NAME = %s", iname) == 1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_NAME = " S(COMMENTSIZE), iname) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," GAIN_MODE_ID = %s", gainmode) == 1) { -+ } else if (sscanf(scanbuff, " GAIN_MODE_ID = " S(COMMENTSIZE), gainmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_GAIN_STATE = %s",gainmode)==1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_GAIN_STATE = " S(COMMENTSIZE), gainmode) ==1 ) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," EDIT_MODE_ID = %s", editmode) == 1) { -+ } else if (sscanf(scanbuff, " EDIT_MODE_ID = " S(COMMENTSIZE), editmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_EDIT_MODE = %s", editmode)==1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_EDIT_MODE = " S(COMMENTSIZE), editmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," SCAN_MODE_ID = %s", scanmode) == 1) { -+ } else if (sscanf(scanbuff, " SCAN_MODE_ID = " S(COMMENTSIZE), scanmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_SCAN_RATE = %s", scanmode)==1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_SCAN_RATE = " S(COMMENTSIZE), scanmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," SHUTTER_MODE_ID = %s", shuttermode) == 1) { -+ } else if (sscanf(scanbuff, " SHUTTER_MODE_ID = " S(COMMENTSIZE), shuttermode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_SHUTTER_MODE = %s", -- shuttermode) == 1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_SHUTTER_MODE = " S(COMMENTSIZE), shuttermode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," SCAN_MODE_ID = %s", scanmode) == 1) { -+ } else if (sscanf(scanbuff, " SCAN_MODE_ID = " S(COMMENTSIZE), scanmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_SCAN_RATE = %s", scanmode)==1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_SCAN_RATE = " S(COMMENTSIZE), scanmode) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," SPACECRAFT_EVENT_TIME = %s", itime) == 1) { -+ } else if (sscanf(scanbuff, " SPACECRAFT_EVENT_TIME = " S(COMMENTSIZE), itime) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," IMAGE_TIME = %s", itime) == 1) { -+ } else if (sscanf(scanbuff, " IMAGE_TIME = " S(COMMENTSIZE), itime) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," FILTER_NAME = %s", filtname) == 1) { -+ } else if (sscanf(scanbuff, " FILTER_NAME = " S(COMMENTSIZE), filtname) == 1) { - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff," INSTRUMENT_FILTER_NAME = %s",filtname)==1) { -+ } else if (sscanf(scanbuff, " INSTRUMENT_FILTER_NAME = " S(COMMENTSIZE), filtname) == 1) { - lastwasinote=FALSE; continue; - -- } else if ((sscanf(scanbuff," EXPOSURE_DURATION = %s", exposure) == 1) -- || (sscanf(scanbuff," INSTRUMENT_EXPOSURE_DURATION = %s", -- exposure) == 1)) { -+ } else if ((sscanf(scanbuff, " EXPOSURE_DURATION = " S(COMMENTSIZE), exposure) == 1) -+ || (sscanf(scanbuff, " INSTRUMENT_EXPOSURE_DURATION = " S(COMMENTSIZE), -+ exposure)) == 1) { - tmptmp = (char *) index(scanbuff,'='); - tmptmp++; - while((*tmptmp) == ' ') -@@ -520,10 +527,10 @@ - strcpy(exposure,tmptmp); - lastwasinote=FALSE; continue; - -- } else if (sscanf(scanbuff, "NOTE = %s", inote) == 1) { -+ } else if (sscanf(scanbuff, "NOTE = " S(INOTESIZE), inote) == 1) { - tmptmp = (char *) index(scanbuff,'='); tmptmp++; - while (((*tmptmp) == ' ') || ((*tmptmp) == '"')) tmptmp++; -- strcpy(inote,tmptmp); -+ strncpy(inote, tmptmp, INOTESIZE - 1); - strcat(inote," "); - - /* evil and somewhat risky: A "note" (really, any textual -@@ -548,7 +555,7 @@ - } else if (lastwasinote) { - tmptmp=scanbuff; - while (((*tmptmp) == ' ') || ((*tmptmp) == '"')) tmptmp++; -- strcat(inote,tmptmp); -+ strncat(inote, tmptmp, INOTESIZE - strlen(inote) - 1); - strcat(inote," "); - if (index(tmptmp,'"') != NULL) - lastwasinote=FALSE; -@@ -647,27 +654,27 @@ - - *infobuff='\0'; - if (*spacecraft) { -- strcat(infobuff,spacecraft); -+ strncat(infobuff, spacecraft, sizeof(infobuff) - 1); - } - - if (*target) { -- strcat(infobuff,", "); -- strcat(infobuff,target); -+ strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1); -+ strncat(infobuff, target, sizeof(infobuff) - strlen(infobuff) - 1); - } - - if (*filtname) { -- strcat(infobuff,", "); -- strcat(infobuff,filtname); -+ strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1); -+ strncat(infobuff, filtname, sizeof(infobuff) - strlen(infobuff) - 1); - } - - if (*itime) { -- strcat(infobuff,", "); -- strcat(infobuff,itime); -+ strncat(infobuff, ", ", sizeof(infobuff) - strlen(infobuff) - 1); -+ strncat(infobuff, itime, sizeof(infobuff) - strlen(infobuff) - 1); - } - -- SetISTR(ISTR_WARNING,infobuff); -+ SetISTR(ISTR_WARNING, "%s", infobuff); - -- strcpy(pdsuncompfname,fname); -+ strncpy(pdsuncompfname,fname,sizeof(pdsuncompfname) - 1); - ftypstr = ""; - - switch (itype) { -@@ -695,7 +702,7 @@ - fclose(zf); - - #ifndef VMS -- sprintf(pdsuncompfname,"%s/xvhuffXXXXXX", tmpdir); -+ snprintf(pdsuncompfname, sizeof(pdsuncompfname) - 1, "%s/xvhuffXXXXXX", tmpdir); - #else - strcpy(pdsuncompfname,"sys$disk:[]xvhuffXXXXXX"); - #endif -@@ -704,10 +711,16 @@ - close(mkstemp(pdsuncompfname)); - #else - mktemp(pdsuncompfname); -+ tmpfd = open(pdsuncompfname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR); -+ if (tmpfd < 0) { -+ SetISTR(ISTR_WARNING,"Unable to create temporary file."); -+ return 0; -+ } -+ close(tmpfd); - #endif - - #ifndef VMS -- sprintf(scanbuff,"%s %s - 4 >%s",PDSUNCOMP,fname,pdsuncompfname); -+ sprintf(scanbuff,"%s '%s' - 4 > %s", PDSUNCOMP, fname, pdsuncompfname); - #else - sprintf(scanbuff,"%s %s %s 4",PDSUNCOMP,fname,pdsuncompfname); - #endif -@@ -823,26 +836,26 @@ - char tmp[256]; - *(pinfo->comment) = '\0'; - -- sprintf(tmp, "Spacecraft: %-28sTarget: %-32s\n", spacecraft, target); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Spacecraft: %-28.28sTarget: %-32.32s\n", spacecraft, target); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Filter: %-32sMission phase: %-24s\n", filtname, mphase); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Filter: %-32.32sMission phase: %-24.24s\n", filtname, mphase); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Image time: %-28sGain mode: %-29s\n", itime, gainmode); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Image time: %-28.28sGain mode: %-29.29s\n", itime, gainmode); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Edit mode: %-29sScan mode: %-29s\n", editmode, scanmode); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Edit mode: %-29.29sScan mode: %-29.29s\n", editmode, scanmode); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Exposure: %-30sShutter mode: %-25s\n", exposure,shuttermode); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Exposure: %-30.30sShutter mode: %-25.25s\n", exposure,shuttermode); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Instrument: %-28sImage time: %-28s\n", iname, itime); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Instrument: %-28.28sImage time: %-28.28s\n", iname, itime); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - -- sprintf(tmp, "Image Note: %-28s", inote); -- strcat(pinfo->comment, tmp); -+ sprintf(tmp, "Image Note: %-28.28s", inote); -+ strncat(pinfo->comment, tmp, 2000 - strlen(pinfo->comment) - 1); - } - - if (LoadPDSPalette(fname, pinfo)) return 1; -diff -ruN xv-3.10a-bugfixes/xvpi.c xv-3.10a-enhancements/xvpi.c ---- xv-3.10a-bugfixes/xvpi.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvpi.c 2005-04-17 22:57:04.000000000 -0700 -@@ -0,0 +1,1060 @@ -+/* -+ * xvpi.c - load routine for `Pi' format pictures. -+ * -+ * The `Pi' format is made by Yanagisawa. -+ * It is common among many Japanese personal computer users. -+ * -+ */ -+ -+#include "xv.h" -+#include <setjmp.h> -+ -+#ifdef HAVE_PI -+ -+typedef unsigned short data16; -+typedef unsigned int data32; -+ -+struct pi_info { -+ jmp_buf jmp; -+ FILE *fp; -+ struct { -+ int rest; -+ byte cur; -+ }bs; -+ long fsize; -+ byte mode; -+ int width, height; -+ float aspect; -+ int cbits; -+ int numcols; -+ byte *cmap; -+ struct ct_t{ -+ struct elt_t *top; -+ struct elt_t{ -+ struct elt_t *old, *recent; -+ byte val; -+ } *elt; -+ }*ct; -+ int defcmap; -+ int writing_grey; -+}; -+ -+static void pi_open_file PARM((struct pi_info*, char*)); -+static void pi_read_header PARM((struct pi_info*, char**)); -+static void pi_check_id PARM((struct pi_info*)); -+static void pi_read_comment PARM((struct pi_info*, char**)); -+static void pi_read_palette PARM((struct pi_info*)); -+static void pi_expand PARM((struct pi_info*, byte**)); -+static byte pi_read_color PARM((struct pi_info*, int)); -+static int pi_read_position PARM((struct pi_info*)); -+static data32 pi_read_length PARM((struct pi_info*)); -+static int pi_copy_pixels PARM((struct pi_info*, -+ byte*, int, int, data32)); -+ -+static void pi_write_header PARM((struct pi_info*, -+ char*, byte*, byte*, byte*)); -+static void pi_write_id PARM((struct pi_info*)); -+static void pi_write_comment PARM((struct pi_info*, char*)); -+static void pi_write_palette PARM((struct pi_info*, byte*, byte*, byte*)); -+static void pi_compress PARM((struct pi_info*, byte*)); -+static void pi_write_gabage PARM((struct pi_info*)); -+static void pi_write_color PARM((struct pi_info*, int, int)); -+static int pi_test_matching PARM((struct pi_info*, -+ byte*, int, int, data32*)); -+static void pi_write_position PARM((struct pi_info*, int)); -+static void pi_write_length PARM((struct pi_info*, data32)); -+ -+static void pi_table_create PARM((struct pi_info*)); -+static byte pi_table_get_value PARM((struct pi_info*, int, int)); -+static int pi_table_lookup_value PARM((struct pi_info*, int, int)); -+static data32 pi_read_bits PARM((struct pi_info*, int)); -+static void pi_write_bits PARM((struct pi_info*, data32, int)); -+static void pi_init_pi_info PARM((struct pi_info*)); -+static void pi_cleanup_pi_info PARM((struct pi_info*, int)); -+static void pi_cleanup_pinfo PARM((PICINFO*)); -+static void pi_memory_error PARM((char*, char*)); -+static void pi_error PARM((struct pi_info*, int)); -+static void pi_file_error PARM((struct pi_info*, int)); -+static void pi_file_warning PARM((struct pi_info*, int)); -+static void pi_show_pi_info PARM((struct pi_info*)); -+static void *pi_malloc PARM((size_t, char*)); -+static void *pi_realloc PARM((void*, size_t, char*)); -+ -+ -+static char *pi_id = "Pi"; -+static char *pi_msgs[] = { -+ NULL, -+#define PI_OPEN 1 -+ "couldn't open.", -+#define PI_CORRUPT 2 -+ "file corrupted.", -+#define PI_FORMAT 3 -+ "not PI format.", -+#define PI_PLANES 4 -+ "bad number of planes.", -+#define PI_WRITE 5 -+ "write failed.", -+}; -+ -+ -+/* The main routine of `Pi' loader. */ -+int LoadPi(fname, pinfo) -+ char *fname; -+ PICINFO *pinfo; -+{ -+ struct pi_info pi; -+ int e; -+ int i; -+ if(DEBUG) fputs("LoadPi:\n", stderr); -+ -+ pinfo->comment = NULL; -+ pi_init_pi_info(&pi); -+ if((e = setjmp(pi.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ pi_cleanup_pi_info(&pi, 0); -+ pi_cleanup_pinfo(pinfo); -+ if(DEBUG) fputs("\n", stderr); -+ return 0; -+ } -+ -+ pi_open_file(&pi, fname); -+ pi_read_header(&pi, &pinfo->comment); -+ pi_expand(&pi, &pinfo->pic); -+ -+ pinfo->normw = pinfo->w = pi.width; -+ pinfo->normh = pinfo->h = pi.height; -+ pinfo->type = PIC8; -+ if(pi.numcols > 256) /* shouldn't happen. */ -+ pi.numcols = 256; -+ for(i = 0; i < pi.numcols; i++){ -+ pinfo->r[i] = pi.cmap[i * 3 ]; -+ pinfo->g[i] = pi.cmap[i * 3 + 1]; -+ pinfo->b[i] = pi.cmap[i * 3 + 2]; -+ } -+ pinfo->frmType = F_PI; -+ pinfo->colType = F_FULLCOLOR; -+ sprintf(pinfo->fullInfo, "Pi, %d colors (%ld bytes)", -+ pi.numcols, pi.fsize); -+ sprintf(pinfo->shrtInfo, "%dx%d Pi.", pi.width, pi.height); -+ normaspect = pi.aspect; -+ -+ pi_cleanup_pi_info(&pi, 0); -+ if(DEBUG) fputs("\n", stderr); -+ return 1; -+} -+ -+static void pi_open_file(pi, fname) -+ struct pi_info *pi; -+ char *fname; -+{ -+ if((pi->fp = fopen(fname, "rb")) == NULL) -+ pi_file_error(pi, PI_OPEN); -+ fseek(pi->fp, (size_t) 0, SEEK_END); -+ pi->fsize = ftell(pi->fp); -+ fseek(pi->fp, (size_t) 0, SEEK_SET); -+} -+ -+static void pi_read_header(pi, comm) -+ struct pi_info *pi; -+ char **comm; -+{ -+ byte buf[10]; -+ int mda; -+ int i; -+ -+ pi_check_id(pi); -+ pi_read_comment(pi, comm); -+ -+ if(fread(buf, (size_t) 10, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_CORRUPT); -+ -+ pi->mode = buf[0]; -+ pi->defcmap = pi->mode & 0x80; -+ if(buf[1] != 0 && buf[2] != 0) -+ pi->aspect = (float) buf[2] / (int) buf[1]; -+ pi->cbits = buf[3]; -+ pi->numcols = 1 << pi->cbits; -+ -+ if(pi->cbits != 4 && pi->cbits != 8) -+ pi_error(pi, PI_PLANES); -+ -+ mda = (int) buf[8] << 8 | (int) buf[9]; -+ for(i = 0; i < mda; i++){ -+ if(fgetc(pi->fp) == EOF) -+ pi_file_error(pi, PI_CORRUPT); -+ } -+ -+ if(fread(buf, (size_t) 4, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_CORRUPT); -+ pi->width = (int) buf[0] << 8 | (int) buf[1]; -+ pi->height = (int) buf[2] << 8 | (int) buf[3]; -+ -+ pi_read_palette(pi); -+ -+ if(DEBUG) pi_show_pi_info(pi); -+} -+ -+static void pi_check_id(pi) -+ struct pi_info *pi; -+{ -+ char buf[2]; -+ -+ if(fread(buf, (size_t) 2, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_CORRUPT); -+ if(strncmp(buf, pi_id, (size_t) 2) != 0) -+ pi_error(pi, PI_FORMAT); -+} -+ -+static void pi_read_comment(pi, comm) -+ struct pi_info *pi; -+ char **comm; -+{ -+/* -+ * The comment format is like: -+ * comment string `^Z' dummy string `\0' -+ */ -+ int max = -1, i = 0; -+ int c; -+ -+ while(1){ -+ if((c = fgetc(pi->fp)) == EOF) -+ pi_file_error(pi, PI_CORRUPT); -+ if(c == '\032') /* 0x1a, '^Z' */ -+ break; -+ if(max < i){ -+ max += 32; -+ *comm = pi_realloc(*comm, (size_t) max + 1, "pi_read_comment(1)"); -+ } -+ (*comm)[i++] = c; -+ } -+ if(max < i){ -+ max++; -+ *comm = pi_realloc(*comm, (size_t) max + 1, "pi_read_comment(2)"); -+ } -+ (*comm)[i] = '\0'; -+ -+ while((c = fgetc(pi->fp)) != '\0'){ /* skip the dummy area */ -+ if(c == EOF) -+ pi_file_error(pi, PI_CORRUPT); -+ } -+} -+ -+static void pi_read_palette(pi) -+ struct pi_info *pi; -+{ -+ pi->cmap = pi_malloc((size_t) pi->numcols * 3, "pi_read_palette"); -+ if(pi->mode & 0x80){ -+ if(pi->numcols == 16){ -+ int i; -+ byte on; -+ -+ on = 0x77; -+ for(i = 0; i < 8; i++){ -+ pi->cmap[i * 3 ] = i & 2 ? on : 0; -+ pi->cmap[i * 3 + 1] = i & 4 ? on : 0; -+ pi->cmap[i * 3 + 2] = i & 1 ? on : 0; -+ } -+ on = 0xff; -+ for(; i < 16; i++){ -+ pi->cmap[i * 3 ] = i & 2 ? on : 0; -+ pi->cmap[i * 3 + 1] = i & 4 ? on : 0; -+ pi->cmap[i * 3 + 2] = i & 1 ? on : 0; -+ } -+ }else{ /* pi->numcols == 256 */ -+ int i; -+ byte r, g, b; -+ r = g = b = 0; -+ for(i = 0; i < 256; i++){ -+ pi->cmap[i * 3 ] = r; -+ pi->cmap[i * 3 + 1] = g; -+ pi->cmap[i * 3 + 2] = b; -+ if((b += 0x40) == 0){ -+ if((r += 0x20) == 0) -+ g += 0x20; -+ } -+ } -+ } -+ }else{ -+ if(fread(pi->cmap, (size_t) pi->numcols * 3, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_CORRUPT); -+ } -+} -+ -+/* The main routine to expand `Pi' file. */ -+static void pi_expand(pi, pic) -+ struct pi_info *pi; -+ byte **pic; -+{ -+ byte prev_col = 0; -+ int prev_pos = -1; -+ int cnt = 0, max_cnt = pi->width * pi->height; -+ -+ *pic = pi_malloc((size_t) max_cnt, "pi_expand"); // GRR POSSIBLE OVERFLOW / FIXME -+ -+ pi_table_create(pi); -+ -+ if(pi->width > 2){ -+ (*pic)[0] = pi_read_color(pi, 0); -+ (*pic)[1] = pi_read_color(pi, (*pic)[0]); -+ -+ while(cnt < max_cnt){ -+ int pos = pi_read_position(pi); -+ if(pos != prev_pos){ -+ data32 len = pi_read_length(pi); -+ cnt = pi_copy_pixels(pi, *pic, cnt, pos, len); -+ prev_col = (*pic)[cnt - 1]; -+ prev_pos = pos; -+ }else{ -+ do{ -+ prev_col = pi_read_color(pi, (int) prev_col); -+ (*pic)[cnt++] = prev_col; -+ prev_col = pi_read_color(pi, (int) prev_col); -+ (*pic)[cnt++] = prev_col; -+ }while(pi_read_bits(pi, 1) == 1); -+ -+ prev_pos = -1; -+ } -+ } -+ }else{ -+ while(cnt < max_cnt){ -+ prev_col = pi_read_color(pi, (int) prev_col); -+ (*pic)[cnt++] = prev_col; -+ } -+ } -+} -+ -+static byte pi_read_color(pi, prev) -+ struct pi_info *pi; -+ int prev; -+{ -+ byte n; -+ if(pi->cbits == 4){ -+ if(pi_read_bits(pi, 1) == 1) -+ n = pi_read_bits(pi, 1); /* 1x */ -+ else{ -+ if(pi_read_bits(pi, 1) == 0) -+ n = pi_read_bits(pi, 1) + 2; /* 00x */ -+ else{ -+ if(pi_read_bits(pi, 1) == 0) -+ n = pi_read_bits(pi, 2) + 4; /* 010xx */ -+ else -+ n = pi_read_bits(pi, 3) + 8; /* 011xxx */ -+ } -+ } -+ }else{ /* cbits == 8 */ -+ if(pi_read_bits(pi, 1) == 1) -+ n = pi_read_bits(pi, 1); -+ else{ -+ int bits = 0; -+ byte base = 2; -+ while(bits < 6){ -+ if(pi_read_bits(pi, 1) == 0) -+ break; -+ bits++; -+ base <<= 1; -+ } -+ n = pi_read_bits(pi, bits + 1) + base; -+ } -+ } -+ -+ return pi_table_get_value(pi, prev, (int) n); -+} -+ -+static int pi_read_position(pi) -+ struct pi_info *pi; -+{ -+ byte r; -+ if((r = pi_read_bits(pi, 2)) != 3) -+ return (int) r; -+ else -+ return (int) pi_read_bits(pi, 1) + 3; -+} -+ -+static data32 pi_read_length(pi) -+ struct pi_info *pi; -+{ -+ data32 r = 1; -+ int bits = 0; -+ while(pi_read_bits(pi, 1) == 1){ -+ r <<= 1; -+ bits++; -+ } -+ if(bits > 0) -+ return r + pi_read_bits(pi, bits); -+ return 1; -+} -+ -+static int pi_copy_pixels(pi, pic, cnt, pos, len) -+ struct pi_info *pi; -+ byte *pic; -+ int cnt, pos; -+ data32 len; -+{ -+ int s = 0, d = cnt; -+ int max = pi->width * pi->height; -+ switch(pos){ -+ case 0: -+ if(cnt < 2){ -+ if(pic[0] == pic[1]) -+ s = cnt - 2; -+ else -+ s = cnt - 4; -+ }else{ -+ if(pic[cnt - 2] == pic[cnt - 1]) -+ s = cnt - 2; -+ else -+ s = cnt - 4; -+ } -+ break; -+ case 1: -+ s = cnt - pi->width; -+ break; -+ case 2: -+ s = cnt - pi->width * 2; -+ break; -+ case 3: -+ s = cnt - pi->width + 1; -+ break; -+ case 4: -+ s = cnt - pi->width - 1; -+ } -+ -+ len *= 2; -+ while(s < 0 && len != 0 && d < max){ -+ pic[d++] = pic[-(s++) % 2]; -+ len--; -+ } -+ while(len != 0 && d < max){ -+ pic[d++] = pic[s++]; -+ len--; -+ } -+ return d; -+} -+ -+/* The main routine of `Pi' saver. */ -+int WritePi(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle, -+ comment) -+ FILE *fp; -+ byte *pic; -+ int ptype, w, h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+ char *comment; -+{ -+ byte rtemp[256], gtemp[256], btemp[256]; -+ struct pi_info pi; -+ int e; -+ -+ if(DEBUG) fputs("WritePi\n", stderr); -+ pi_init_pi_info(&pi); -+ pi.fp = fp; -+ pi.width = w; -+ pi.height = h; -+ pi.writing_grey = (colorstyle == F_GREYSCALE); -+ if(ptype == PIC24){ -+ if(!(pic = Conv24to8(pic, w, h, 256, rtemp, gtemp, btemp))) -+ pi_memory_error("Conv24to8", "WritePi"); -+ rmap = rtemp; -+ gmap = gtemp; -+ bmap = btemp; -+ numcols = 256; -+ } -+ -+ if((e = setjmp(pi.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ pi_cleanup_pi_info(&pi, 1); -+ if(DEBUG) fputs("\n", stderr); -+ return -1; -+ } -+ -+ pi.numcols = numcols; -+ pi_write_header(&pi, comment, rmap, gmap, bmap); -+ pi_compress(&pi, pic); -+ pi_write_gabage(&pi); -+ -+ pi_cleanup_pi_info(&pi, 1); -+ if(DEBUG) fputs("\n", stderr); -+ return 0; -+} -+ -+static void pi_write_header(pi, comm, r, g, b) -+ struct pi_info *pi; -+ char *comm; -+ byte *r, *g, *b; -+{ -+ byte buf[14]; -+ -+ if(DEBUG) pi_show_pi_info(pi); -+ -+ pi_write_id(pi); -+ pi_write_comment(pi, comm); -+ -+ buf[0] = buf[1] = buf[2] = 0; -+ buf[3] = pi->cbits = pi->numcols > 16 ? 8 : 4; -+ buf[4] = 'X'; -+ buf[5] = 'V'; -+ buf[6] = ' '; -+ buf[7] = ' '; -+ buf[8] = buf[9] = 0; -+ buf[10] = pi->width >> 8; -+ buf[11] = pi->width; -+ buf[12] = pi->height >> 8; -+ buf[13] = pi->height; -+ if(fwrite(buf, (size_t) 14, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+ -+ pi_write_palette(pi, r, g, b); -+} -+ -+static void pi_write_id(pi) -+ struct pi_info *pi; -+{ -+ if(fwrite(pi_id, (size_t) 2, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+} -+ -+static void pi_write_comment(pi, comm) -+ struct pi_info *pi; -+ char *comm; -+{ -+ if(comm){ -+ int i; -+ for(i = 0; comm[i]; i++){ -+ if(comm[i] == '\032') /* 0x1a, '^Z' */ -+ comm[i] = ' '; -+ } -+ if(i > 0){ -+ if(fwrite(comm, (size_t) i, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+ } -+ } -+ -+ if(fwrite("\032\0", (size_t) 2, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+} -+ -+static void pi_write_palette(pi, r, g, b) -+ struct pi_info *pi; -+ byte *r, *g, *b; -+{ -+ int i; -+ int pinum = 1 << pi->cbits; -+ char buf[3]; -+ -+ for(i = 0; i < pi->numcols; i++){ -+ buf[0] = *r++; -+ buf[1] = *g++; -+ buf[2] = *b++; -+ if(pi->writing_grey) -+ buf[0] = buf[1] = buf[2] = MONO(buf[0], buf[1], buf[2]); -+ if(fwrite(buf, (size_t) 3, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+ } -+ for( ; i < pinum; i++){ -+ if(fwrite(buf, (size_t) 3, (size_t) 1, pi->fp) != 1) -+ pi_file_error(pi, PI_WRITE); -+ } -+ pi->numcols = pinum; -+} -+ -+/* The main routine to compress `Pi' format. */ -+static void pi_compress(pi, pic) -+ struct pi_info *pi; -+ byte *pic; -+{ -+ byte prev_col = 0; -+ int prev_pos = -1; -+ int cnt = 0, max_cnt = pi->width * pi->height; -+ pi_table_create(pi); -+ -+ if(pi->width > 2){ -+ int pos; -+ data32 len; -+ -+ pi_write_color(pi, 0, pic[0]); -+ pi_write_color(pi, pic[0], pic[1]); -+ pos = pi_test_matching(pi, pic, prev_pos, cnt, &len); -+ while(cnt < max_cnt){ -+ if(pos >= 0){ -+ pi_write_position(pi, pos); -+ pi_write_length(pi, len); -+ if((cnt += len * 2) >= max_cnt) -+ break; -+ prev_col = pic[cnt - 1]; -+ prev_pos = pos; -+ pos = pi_test_matching(pi, pic, prev_pos, cnt, &len); -+ }else{ -+ pi_write_position(pi, prev_pos); -+ prev_pos = -1; -+ while(pos < 0){ -+ pi_write_color(pi, (int) prev_col, pic[cnt]); -+ prev_col = pic[cnt]; -+ if(++cnt >= max_cnt) -+ break; -+ pi_write_color(pi, (int) prev_col, pic[cnt]); -+ prev_col = pic[cnt]; -+ if(++cnt >= max_cnt) -+ break; -+ pos = pi_test_matching(pi, pic, -1, cnt, &len); -+ if(pos < 0) -+ pi_write_bits(pi, 1, 1); -+ else -+ pi_write_bits(pi, 0, 1); -+ } -+ } -+ } -+ }else{ -+ while(cnt < max_cnt){ -+ pi_write_color(pi, (int) prev_col, pic[cnt]); -+ prev_col = pic[cnt++]; -+ } -+ } -+} -+ -+static void pi_write_gabage(pi) -+ struct pi_info *pi; -+{ -+ pi_write_bits(pi, 0, 32); -+} -+ -+static void pi_write_color(pi, prev, col) -+ struct pi_info *pi; -+ int prev, col; -+{ -+ int n = pi_table_lookup_value(pi, prev, col); -+ -+ if(pi->cbits == 4){ -+ if(n < 2) -+ pi_write_bits(pi, (data32) n | 2, 2); -+ else if(n < 4) -+ pi_write_bits(pi, (data32) n - 2, 3); -+ else if(n < 8) -+ pi_write_bits(pi, (data32) (n - 4) | 8, 5); -+ else -+ pi_write_bits(pi, (data32) (n - 8) | 24, 6); -+ }else{ /* cbits == 8 */ -+ if(n < 2){ -+ pi_write_bits(pi, (data32) n | 2, 2); -+ }else{ -+ int bits = 0; -+ byte base = 2; -+ while(bits < 6){ -+ if(n < (int) base * 2) -+ break; -+ bits++; -+ base <<= 1; -+ } -+ pi_write_bits(pi, 0, 1); -+ if(bits > 0) -+ pi_write_bits(pi, 0xffffffff, bits); -+ if(bits < 6) -+ pi_write_bits(pi, 0, 1); -+ pi_write_bits(pi, (data32) n - base, bits + 1); -+ } -+ } -+} -+ -+static int pi_test_matching(pi, pic, prev, cnt, len) -+ struct pi_info *pi; -+ byte *pic; -+ int prev, cnt; -+ data32 *len; -+{ -+ data32 lens[5]; -+ int pos, p; -+ int s, d = 0; -+ int max = pi->width * pi->height; -+ -+ for(pos = 0; pos < 5; pos++){ -+ switch(pos){ -+ case 0: -+ if(cnt < 2){ -+ if(pic[0] == pic[1]) -+ d = cnt - 2; -+ else -+ d = cnt - 4; -+ }else{ -+ if(pic[cnt - 2] == pic[cnt - 1]) -+ d = cnt - 2; -+ else -+ d = cnt - 4; -+ } -+ break; -+ case 1: -+ d = cnt - pi->width; -+ break; -+ case 2: -+ d = cnt - pi->width * 2; -+ break; -+ case 3: -+ d = cnt - pi->width + 1; -+ break; -+ case 4: -+ d = cnt - pi->width - 1; -+ } -+ s = cnt; -+ lens[pos] = 0; -+ -+ if(prev == 0 && pos == 0) -+ continue; -+ -+ while(d < max){ -+ if(pic[(d < 0) ? (-d) % 2 : d] != pic[s]) -+ break; -+ lens[pos]++; -+ d++; -+ s++; -+ } -+ -+ } -+ -+ for(pos = 0, p = 1; p < 5; p++){ -+ if(lens[p] >= lens[pos]) -+ pos = p; -+ } -+ -+ if(lens[pos] / 2 == 0) -+ return -1; -+ *len = lens[pos] / 2; -+ return pos; -+} -+ -+static void pi_write_position(pi, pos) -+ struct pi_info *pi; -+ int pos; -+{ -+ switch(pos){ -+ case 0: -+ pi_write_bits(pi, 0, 2); -+ break; -+ case 1: -+ pi_write_bits(pi, 1, 2); -+ break; -+ case 2: -+ pi_write_bits(pi, 2, 2); -+ break; -+ case 3: -+ pi_write_bits(pi, 6, 3); -+ break; -+ case 4: -+ pi_write_bits(pi, 7, 3); -+ break; -+ } -+} -+ -+static void pi_write_length(pi, len) -+ struct pi_info *pi; -+ data32 len; -+{ -+ int bits = 0; -+ data32 base = 1; -+ -+ while(len >= base * 2){ -+ bits++; -+ base <<= 1; -+ } -+ if(bits > 0){ -+ pi_write_bits(pi, 0xffffffff, bits); -+ pi_write_bits(pi, 0, 1); -+ pi_write_bits(pi, len - base, bits); -+ }else -+ pi_write_bits(pi, 0, 1); -+} -+ -+/* -+ * These pi_table_* functions manipulate the color table. -+ * pi_table_create: -+ * allocates and initializes a color table. -+ * pi_table_get_value: -+ * get the specified value, and move it to the top of the list. -+ * pi_table_lookup_value: -+ * look up the specified value, and move it to the top of the list. -+ */ -+static void pi_table_create(pi) -+ struct pi_info *pi; -+{ -+ struct ct_t *t; -+ int i; -+ byte mask = pi->numcols - 1; -+ pi->ct = pi_malloc(sizeof *pi->ct * pi->numcols, "pi_table_create(1)"); -+ for(i = 0, t = pi->ct; i < pi->numcols; i++, t++){ -+ int j; -+ byte v = i; -+ t->elt = pi_malloc(sizeof *t->elt * pi->numcols, "pi_table_create(2)"); -+ t->top = &t->elt[pi->numcols - 1]; -+ for(j = 0; j < pi->numcols; j++){ -+ v = (v + 1) & mask; -+ if(j > 0) -+ t->elt[j].old = &t->elt[j - 1]; -+ else -+ t->elt[0].old = t->top; -+ if(j < pi->numcols - 1) -+ t->elt[j].recent = &t->elt[j + 1]; -+ else -+ t->elt[j].recent = &t->elt[0]; -+ t->elt[j].val = v; -+ } -+ t->elt[0].old = t->top; -+ t->top->recent = &t->elt[0]; -+ } -+} -+ -+static byte pi_table_get_value(pi, left, num) -+ struct pi_info *pi; -+ int left, num; -+{ -+ struct ct_t *t = &pi->ct[left]; -+ struct elt_t *e = t->top; -+ if(left >= pi->numcols || num >= pi->numcols) -+ abort(); -+ if(num != 0){ -+ do { -+ e = e->old; -+ }while(--num != 0); -+ -+ e->old->recent = e->recent; -+ e->recent->old = e->old; -+ -+ e->recent = t->top->recent; -+ e->recent->old = e; -+ e->old = t->top; -+ t->top->recent = e; -+ -+ t->top = e; -+ } -+ return e->val; -+} -+ -+static int pi_table_lookup_value(pi, left, v) -+ struct pi_info *pi; -+ int left, v; -+{ -+ struct ct_t *t = &pi->ct[left]; -+ struct elt_t *e = t->top; -+ int num = 0; -+ -+ if(left >= pi->numcols || v >= pi->numcols) -+ abort(); -+ -+ while(e->val != v){ -+ e = e->old; -+ num++; -+ } -+ -+ if(num != 0){ -+ e->old->recent = e->recent; -+ e->recent->old = e->old; -+ -+ e->recent = t->top->recent; -+ e->recent->old = e; -+ e->old = t->top; -+ t->top->recent = e; -+ -+ t->top = e; -+ } -+ -+ return num; -+} -+ -+/* -+ * These 2 functions read or write to a bit stream. -+ * pi_read_bits: -+ * reads a specified-bit data from the bit stream. -+ * pi_write_bits: -+ * writes a specified-bit data to the bit stream. -+ */ -+static data32 pi_read_bits(pi, numbits) -+ struct pi_info *pi; -+ int numbits; -+{ -+ data32 r = 0; -+ -+ while(numbits > 0){ -+ while(pi->bs.rest > 0 && numbits > 0){ -+ r = (r << 1) | (pi->bs.cur & 0x80 ? 1 : 0); -+ pi->bs.cur <<= 1; -+ pi->bs.rest--; -+ numbits--; -+ } -+ if(numbits > 0){ -+ int c; -+ if((c = fgetc(pi->fp)) == EOF) -+ pi_file_warning(pi, PI_CORRUPT); -+ pi->bs.cur = c; -+ pi->bs.rest = 8; -+ } -+ } -+ -+ return r; -+} -+ -+static void pi_write_bits(pi, dat, bits) -+ struct pi_info *pi; -+ data32 dat; -+ int bits; -+{ -+ data32 dat_mask = 1 << (bits - 1); -+ while(bits > 0){ -+ while(pi->bs.rest < 8 && bits > 0){ -+ pi->bs.cur <<= 1; -+ if(dat & dat_mask) -+ pi->bs.cur |= 1; -+ pi->bs.rest++; -+ bits--; -+ dat_mask >>= 1; -+ } -+ if(pi->bs.rest >= 8){ -+ if(fputc((int)pi->bs.cur, pi->fp) == EOF) -+ pi_file_error(pi, PI_WRITE); -+ pi->bs.cur = 0; -+ pi->bs.rest = 0; -+ } -+ } -+} -+ -+/* -+ * The routines to initialize or clean up. -+ * pi_inif_pi_info: -+ * initializes a pi_info structure. -+ * pi_cleanup_pi_info: -+ * cleanup pi_info structure. It frees allocated memories. -+ * pi_cleanup_pinfo: -+ * cleanup PICINFO structure when an error occurs. -+ */ -+static void pi_init_pi_info(pi) -+ struct pi_info *pi; -+{ -+ pi->fp = NULL; -+ pi->bs.rest = 0; -+ pi->bs.cur = 0; -+ pi->fsize = 0; -+ pi->mode = 0; -+ pi->width = pi->mode = 0; -+ pi->aspect = 1.0; -+ pi->cbits = 0; -+ pi->numcols = 0; -+ pi->cmap = NULL; -+ pi->ct = NULL; -+ pi->defcmap = 0; -+ pi->writing_grey = 0; -+} -+ -+static void pi_cleanup_pi_info(pi, writing) -+ struct pi_info *pi; -+ int writing; -+{ -+ if(pi->fp && !writing){ -+ fclose(pi->fp); -+ pi->fp = NULL; -+ } -+ if(pi->cmap){ -+ free(pi->cmap); -+ pi->cmap = NULL; -+ } -+ if(pi->ct){ -+ int i; -+ for(i = 0; i < pi->numcols; i++) -+ free(pi->ct[i].elt); -+ free(pi->ct); -+ pi->ct = NULL; -+ } -+} -+ -+static void pi_cleanup_pinfo(pinfo) -+ PICINFO *pinfo; -+{ -+ if(pinfo->pic){ -+ free(pinfo->pic); -+ pinfo->pic = NULL; -+ } -+ if(pinfo->comment){ -+ free(pinfo->comment); -+ pinfo->comment = NULL; -+ } -+} -+ -+/* -+ * Error handling routins. -+ * pi_memory_error: -+ * shows a error message, and terminates. -+ * pi_error: -+ * shows a non-file error message. -+ * pi_file_error: -+ * shows a file error message. -+ */ -+static void pi_memory_error(scm, fn) -+ char *scm, *fn; -+{ -+ char buf[128]; -+ sprintf(buf, "%s: couldn't allocate memory. (%s)", scm ,fn); -+ FatalError(buf); -+} -+ -+static void pi_error(pi, mn) -+ struct pi_info *pi; -+ int mn; -+{ -+ SetISTR(ISTR_WARNING, "%s", pi_msgs[mn]); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pi_file_error(pi, mn) -+ struct pi_info *pi; -+ int mn; -+{ -+ if(feof(pi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", pi_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", pi_msgs[mn], ERRSTR(errno)); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pi_file_warning(pi, mn) -+ struct pi_info *pi; -+ int mn; -+{ -+ if(feof(pi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", pi_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", pi_msgs[mn], ERRSTR(errno)); -+} -+ -+static void pi_show_pi_info(pi) -+ struct pi_info *pi; -+{ -+ fprintf(stderr, " file size: %ld.\n", pi->fsize); -+ fprintf(stderr, " mode: 0x%02x.\n", pi->mode); -+ fprintf(stderr, " image size: %dx%d.\n", pi->width, pi->height); -+ fprintf(stderr, " aspect: %f.\n", pi->aspect); -+ fprintf(stderr, " number of color bits: %d.\n", pi->cbits); -+ fprintf(stderr, " number of colors: %d.\n", pi->numcols); -+ fprintf(stderr, " using default colormap: %s.\n", -+ pi->defcmap ? "true" : "false"); -+ fprintf(stderr, " writing greyscale image: %s.\n", -+ pi->writing_grey ? "true" : "false"); -+} -+ -+/* -+ * Memory related routines. If failed, they calls pi_memory_error. -+ */ -+static void *pi_malloc(n, fn) -+ size_t n; -+ char *fn; -+{ -+ void *r = (void *) malloc(n); -+ if(r == NULL) -+ pi_memory_error("malloc", fn); -+ return r; -+} -+ -+static void *pi_realloc(p, n, fn) -+ void *p; -+ size_t n; -+ char *fn; -+{ -+ void *r = (p == NULL) ? (void *) malloc(n) : (void *) realloc(p, n); -+ if(r == NULL) -+ pi_memory_error("realloc", fn); -+ return r; -+} -+#endif /* HAVE_PI */ -diff -ruN xv-3.10a-bugfixes/xvpic.c xv-3.10a-enhancements/xvpic.c ---- xv-3.10a-bugfixes/xvpic.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvpic.c 2005-04-17 22:57:08.000000000 -0700 -@@ -0,0 +1,1285 @@ -+/* -+ * xvpic.c - load routine for `PIC' format pictures. -+ * -+ * The `PIC' format is used by many Japanese personal computer users. -+ */ -+ -+#include "xv.h" -+#include <setjmp.h> -+ -+#ifdef HAVE_PIC -+ -+typedef unsigned short data16; -+typedef unsigned int data32; -+ -+struct pic_info { -+ jmp_buf jmp; -+ FILE *fp; -+ struct { -+ int rest; -+ byte cur; -+ }bs; -+ long fsize; -+ int type, mode; -+ int width, height; -+ float aspect; -+ int cbits; -+ int cmapped; -+ byte *cmap; -+ int cached; -+ struct cache_t { -+ int newest; -+ struct cachenode_t { -+ data32 dat; -+ int newer, older; -+ } *node; -+ } cache; -+ int g_bits, r_bits, b_bits, i_bits; -+ int inv_gr; -+ int tiled256; -+ int numcols; -+ int writing_grey; -+ data32 *data; -+}; -+ -+static void pic_open_file PARM((struct pic_info*,char*)); -+static void pic_check_id PARM((struct pic_info*)); -+static void pic_read_comment PARM((struct pic_info*, char**)); -+static void pic_read_header PARM((struct pic_info*)); -+static void pic_expand_data PARM((struct pic_info*)); -+static int pic_expanding_read_len PARM((struct pic_info*)); -+static data32 pic_expanding_read_color PARM((struct pic_info*)); -+static void pic_expanding_read_chain -+ PARM((struct pic_info*, int, int, data32)); -+static void pic_make_xvpic -+ PARM((struct pic_info*, byte**, byte*, byte*, byte*)); -+ -+static void pic_write_id PARM((struct pic_info*)); -+static void pic_write_comment PARM((struct pic_info*, char*)); -+static void pic_write_header PARM((struct pic_info*)); -+static void pic_write_palette -+ PARM((struct pic_info*, byte*, byte*, byte*)); -+static void pic_make_sparse_data PARM((struct pic_info*, byte*)); -+static void pic_write_data PARM((struct pic_info*)); -+static void pic_write_length PARM((struct pic_info*, data32)); -+static void pic_write_color PARM((struct pic_info*, data32)); -+static void pic_write_chain -+ PARM((struct pic_info*, int, int, data32)); -+ -+static data32 pic_read_rgb PARM((struct pic_info*)); -+static data32 pic_read_color_code PARM((struct pic_info*)); -+static void pic_write_rgb PARM((struct pic_info*, data32)); -+static void pic_write_color_code PARM((struct pic_info*, data32)); -+ -+static void pic_cache_init PARM((struct pic_info*)); -+static data32 pic_cache_get_value PARM((struct pic_info*, int)); -+static void pic_cache_add_value PARM((struct pic_info*, data32)); -+static int pic_cache_lookup PARM((struct pic_info*, data32)); -+ -+static data32 pic_read_bits PARM((struct pic_info*, int)); -+static void pic_write_bits PARM((struct pic_info*, data32, int)); -+static byte pic_pad_bit PARM((int, data32)); -+ -+static void pic_init_info PARM((struct pic_info*)); -+static void pic_cleanup_pic_info PARM((struct pic_info*, int)); -+static void pic_cleanup_pinfo PARM((PICINFO*)); -+static void pic_memory_error PARM((char*, char*)); -+static void pic_error PARM((struct pic_info*, int)); -+static void pic_file_error PARM((struct pic_info*, int)); -+static void pic_file_warning PARM((struct pic_info*, int)); -+static void pic_show_pic_info PARM((struct pic_info*)); -+static void *pic_malloc PARM((size_t, char*)); -+static void *pic_realloc PARM((void*, size_t, char*)); -+ -+ -+static char *pic_id = "PIC"; -+ -+/* Error Messages */ -+static char *pic_msgs[] = { -+ NULL, -+#define PIC_OPEN 1 -+ "can't open file.", -+#define PIC_CORRUPT 2 -+ "file corrupted.", -+#define PIC_FORMAT 3 -+ "not PIC format.", -+#define PIC_SUPPORT 4 -+ "unsupported type.", -+#define PIC_COMMENT 5 -+ "can't read comment.", -+#define PIC_TYPE 6 -+ "bad machine type.", -+#define PIC_MODE 7 -+ "bad machine-dependent mode.", -+#define PIC_NUM_COLORS 8 -+ "bad number of colors.", -+#define PIC_SIZE 9 -+ "bad size.", -+#define PIC_ASPECT 10 -+ "bad aspect.", -+#define PIC_WRITE 11 -+ "write failed.", -+}; -+ -+#define H4(b) (((b) >> 4) & 0x0f) -+#define L4(b) ( (b) & 0x0f) -+ -+ -+/* The main routine to load a PIC file. */ -+int LoadPIC(fname, pinfo) -+ char *fname; -+ PICINFO *pinfo; -+{ -+ int e; -+ struct pic_info pic; -+ char buf[128]; -+ -+ if(DEBUG) fputs("LoadPIC:\n", stderr); -+ -+ pic_init_info(&pic); -+ -+ pinfo->comment = NULL; -+ if((e = setjmp(pic.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ pic_cleanup_pic_info(&pic, 0); -+ pic_cleanup_pinfo(pinfo); -+ if(DEBUG) fputs("\n", stderr); -+ return 0; -+ } -+ -+ pic_open_file(&pic, fname); -+ pic_check_id(&pic); -+ pic_read_comment(&pic, &pinfo->comment); -+ pic_read_header(&pic); -+ pic_expand_data(&pic); -+ pic_make_xvpic(&pic, &pinfo->pic, pinfo->r, pinfo->g, pinfo->b); -+ -+ pinfo->w = pic.width; -+ if(pic.tiled256) -+ pinfo->h = pic.height * 2; -+ else -+ pinfo->h = pic.height; -+ pinfo->normw = pinfo->w; -+ pinfo->normh = pinfo->h; -+ pinfo->type = pic.cmapped ? PIC8 : PIC24; -+ pinfo->frmType = F_PIC; -+ pinfo->colType = F_FULLCOLOR; -+ strcpy(pinfo->fullInfo, "PIC"); -+ switch(pic.type){ -+ case 0x0: -+ strcat(pinfo->fullInfo, ", X68k"); -+ break; -+ case 0x1: -+ strcat(pinfo->fullInfo, ", PC-88VA"); -+ if(pic.mode & 1) -+ strcat(pinfo->fullInfo, ", HR"); -+ if(pic.mode & 2) -+ strcat(pinfo->fullInfo, ", tiled 256"); -+ break; -+ case 0x2: -+ strcat(pinfo->fullInfo, ", FM-TOWNS"); -+ if(pic.mode == 0x5){ -+ strcat(pinfo->fullInfo, ", low-resolution"); -+ }else{ -+ strcat(pinfo->fullInfo, ", high-resolution"); -+ } -+ break; -+ case 0x3: -+ strcat(pinfo->fullInfo, ", Macintosh"); -+ break; -+ case 0xf: -+ ; -+ } -+ sprintf(buf, " (%ld bytes)", pic.fsize); -+ strcat(pinfo->fullInfo, buf); -+ sprintf(pinfo->shrtInfo, "%dx%d(aspect %4.2f) PIC.", -+ pinfo->w, pinfo->h, pic.aspect); -+ if (!nopicadjust) -+ normaspect = pic.aspect; -+ -+ pic_cleanup_pic_info(&pic, 0); -+ if(DEBUG) fputs("\n", stderr); -+ return 1; -+} -+ -+static void pic_open_file(pi, fname) -+ struct pic_info *pi; -+ char *fname; -+{ -+ if((pi->fp = fopen(fname, "rb")) == NULL) -+ pic_file_error(pi, PIC_OPEN); -+ fseek(pi->fp, (size_t) 0, SEEK_END); -+ pi->fsize = ftell(pi->fp); -+ fseek(pi->fp, (size_t) 0, SEEK_SET); -+} -+ -+static void pic_check_id(pi) -+ struct pic_info *pi; -+{ -+ char buf[3]; -+ if(fread(buf, (size_t) 3, (size_t) 1, pi->fp) != 1) -+ pic_file_error(pi, PIC_CORRUPT); -+ if(strncmp(buf, pic_id, (size_t) 3) != 0) -+ pic_error(pi, PIC_FORMAT); -+} -+ -+static void pic_read_comment(pi, comm) -+ struct pic_info *pi; -+ char **comm; -+{ -+ /* The comment field is like: -+ * comment-string ^Z dummy \0 \0 -+ */ -+ int max = -1, i = 0; -+ int c; -+ -+ while(1){ -+ if((c = fgetc(pi->fp)) == EOF) -+ pic_file_error(pi, PIC_CORRUPT); -+ if(c == '\032') /* 0x1a, '^Z' */ -+ break; -+ if(max < i){ -+ max += 32; -+ *comm = pic_realloc(*comm, (size_t) max + 1, "pic_read_comment#1"); -+ } -+ (*comm)[i++] = c; -+ } -+ -+ if(max < i){ -+ max++; -+ *comm = pic_realloc(*comm, (size_t) max + 1, "pic_read_comment#2"); -+ } -+ (*comm)[i] = '\0'; -+ -+ while((c = fgetc(pi->fp)) != '\0'){ /* skip the dummy area */ -+ if(c == EOF) -+ pic_file_error(pi, PIC_CORRUPT); -+ } -+ -+ if(fgetc(pi->fp) != '\0') /* check the reserved byte */ -+ pic_error(pi, PIC_SUPPORT); -+} -+ -+static void pic_read_header(pi) -+ struct pic_info *pi; -+{ -+ pi->mode = pic_read_bits(pi, 4); -+ pi->type = pic_read_bits(pi, 4); -+ pi->cbits = pic_read_bits(pi, 16); -+ pi->width = pic_read_bits(pi, 16); -+ pi->height = pic_read_bits(pi, 16); -+ -+ /* machine-dependent setup. */ -+ switch(pi->type){ -+ case 0x0: /* X68K */ -+ if(pi->mode != 0) -+ pic_error(pi, PIC_MODE); -+ switch(pi->cbits){ -+ case 4: -+ pi->aspect = 1.0; -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->i_bits = 1; -+ pi->cmapped = 1; -+ break; -+ -+ case 8: -+ pi->aspect = 4.0 / 3.0; -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->i_bits = 1; -+ pi->cmapped = 1; -+ break; -+ -+ case 15: -+ pi->aspect = 4.0 / 3.0; -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->cached = 1; -+ break; -+ -+ case 16: -+ pi->aspect = 4.0 / 3.0; -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->i_bits = 1; -+ pi->cached = 1; -+ break; -+ -+ default: -+ pic_error(pi, PIC_NUM_COLORS); -+ } -+ break; -+ -+ case 0x1: /* PC-88VA */ -+ if(pi->height > 1000) -+ pic_error(pi, PIC_SIZE); -+ switch(pi->width * 1000 + pi->height){ -+ case 640400: -+ case 640204: -+ case 640200: -+ case 320408: -+ case 320400: -+ case 320200: -+ break; -+ default: -+ pic_error(pi, PIC_SIZE); -+ } -+ pi->aspect = 400.0 / pi->height; -+ pi->aspect *= pi->width / 640.0; -+ if(pi->mode & 0x1) /* HR mode */ -+ pi->aspect *= 2.0; -+ if(pi->mode & 0x2){ /* tiled 256 format */ -+ if(pi->cbits != 16) -+ pic_error(pi, PIC_NUM_COLORS); -+ pi->tiled256 = 1; -+ } -+ switch(pi->cbits){ -+ case 8: -+ pi->g_bits = pi->r_bits = 3; -+ pi->b_bits = 2; -+ break; -+ -+ case 12: -+ pi->g_bits = pi->r_bits = pi->b_bits = 4; -+ pi->cached = 1; -+ break; -+ -+ case 16: -+ pi->g_bits = 6; -+ pi->r_bits = pi->b_bits = 5; -+ pi->cached = 1; -+ break; -+ -+ default: -+ pic_error(pi, PIC_NUM_COLORS); -+ } -+ break; -+ -+ case 0x2: /* FM-TOWNS */ -+ if(pi->cbits != 15) -+ pic_error(pi, PIC_NUM_COLORS); -+ switch(pi->mode){ -+ case 0x5: -+ case 0xc: -+ break; -+ default: -+ pic_error(pi, PIC_MODE); -+ } -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->cached = 1; -+ break; -+ -+ case 0x3: /* MAC */ -+ if(pi->cbits != 15) -+ pic_error(pi, PIC_NUM_COLORS); -+ pi->r_bits = pi->g_bits = pi->b_bits = 5; -+ pi->inv_gr = 1; -+ break; -+ -+ case 0xf: /* misc */ -+ { -+ byte ah, al; -+ -+ switch(pi->mode){ -+ case 0x0: -+ break; -+ case 0x1: -+ pi->aspect = 4.0 / 3.0; -+ break; -+ case 0xf: -+ break; -+ default: -+ pic_error(pi, PIC_MODE); -+ } -+ pic_read_bits(pi, 16); /* x */ -+ pic_read_bits(pi, 16); /* y */ -+ ah = pic_read_bits(pi, 8); -+ al = pic_read_bits(pi, 8); -+ if(ah > 0 && al > 0) -+ pi->aspect = (float) al / (int) ah; -+ else if(pi->mode == 0xf) -+ pic_error(pi, PIC_ASPECT); -+ switch(pi->cbits){ -+ case 4: -+ case 8: -+ pi->g_bits = pi->r_bits = pi->b_bits = pic_read_bits(pi, 8); -+ pi->cmapped = 1; -+ break; -+ -+ case 12: -+ pi->g_bits = pi->r_bits = pi->b_bits = 4; -+ pi->cached = 1; -+ break; -+ -+ case 15: -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->cached = 1; -+ break; -+ -+ case 16: -+ pi->g_bits = pi->r_bits = pi->b_bits = 5; -+ pi->i_bits = 1; -+ pi->cached = 1; -+ break; -+ -+ case 24: -+ pi->g_bits = pi->r_bits = pi->b_bits = 8; -+ pi->cached = 1; -+ break; -+ -+ case 32: -+ pic_error(pi, PIC_SUPPORT); -+ break; -+ -+ default: -+ pic_error(pi, PIC_NUM_COLORS); -+ } -+ } -+ break; -+ -+ default: -+ pic_error(pi, PIC_TYPE); -+ } -+ -+ pi->numcols = 1 << pi->cbits; -+ -+ /* read palette data */ -+ if(pi->cmapped){ -+ int i; -+ pi->cmap = pic_malloc((size_t) 3 * pi->numcols, "pic_read_header#1"); -+ for(i = 0; i < pi->numcols; i++){ -+ data32 c = pic_read_rgb(pi); -+ pi->cmap[i * 3 ] = c >> 16 & 0xff; -+ pi->cmap[i * 3 + 1] = c >> 8 & 0xff; -+ pi->cmap[i * 3 + 2] = c & 0xff; -+ } -+ } -+ -+ /* setup color code cache */ -+ if(pi->cached) -+ pic_cache_init(pi); -+ -+ -+ pi->data = pic_malloc(sizeof(data32) * pi->width * pi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "pic_read_header#2"); -+ { -+ int i; -+ for(i = 0; i < pi->width * pi->height; i++) -+ pi->data[i] = 0xffffffff; -+ } -+ -+ if(DEBUG) -+ pic_show_pic_info(pi); -+} -+ -+/* The main routine to expand a PIC file. */ -+static void pic_expand_data(pi) -+ struct pic_info *pi; -+{ -+ int cnt; -+ data32 c; -+ pi->data[0] = c = 0; -+ for(cnt = -1; cnt < pi->width * pi->height; ){ -+ int len = pic_expanding_read_len(pi); -+ cnt += len; -+ if(cnt < pi->width * pi->height){ -+ int x = cnt % pi->width; -+ int y = cnt / pi->width; -+ data32 c = pic_expanding_read_color(pi); -+ pic_expanding_read_chain(pi, x, y, c); -+ } -+ } -+} -+ -+static int pic_expanding_read_len(pi) -+ struct pic_info *pi; -+{ -+ int len; -+ byte bits; -+ for(len = 2, bits = 1; pic_read_bits(pi, 1) == 1; bits++) -+ len <<= 1; -+ return len - 1 + pic_read_bits(pi, bits); -+} -+ -+static data32 pic_expanding_read_color(pi) -+ struct pic_info *pi; -+{ -+ if(pi->cached){ -+ byte b = pic_read_bits(pi, 1); -+ if(b){ -+ return pic_cache_get_value(pi, (int) pic_read_bits(pi, 7)); -+ }else{ -+ data32 c = pic_read_color_code(pi); -+ pic_cache_add_value(pi, c); -+ return c; -+ } -+ } -+ return pic_read_color_code(pi); -+} -+ -+static void pic_expanding_read_chain(pi, x, y, c) -+ struct pic_info *pi; -+ int x, y; -+ data32 c; -+{ -+ pi->data[y * pi->width + x] = c; -+ if(pic_read_bits(pi, 1) == 1){ -+ int fin = 0; -+ while(!fin){ -+ switch(pic_read_bits(pi, 2)){ -+ case 1: /* left */ -+ pi->data[(++y) * pi->width + (--x)] = c; -+ break; -+ case 2: /* middle */ -+ pi->data[(++y) * pi->width + x ] = c; -+ break; -+ case 3: /* right */ -+ pi->data[(++y) * pi->width + (++x)] = c; -+ break; -+ case 0: /* far or nothing */ -+ if(pic_read_bits(pi, 1) == 0) -+ fin = 1; -+ else{ -+ if(pic_read_bits(pi, 1) == 0) -+ pi->data[(++y) * pi->width + (x -= 2)] = c; -+ else -+ pi->data[(++y) * pi->width + (x += 2)] = c; -+ } -+ } -+ } -+ } -+} -+ -+/* -+ * Make a picture from the expanded data. -+ */ -+static void pic_make_xvpic(pi, xp, rp, gp, bp) -+ struct pic_info *pi; -+ byte **xp, *rp, *gp, *bp; -+{ -+ if(pi->cmapped){ -+ if(pi->tiled256) -+ *xp = pic_malloc((size_t) pi->width * pi->height * 2, // GRR POSSIBLE OVERFLOW / FIXME -+ "pic_make_xvpic#1"); -+ else -+ *xp = pic_malloc((size_t) pi->width * pi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "pic_make_xvpic#2"); -+ }else -+ *xp = pic_malloc((size_t) pi->width * pi->height * 3, // GRR POSSIBLE OVERFLOW / FIXME -+ "pic_make_xvpic#3"); -+ -+ if(pi->cmapped){ -+ int i; -+ -+ for(i = 0; i < pi->numcols; i++){ -+ rp[i] = pi->cmap[i * 3 ]; -+ gp[i] = pi->cmap[i * 3 + 1]; -+ bp[i] = pi->cmap[i * 3 + 2]; -+ } -+ -+ if(pi->tiled256){ -+ int pic_idx = 0, dat_idx; -+ data16 col = 0; -+ for(dat_idx = 0; dat_idx < pi->width * pi->height; dat_idx++){ -+ if(pi->data[dat_idx] != 0xffffffff) -+ col = pi->data[dat_idx]; -+ (*xp)[pic_idx++] = col & 0xff; -+ (*xp)[pic_idx++] = col >> 8 & 0xff; -+ dat_idx++; -+ } -+ }else{ -+ int pic_idx = 0, dat_idx; -+ byte col = 0; -+ for(dat_idx = 0; dat_idx < pi->width * pi->height; dat_idx++){ -+ if(pi->data[dat_idx] != 0xffffffff) -+ col = pi->data[dat_idx]; -+ (*xp)[pic_idx++] = col; -+ } -+ } -+ }else{ -+ int pic_idx = 0, dat_idx; -+ byte r = 0, g = 0, b = 0; -+ for(dat_idx = 0; dat_idx < pi->width * pi->height; dat_idx++){ -+ if(pi->data[dat_idx] != 0xffffffff){ -+ data32 col = pi->data[dat_idx]; -+ r = col >> 16 & 0xff; -+ g = col >> 8 & 0xff; -+ b = col & 0xff; -+ } -+ (*xp)[pic_idx++] = r; -+ (*xp)[pic_idx++] = g; -+ (*xp)[pic_idx++] = b; -+ } -+ } -+} -+ -+ -+/* The main routine to write PIC file. */ -+int WritePIC(fp, pic0, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle, -+ comment) -+ FILE *fp; -+ byte *pic0; -+ int ptype, w, h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+ char *comment; -+{ -+ struct pic_info pic; -+ int e; -+ -+ if(DEBUG) fputs("WritePIC:\n", stderr); -+ -+ pic_init_info(&pic); -+ pic.fp = fp; -+ pic.width = w; -+ pic.height = h; -+ pic.writing_grey = (colorstyle == F_GREYSCALE); -+ if(ptype != PIC24){ /* PIC8 */ -+ pic.cmapped = 1; -+ pic.cached = 0; -+ pic.cbits = 8; -+ pic.g_bits = -+ pic.r_bits = -+ pic.b_bits = 8; -+ pic.i_bits = 0; -+ pic.numcols = numcols; -+ }else{ /* PIC24 */ -+ pic.cmapped = 0; -+ pic.cached = 1; -+ pic.cbits = 24; -+ pic.g_bits = -+ pic.r_bits = -+ pic.b_bits = 8; -+ pic.i_bits = 0; -+ pic.numcols = 1 << 24; -+ pic_cache_init(&pic); -+ } -+ -+ if((e = setjmp(pic.jmp)) != 0){ -+ /* When an error occurs while writing, comes here. */ -+ pic_cleanup_pic_info(&pic, 1); -+ if(DEBUG) fputs("\n", stderr); -+ return -1; -+ } -+ -+ pic_write_id(&pic); -+ pic_write_comment(&pic, comment); -+ pic_write_header(&pic); -+ if(pic.cmapped) -+ pic_write_palette(&pic, rmap, gmap, bmap); -+ pic_make_sparse_data(&pic, pic0); -+ pic_write_data(&pic); -+ pic_write_bits(&pic, 0, 8); -+ -+ pic_cleanup_pic_info(&pic, 1); -+ if(DEBUG) fputs("\n", stderr); -+ return 0; -+} -+ -+static void pic_write_id(pi) -+ struct pic_info *pi; -+{ -+ if(fwrite("PIC", (size_t) 3, (size_t) 1, pi->fp) != 1) -+ pic_file_error(pi, PIC_WRITE); -+} -+ -+static void pic_write_comment(pi, comm) -+ struct pic_info *pi; -+ char *comm; -+{ -+ if(comm){ -+ while(*comm){ -+ int c = *comm; -+ if(c == '\032') -+ c = ' '; -+ if(fputc(*comm, pi->fp) == EOF) -+ pic_file_error(pi, PIC_WRITE); -+ comm++; -+ } -+ } -+ /* write ^Z, 0, and reserved. */ -+ if(fwrite("\032\0\0", (size_t)3, (size_t) 1, pi->fp) != 1) -+ pic_file_error(pi, PIC_WRITE); -+} -+ -+static void pic_write_header(pi) -+ struct pic_info *pi; -+{ -+ if(DEBUG) pic_show_pic_info(pi); -+ pic_write_bits(pi, (data32) 0, 4); /* mode: 1:1 */ -+ pic_write_bits(pi, (data32) 0xf, 4); /* type: misc */ -+ pic_write_bits(pi, (data32) pi->cbits, 16); /* bits */ -+ pic_write_bits(pi, (data32) pi->width, 16); /* width */ -+ pic_write_bits(pi, (data32) pi->height, 16); /* height */ -+ pic_write_bits(pi, (data32) 0xffff, 16); /* x: unused */ -+ pic_write_bits(pi, (data32) 0xffff, 16); /* y: unused */ -+ pic_write_bits(pi, (data32) 0x0101, 16); /* real aspect */ -+} -+ -+static void pic_write_palette(pi, r, g, b) -+ struct pic_info *pi; -+ byte *r, *g, *b; -+{ -+ int i; -+ data32 rgb = 0; -+ pic_write_bits(pi, (data32) pi->g_bits, 8); -+ for(i = 0; i < pi->numcols; i++){ -+ rgb = (data32) *r++ << 16 | (data32) *g++ << 8 | (data32) *b++; -+ pic_write_rgb(pi, rgb); -+ } -+ for( ; i < 256; i++) -+ pic_write_rgb(pi, rgb); -+} -+ -+static void pic_make_sparse_data(pi, dat) -+ struct pic_info *pi; -+ byte *dat; -+{ -+ int i; -+ data32 c; -+ -+ pi->data = pic_malloc(sizeof(data32) * pi->width * pi->height, // GRR POSSIBLE OVERFLOW / FIXME -+ "pic_make_sparse_data"); -+ -+ if(pi->cmapped){ -+ c = 0; -+ for(i = 0; i < pi->width * pi->height; i++){ -+ if(c != dat[i]) -+ c = pi->data[i] = dat[i]; -+ else -+ pi->data[i] = 0xffffffff; -+ } -+ }else{ -+ int j = 0; -+ c = 0; -+ for(i = 0; i < pi->width * pi->height; i++){ -+ data32 r, g, b, t; -+ r = dat[j++]; -+ g = dat[j++]; -+ b = dat[j++]; -+ t = r << 16 | g << 8 | b; -+ if(c != t) -+ c = pi->data[i] = t; -+ else -+ pi->data[i] = 0xffffffff; -+ } -+ } -+} -+ -+static void pic_write_data(pi) -+ struct pic_info *pi; -+{ -+ int i; -+ int max = pi->width * pi->height; -+ data32 c = 0; -+ -+ i = -1; -+ while(i < max){ -+ int j; -+ for(j = i + 1; j < max; j++){ -+ if(pi->data[j] != 0xffffffff) -+ break; -+ } -+ pic_write_length(pi, (data32) j - i); -+ i = j; -+ if(i < max){ -+ pic_write_color(pi, c = pi->data[i]); -+ pic_write_chain(pi, i % pi->width, i / pi->width, c); -+ } -+ } -+} -+ -+static void pic_write_length(pi, len) -+ struct pic_info *pi; -+ data32 len; -+{ -+ int bits = 0; /* leading 1's */ -+ int max = 2; -+ -+ while(len > max){ -+ max = (max + 1) * 2; -+ bits++; -+ } -+ pic_write_bits(pi, 0xffffffff, bits); -+ pic_write_bits(pi, 0, 1); -+ pic_write_bits(pi, len - max / 2, bits + 1); -+} -+ -+static void pic_write_color(pi, c) -+ struct pic_info *pi; -+ data32 c; -+{ -+ if(pi->cached){ -+ int idx = pic_cache_lookup(pi, c); -+ if(idx < 0){ /* not found */ -+ pic_write_bits(pi, 0, 1); -+ pic_write_color_code(pi, c); -+ pic_cache_add_value(pi, c); -+ }else{ /* found */ -+ pic_write_bits(pi, (data32) 0xffffffff, 1); -+ pic_write_bits(pi, (data32) idx, 7); -+ } -+ }else -+ pic_write_color_code(pi, c); -+} -+ -+static void pic_write_chain(pi, x, y, c) -+ struct pic_info *pi; -+ int x, y; -+ data32 c; -+{ -+ int ctr = (y + 1) * pi->width + x; -+ -+ if(y < pi->height - 1 && -+ ( pi->data[ctr ] == c || -+ (x > 0 && pi->data[ctr - 1] == c) || -+ (x < pi->width - 1 && pi->data[ctr + 1] == c) || -+ (x > 1 && pi->data[ctr - 2] == c) || -+ (x < pi->width - 2 && pi->data[ctr + 2] == c))){ -+ pic_write_bits(pi, 1, 1); -+ while(++y < pi->height){ -+ if(pi->data[ctr] == c){ /* center */ -+ pic_write_bits(pi, 2, 2); -+ pi->data[ctr] = 0xffffffff; -+ ctr += pi->width; -+ }else if(x > 0 && pi->data[ctr - 1] == c){ /* left */ -+ pic_write_bits(pi, 1, 2); -+ pi->data[ctr - 1] = 0xffffffff; -+ ctr += pi->width - 1; -+ }else if(x < pi->width - 1 && pi->data[ctr + 1] == c){/* right */ -+ pic_write_bits(pi, 3, 2); -+ pi->data[ctr + 1] = 0xffffffff; -+ ctr += pi->width + 1; -+ }else if(x > 1 && pi->data[ctr - 2] == c){ /* 2-left */ -+ pic_write_bits(pi, 2, 4); -+ pi->data[ctr - 2] = 0xffffffff; -+ ctr += pi->width - 2; -+ }else if(x < pi->width - 2 && pi->data[ctr + 2] == c){/* 2-right */ -+ pic_write_bits(pi, 3, 4); -+ pi->data[ctr + 2] = 0xffffffff; -+ ctr += pi->width + 2; -+ }else /* nothing */ -+ break; -+ } -+ pic_write_bits(pi, 0, 3); -+ }else -+ pic_write_bits(pi, 0, 1); -+} -+ -+ -+/* -+ * These 4 functions read or write a color. -+ * -+ * pic_read_rgb: -+ * reads an RGB. Each bit length is [rgb]_bits, but -+ * it is expanded to 8bits when returned. -+ * -+ * pic_read_color_code: -+ * reads a color code, whose length is cbits. -+ * It is the index to the colormap or RGB itself. -+ * -+ * pic_write_rgb: -+ * writes an RGB value. -+ * -+ * pic_write_color_code: -+ * writes a color code. -+ */ -+static data32 pic_read_rgb(pi) -+ struct pic_info *pi; -+{ -+ int rb = pi->r_bits, gb = pi->g_bits, bb = pi->b_bits; -+ byte r, g, b; -+ if(pi->inv_gr){ -+ r = pic_read_bits(pi, rb); -+ g = pic_read_bits(pi, gb); -+ }else{ -+ g = pic_read_bits(pi, gb); -+ r = pic_read_bits(pi, rb); -+ } -+ b = pic_read_bits(pi, bb); -+ if(pi->i_bits){ -+ byte i; -+ i = pic_read_bits(pi, pi->i_bits); -+ r = r << pi->i_bits | i; -+ g = g << pi->i_bits | i; -+ b = b << pi->i_bits | i; -+ rb += pi->i_bits; -+ gb += pi->i_bits; -+ bb += pi->i_bits; -+ } -+ r = pic_pad_bit(rb, r); -+ g = pic_pad_bit(gb, g); -+ b = pic_pad_bit(bb, b); -+ -+ return (data32) r << 16 | (data32) g << 8 | (data32) b; -+} -+ -+static data32 pic_read_color_code(pi) -+ struct pic_info *pi; -+{ -+ if(pi->cmapped) -+ return pic_read_bits(pi, pi->cbits); -+ return pic_read_rgb(pi); -+} -+ -+static void pic_write_rgb(pi, rgb) -+ struct pic_info *pi; -+ data32 rgb; -+{ -+ byte r = rgb >> 16; -+ byte g = rgb >> 8; -+ byte b = rgb; -+ if(pi->writing_grey) -+ r = g = b = MONO(r, g, b); -+ pic_write_bits(pi, g, pi->g_bits); -+ pic_write_bits(pi, r, pi->r_bits); -+ pic_write_bits(pi, b, pi->b_bits); -+} -+ -+static void pic_write_color_code(pi, code) -+ struct pic_info *pi; -+ data32 code; -+{ -+ if(pi->cmapped){ -+ pic_write_bits(pi, code, pi->cbits); -+ }else{ -+ pic_write_rgb(pi, code); -+ } -+} -+ -+ -+/* -+ * These pic_cache_* functions are an implementation of the color cache. -+ * -+ * pic_cache_init: -+ * initializes the cache. -+ * -+ * pic_cache_get_value: -+ * gets a color indexed by the argument `idx'. -+ * It updates the `most recently used' time. -+ * -+ * pic_cache_add_value: -+ * adds a color to the top of the cache list. -+ */ -+static void pic_cache_init(pi) -+ struct pic_info *pi; -+{ -+ int i; -+ pi->cache.node = pic_malloc(sizeof(struct cachenode_t) * 128, -+ "pic_cache_init"); -+ for(i = 0; i < 128; i++){ -+ pi->cache.node[i].newer = i + 1; -+ pi->cache.node[i].older = i - 1; -+ pi->cache.node[i].dat = 0; -+ } -+ pi->cache.node[ 0].older = 127; -+ pi->cache.node[127].newer = 0; -+ pi->cache.newest = 0; -+} -+ -+static data32 pic_cache_get_value(pi, idx) -+ struct pic_info *pi; -+ int idx; -+{ -+ struct cachenode_t *p = pi->cache.node; -+ int n = pi->cache.newest; -+ if(n != idx){ -+ p[p[idx].newer].older = p[idx].older; -+ p[p[idx].older].newer = p[idx].newer; -+ -+ p[p[n].newer].older = idx; -+ p[idx].newer = p[n].newer; -+ p[n].newer = idx; -+ p[idx].older = n; -+ -+ pi->cache.newest = idx; -+ } -+ return pi->cache.node[idx].dat; -+} -+ -+static void pic_cache_add_value(pi, dat) -+ struct pic_info *pi; -+ data32 dat; -+{ -+ pi->cache.newest = pi->cache.node[pi->cache.newest].newer; -+ pi->cache.node[pi->cache.newest].dat = dat; -+} -+ -+static int pic_cache_lookup(pi, dat) -+ struct pic_info *pi; -+ data32 dat; -+{ -+ int i; -+ for(i = 0; i < 128; i++){ -+ if(pi->cache.node[i].dat == dat){ -+ pic_cache_get_value(pi, i); -+ return i; -+ } -+ } -+ return -1; -+} -+ -+ -+/* -+ * These pic_{read,write}_bits functions access the bit stream. -+ * pic_read_bits: -+ * reads the specified bits from the file. -+ * -+ * pic_write_bits: -+ * writes the specified bits to the file. -+ */ -+static data32 pic_read_bits(pi, bits) -+ struct pic_info *pi; -+ int bits; -+{ -+ data32 r = 0; -+ -+ while(bits > 0){ -+ while(pi->bs.rest > 0 && bits > 0){ -+ r = (r << 1) | (pi->bs.cur & 0x80 ? 1 : 0); -+ pi->bs.cur <<= 1; -+ pi->bs.rest--; -+ bits--; -+ } -+ if(bits > 0){ -+ int c; -+ if((c = fgetc(pi->fp)) == EOF){ -+ pic_file_warning(pi, PIC_CORRUPT); -+ c = 0; -+ } -+ pi->bs.cur = c; -+ pi->bs.rest = 8; -+ } -+ } -+ -+ return r; -+} -+ -+static void pic_write_bits(pi, dat, bits) -+ struct pic_info *pi; -+ data32 dat; -+ int bits; -+{ -+ data32 dat_mask = 1 << (bits - 1); -+ while(bits > 0){ -+ while(pi->bs.rest < 8 && bits > 0){ -+ pi->bs.cur <<= 1; -+ if(dat & dat_mask) -+ pi->bs.cur |= 1; -+ pi->bs.rest++; -+ bits--; -+ dat_mask >>= 1; -+ } -+ if(pi->bs.rest >= 8){ -+ if(fputc((int)pi->bs.cur, pi->fp) == EOF) -+ pic_error(pi, PIC_WRITE); -+ pi->bs.cur = 0; -+ pi->bs.rest = 0; -+ } -+ } -+} -+ -+ -+/* -+ * This function extends sub-8-bit data to 8-bit data using bit-replication. -+ */ -+static byte pic_pad_bit(bits, dat) -+ int bits; -+ data32 dat; -+{ -+ switch(bits){ -+ case 1: -+ if(dat & 1) -+ dat = 0xff; -+ else -+ dat = 0; -+ break; -+ case 2: -+ dat = dat << 6 | dat << 4 | dat << 2 | dat; -+ break; -+ case 3: -+ dat = dat << 5 | dat << 2 | dat >> 1; -+ break; -+ case 4: -+ dat = dat << 4 | dat; -+ break; -+ case 5: -+ dat = dat << 3 | dat >> 2; -+ break; -+ case 6: -+ dat = dat << 2 | dat >> 4; -+ break; -+ case 7: -+ dat = dat << 1 | dat >> 6; -+ } -+ -+ return dat; -+} -+ -+/* -+ * These functions initialize or clean up structures. -+ * pic_init_info: -+ * initializes a pic_info structure. -+ * pic_cleanup_pic_info: -+ * cleans up a pic_info structure. -+ * pic_cleanup_pinfo: -+ * cleans up a PICINFO structure. -+ */ -+static void pic_init_info(pi) -+ struct pic_info *pi; -+{ -+ pi->fp = NULL; -+ pi->bs.rest = 0; -+ pi->bs.cur = '\0'; -+ pi->type = pi->mode = 0; -+ pi->width = pi->height = 0; -+ pi->aspect = 1.0; -+ pi->cbits = 0; -+ pi->cmapped = pi->cached = 0; -+ pi->cache.node = NULL; -+ pi->cmap = NULL; -+ pi->g_bits = pi->r_bits = pi->b_bits = pi->i_bits = 0; -+ pi->inv_gr = 0; -+ pi->tiled256 = 0; -+ pi->numcols = 0; -+ pi->writing_grey = 0; -+} -+ -+static void pic_cleanup_pic_info(pi, writing) -+ struct pic_info *pi; -+ int writing; -+{ -+ if(!writing && pi->fp) -+ fclose(pi->fp); -+ if(pi->cmap) -+ free(pi->cmap); -+ if(pi->cache.node) -+ free(pi->cache.node); -+ if(pi->data) -+ free(pi->data); -+ pi->fp = NULL; -+ pi->cmap = NULL; -+ pi->cache.node = NULL; -+ pi->data = NULL; -+} -+ -+static void pic_cleanup_pinfo(pinfo) -+ PICINFO *pinfo; -+{ -+ if(pinfo->pic){ -+ free(pinfo->pic); -+ pinfo->pic = NULL; -+ } -+ if(pinfo->comment){ -+ free(pinfo->comment); -+ pinfo->comment = NULL; -+ } -+} -+ -+/* -+ * Error Handlers. -+ * pic_memory_error: -+ * shows an error message and terminates. -+ * pic_error: -+ * shows a non-file error message and jumps to the entry for errors. -+ * pic_file_error: -+ * shows a file error message and jumps to the entry for errors. -+ * pic_file_warning: -+ * shows a file warning message. -+ */ -+static void pic_memory_error(scm, fn) -+ char *scm, *fn; -+{ -+ char buf[128]; -+ sprintf(buf, "%s: can't allocate memory. (%s)", scm, fn); -+ FatalError(buf); -+} -+ -+static void pic_error(pi, mn) -+ struct pic_info *pi; -+ int mn; -+{ -+ SetISTR(ISTR_WARNING, "%s", pic_msgs[mn]); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pic_file_error(pi, mn) -+ struct pic_info *pi; -+ int mn; -+{ -+ if(feof(pi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", pic_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", pic_msgs[mn], ERRSTR(errno)); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pic_file_warning(pi, mn) -+ struct pic_info *pi; -+ int mn; -+{ -+ if(feof(pi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", pic_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", pic_msgs[mn], ERRSTR(errno)); -+} -+ -+static void pic_show_pic_info(pi) -+ struct pic_info *pi; -+{ -+ fprintf(stderr, " file size: %ld.\n", pi->fsize); -+ -+ fputs(" machine: ", stderr); -+ switch(pi->type){ -+ case 0x0: -+ fputs("X68k", stderr); -+ break; -+ case 0x1: -+ fputs("PC-88VA", stderr); -+ if(pi->mode & 1) -+ fputs(",HR", stderr); -+ if(pi->mode & 2) -+ fputs(",tiled256", stderr); -+ break; -+ case 0x2: -+ fprintf(stderr, -+ "FM-TOWNS,%s-resolution", pi->mode == 5 ? "low" : "high"); -+ break; -+ case 0x3: -+ fputs("Macintosh", stderr); -+ break; -+ case 0xf: -+ fputs("misc", stderr); -+ } -+ fputs("\n", stderr); -+ -+ fprintf(stderr, " image size: %dx%d\n", pi->width, pi->height); -+ fprintf(stderr, " aspect: %f\n", pi->aspect); -+ fprintf(stderr, " cache: %s\n", pi->cached ? "on" : "off"); -+ fprintf(stderr, " colormap: %s\n", pi->cmapped ? "on" : "off"); -+ fprintf(stderr, " number of color bits: %d\n", pi->cbits); -+ fprintf(stderr, " number of RGB bits: R%d,G%d,B%d,I%d\n", -+ pi->r_bits, pi->g_bits, pi->b_bits, pi->i_bits); -+ fprintf(stderr, " inverted G&R: %s\n", pi->inv_gr ? "true" : "false"); -+ fprintf(stderr, " number of colors: %d\n", pi->numcols); -+} -+ -+/* Memory related routines. */ -+static void *pic_malloc(n, fn) -+ size_t n; -+ char *fn; -+{ -+ void *r = (void *) malloc(n); -+ if(r == NULL) -+ pic_memory_error("malloc", fn); -+ return r; -+} -+ -+static void *pic_realloc(p, n, fn) -+ void *p; -+ size_t n; -+ char *fn; -+{ -+ void *r = (p == NULL) ? (void *) malloc(n) : (void *) realloc(p, n); -+ if(r == NULL) -+ pic_memory_error("realloc", fn); -+ return r; -+} -+#endif /* HAVE_PIC */ -diff -ruN xv-3.10a-bugfixes/xvpic2.c xv-3.10a-enhancements/xvpic2.c ---- xv-3.10a-bugfixes/xvpic2.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvpic2.c 2005-04-17 22:56:07.000000000 -0700 -@@ -0,0 +1,3608 @@ -+/* -+ * $Id: xvpic2.c,v 2.9.1.14 1995/04/24 15:34:15 ikeyan Exp $ -+ * xvpic2.c - load and save routines for `PIC2' format pictures. -+ * -+ * -+ * Outline -+ * ======= -+ * xvpic2.c supports the PIC2 format image file. It is used some -+ * Japanese personal computer users. -+ * -+ * The PIC2 format is designed by A.Yanagisawa. It is an excellent -+ * format except for its encode/decode speed. ;-) -+ * -+ * The features of the PIC2 format: -+ * - Powerful header information (included author, filename, title, -+ * saver, product number, created date and comment). -+ * - Reversible compression, and very high compression ratio (in many -+ * cases, a higher compression ratio than the JPEG compression; -+ * because of its compression method, PIC2 is especially good at -+ * pictures like cell animation). -+ * - Can handle full-color (24 bits) image. -+ * - Can include multi image blocks into one PIC2 file. -+ * - Have four different block format (P2SS, P2SF, P2BM and -+ * P2BI). P2SS format uses arithmetic compression for storing -+ * data. P2SF uses normal run-length compression. P2BM and P2BI is -+ * raw image format. Select any one according to the situation. -+ * -+ * Explanation of the PIC2 compression: -+ -+ * - In the first place, try to record pixel color, uses color caches -+ * which keep some recent colors, and formed according to color's -+ * frequency. PIC2 has some color cache spaces that are switched by -+ * upper pixel value of current pixel. If cache is hit, record -+ * that. -+ * - Unfortunately, in the case of color cache didn't hit, record the -+ * difference from the value estimated with the value of upper and -+ * left pixel of current pixel (similar to PNG's AVG predictor). -+ * - And extract image's color chain if exist, and record that (it -+ * results in image's outline). -+ * - In all cases, arithmetic compression is used in the final stage -+ * before writing the file, which in theory produces the ideal -+ * compression ratio (P2SS). -+ * -+ * Features -+ * ======== -+ * - Support 3,6,9,12,15,18,21,24bit PIC2 format (Load/Save). -+ * - Support all image block formats of PIC2 (Load/Save). -+ * - Support multi block PIC2 file (Load/Save). -+ * -+ * -+ * Bugs -+ * ==== -+ * - Unsupport 8bit PIC2 image file. -+ * -+ * If you find other bugs (surely exist :-)), send me bug-report. -+ * -+ * -+ * Author -+ * ====== -+ * IKEMOTO Masahiro <ikeyan@airlab.cs.ritsumei.ac.jp> -+ */ -+ -+#define PIC2_IGNORE_UNUSED_FUNCTIONS -+#define NEEDSDIR -+ -+#include "xv.h" -+#include <setjmp.h> -+ -+#ifdef HAVE_PIC2 -+ -+typedef unsigned long pixel; -+ -+#define pic2_cextoshort(addr) ( \ -+ (((short) (((byte *) addr)[0])) << 8) | \ -+ ( (short) (((byte *) addr)[1])) \ -+) -+#define pic2_cextolong(addr) ( \ -+ (((long) (((byte *) addr)[0])) << 24) | \ -+ (((long) (((byte *) addr)[1])) << 16) | \ -+ (((long) (((byte *) addr)[2])) << 8) | \ -+ ( (long) (((byte *) addr)[3])) \ -+) -+#define pic2_shorttocex(addr, n) { \ -+ ((byte *) addr)[0] = (((unsigned short) (n) >> 8) & 0xff); \ -+ ((byte *) addr)[1] = ( (unsigned short) (n) & 0xff); \ -+} -+#define pic2_longtocex(addr, n) { \ -+ ((byte *) addr)[0] = (((unsigned long) (n) >> 24) & 0xff); \ -+ ((byte *) addr)[1] = (((unsigned long) (n) >> 16) & 0xff); \ -+ ((byte *) addr)[2] = (((unsigned long) (n) >> 8) & 0xff); \ -+ ((byte *) addr)[3] = ( (unsigned long) (n) & 0xff); \ -+} -+#define pic2_shift_bits(b, n) (((n) > 0) ? ((b) << (n)) : ((b) >> -(n))) -+ -+#define PIC2_READ_MODE 0 -+#define PIC2_WRITE_MODE 1 -+ -+#define PIC2_ARITH_CACHE 32 -+#define PIC2_ARITH_CONTEXT 128 -+#define PIC2_FAST_CACHE 64 -+ -+#define PIC2_HEADER_SIZE 124 -+#define PIC2_BLOCK_HEADER_SIZE 26 -+ -+struct pic2_header { -+ char magic[4]; -+ char name[18]; -+ char subtitle[8]; -+ char crlf0[2]; -+ char title[30]; -+ char crlf1[2]; -+ char saver[30]; -+ char crlf2[2]; -+ char eof[1]; -+ char reserve0[1]; -+ short flag; -+ short no; -+ long time; -+ long size; -+ short depth; -+ short x_aspect; -+ short y_aspect; -+ short x_max; -+ short y_max; -+ long reserve1; -+}; -+ -+struct pic2_block { -+ char id[4]; -+ long size; -+ short flag; -+ short x_wid; -+ short y_wid; -+ short x_offset; -+ short y_offset; -+ long opaque; -+ long reserve; -+}; -+ -+struct pic2_info { -+ jmp_buf jmp; -+ FILE *fp; -+ struct { -+ int rest; -+ byte cur; -+ int bits; -+ char zero; -+ }bs; -+ long fsize; -+ struct pic2_header *header; -+ struct pic2_block *block; -+ int n_pal; -+ int pal_bits; -+ byte pal[256][3]; -+ char *comment; -+ char mode; -+ long next_pos; -+ long block_pos; -+ short x_max; -+ short y_max; -+ int ynow; -+ byte *buf; -+ pixel *vram_prev; -+ pixel *vram_now; -+ pixel *vram_next; -+ short *flag_now; -+ short *flag_next; -+ short *flag2_now; -+ short *flag2_next; -+ short *flag2_next2; -+ pixel (*cache)[PIC2_ARITH_CACHE]; -+ unsigned short *cache_pos; -+ unsigned short *mulu_tab; -+ long aa; -+ long cc; -+ long dd; -+ char cache_hit_c; -+ int (*next_line) PARM((struct pic2_info *, pixel **)); -+ char writing_grey; -+ char pagebname[64]; -+ int pnum; -+}; -+ -+static void pic2_open_file PARM((struct pic2_info*,char*)); -+static void pic2_read_header PARM((struct pic2_info*)); -+static void pic2_read_block_header1 PARM((struct pic2_info*)); -+static void pic2_read_block_header2 PARM((struct pic2_info*)); -+static short pic2_arith_decode_bit PARM((struct pic2_info*,int)); -+static short pic2_arith_decode_nn PARM((struct pic2_info*,int)); -+static void pic2_arith_expand_chain PARM((struct pic2_info*,int,int,pixel)); -+static short pic2_arith_get_number PARM((struct pic2_info*,int,int)); -+static pixel pic2_arith_read_color PARM((struct pic2_info*,int)); -+static int pic2_arith_expand_line PARM((struct pic2_info*,pixel**)); -+static int pic2_arith_loader_init PARM((struct pic2_info*)); -+static int pic2_fast_read_length PARM((struct pic2_info*)); -+static void pic2_fast_expand_chain PARM((struct pic2_info*,int,pixel)); -+static pixel pic2_fast_read_color PARM((struct pic2_info*,pixel)); -+static int pic2_fast_expand_line PARM((struct pic2_info*,pixel**)); -+static int pic2_fast_loader_init PARM((struct pic2_info*)); -+static int pic2_beta_expand_line PARM((struct pic2_info*,pixel**)); -+static int pic2_beta_loader_init PARM((struct pic2_info*)); -+static void pic2_make_xvpic PARM((struct pic2_info*,byte**, -+ byte*,byte*,byte*)); -+static void pic2_make_pagefile PARM((struct pic2_info*,char*,int)); -+static void pic2_setup_pic2_info PARM((struct pic2_info*, -+ char*,char*,char*,char*, -+ int,int,int,int,int,int,char *)); -+static void pic2_append PARM((struct pic2_info*)); -+static void pic2_write_header1 PARM((struct pic2_info*)); -+static void pic2_write_header2 PARM((struct pic2_info*)); -+static void pic2_write_block_header PARM((struct pic2_info*)); -+static void pic2_arith_write_zero_bit PARM((struct pic2_info*)); -+static void pic2_arith_flush_bit_buf PARM((struct pic2_info*)); -+static void pic2_arith_carry_bit PARM((struct pic2_info*)); -+static void pic2_arith_encode_bit PARM((struct pic2_info*,int,int)); -+static void pic2_arith_encode_nbyte PARM((struct pic2_info*,int,int,int)); -+static void pic2_arith_encode_nn PARM((struct pic2_info*,int,int)); -+static void pic2_arith_press_chain PARM((struct pic2_info*,int)); -+static void pic2_arith_put_number PARM((struct pic2_info*,int,int,int)); -+static void pic2_arith_write_color PARM((struct pic2_info*,int)); -+static void pic2_arith_press_line2 PARM((struct pic2_info*)); -+static int pic2_arith_press_line PARM((struct pic2_info*,pixel**)); -+static int pic2_arith_saver_init PARM((struct pic2_info*,pixel**)); -+static void pic2_fast_write_length PARM((struct pic2_info*,int)); -+static void pic2_fast_press_chain PARM((struct pic2_info*,int)); -+static void pic2_fast_press_chain2 PARM((struct pic2_info*,int)); -+static void pic2_fast_flush_chain PARM((struct pic2_info*)); -+static void pic2_fast_write_color PARM((struct pic2_info*,int)); -+static void pic2_fast_press_line2 PARM((struct pic2_info*)); -+static int pic2_fast_press_line PARM((struct pic2_info*,pixel**)); -+static int pic2_fast_saver_init PARM((struct pic2_info*,pixel**)); -+static int pic2_beta_press_line PARM((struct pic2_info*,pixel**)); -+static int pic2_beta_saver_init PARM((struct pic2_info*,pixel**)); -+static void pic2_write_data PARM((struct pic2_info*,byte*, -+ int,int,int,int,int, -+ byte*,byte*,byte*,int,int)); -+static int pic2_next_line PARM((struct pic2_info*,pixel**)); -+static int pic2_next_block PARM((struct pic2_info*)); -+static int pic2_find_block PARM((struct pic2_info*)); -+static int pic2_load_block PARM((struct pic2_info*)); -+static int pic2_save_block PARM((struct pic2_info*,pixel**, -+ int,int,int,int,char*,pixel)); -+#ifndef PIC2_IGNORE_UNUSED_FUNCTIONS -+static void pic2_read_palette PARM((struct pic2_info*, -+ byte*,byte*,byte*)); -+static void pic2_write_palette PARM((struct pic2_info*,int,int, -+ byte*,byte*,byte*)); -+#endif /* !PIC2_IGNORE_UNUSED_FUNCTIONS */ -+static byte pic2_convert_color_bits PARM((int,int,int)); -+static byte pic2_pad_color_bits PARM((int,int,int)); -+static byte pic2_reduce_color_bits PARM((int,int,int)); -+static pixel pic2_exchange_rg PARM((pixel,int)); -+static void pic2_handle_para PARM((struct pic2_info*,int)); -+static int pic2_alloc_buffer PARM((struct pic2_info*)); -+static void pic2_free_buffer PARM((struct pic2_info*)); -+static long pic2_seek_file PARM((struct pic2_info*,long,int)); -+static long pic2_tell_file PARM((struct pic2_info*)); -+static int pic2_read_file PARM((struct pic2_info*,void*,size_t)); -+static long pic2_read_long PARM((struct pic2_info*)); -+static short pic2_read_short PARM((struct pic2_info*)); -+static char pic2_read_char PARM((struct pic2_info*)); -+static int pic2_write_file PARM((struct pic2_info*,void*,size_t)); -+static int pic2_write_long PARM((struct pic2_info*,long)); -+static int pic2_write_short PARM((struct pic2_info*,int)); -+static int pic2_write_char PARM((struct pic2_info*,int)); -+static unsigned long pic2_read_bits PARM((struct pic2_info*,int)); -+static void pic2_write_bits PARM((struct pic2_info*, -+ unsigned long,int)); -+static void pic2_flush_bits PARM((struct pic2_info*)); -+static void pic2_memory_error PARM((char*,char*)); -+static void pic2_error PARM((struct pic2_info*,int)); -+static void pic2_file_error PARM((struct pic2_info*,int)); -+static void pic2_init_info PARM((struct pic2_info*)); -+static void pic2_cleanup_pic2_info PARM((struct pic2_info*,int)); -+static void pic2_cleanup_pinfo PARM((PICINFO*)); -+static void pic2_show_pic2_info PARM((struct pic2_info*)); -+static char *pic2_strncpy PARM((char*,char*,size_t)); -+static void *pic2_malloc PARM((size_t,char*)); -+static void *pic2_new PARM((size_t,char*)); -+ -+static int WritePIC2 PARM((FILE*,byte*,int,int,int, -+ byte*,byte*,byte*,int,int,char*, -+ int,int,int,int,int,char*)); -+ -+static char *pic2_id = "P2DT"; -+ -+/* Error Messages */ -+static char *pic2_msgs[] = { -+ NULL, -+#define PIC2_OPEN 1 -+ "can't open file.", -+#define PIC2_CORRUPT 2 -+ "file corrupted.", -+#define PIC2_FORMAT 3 -+ "not PIC2 format.", -+#define PIC2_DEPTH 4 -+ "bit depths not divisible by 3 are unsupported.", -+#define PIC2_TMPFILE 5 -+ "unable to create temporary filename???", -+#define PIC2_PAGE 6 -+ "couldn't load the page.", -+#define PIC2_APPEND 7 -+ "cannot append.", -+#define PIC2_WRITE 8 -+ "write failed.", -+}; -+ -+struct _form_tab { -+ char *id; -+ int (*loader_init) PARM((struct pic2_info *)); -+ int (*saver_init) PARM((struct pic2_info *, pixel **)); -+} form_tab[] = { -+ { "P2SS", pic2_arith_loader_init, pic2_arith_saver_init}, -+ { "P2SF", pic2_fast_loader_init, pic2_fast_saver_init}, -+ { "P2BM", pic2_beta_loader_init, pic2_beta_saver_init}, -+ { "P2BI", pic2_beta_loader_init, pic2_beta_saver_init}, -+}; -+#define n_form_tab (sizeof(form_tab) / sizeof(struct _form_tab)) -+#define P2SS 0 -+#define P2SF 1 -+#define P2BM 2 -+#define P2BI 3 -+ -+/* The main routine to load a PIC2 file. */ -+int LoadPIC2(fname, pinfo, quick) -+char *fname; -+PICINFO *pinfo; -+int quick; -+{ -+ int e, i, block; -+ struct pic2_info pic2; -+ -+ if (DEBUG) -+ fputs("LoadPIC2:\n", stderr); -+ -+ pic2_init_info(&pic2); -+ -+ if ((e = setjmp(pic2.jmp)) != 0){ -+ /* When an error occurs, comes here. */ -+ pic2_free_buffer(&pic2); -+ pic2_cleanup_pic2_info(&pic2, 0); -+ pic2_cleanup_pinfo(pinfo); -+ if (pic2split) -+ KillPageFiles(pic2.pagebname, pic2.pnum); -+ SetCursors(-1); -+ if (DEBUG) -+ fputs("\n", stderr); -+ return (0); -+ } -+ pic2_open_file(&pic2, fname); -+ pic2_read_header(&pic2); -+ -+ if ((i = pic2_find_block(&pic2)) == 0) -+ pic2_file_error(&pic2, PIC2_CORRUPT); -+ -+ block = 1; -+ while(i == 2) { -+ SetISTR(ISTR_WARNING, "unknown or invalid block #%d.", block); -+ i = pic2_next_block(&pic2); -+ block++; -+ } -+ -+ if (pic2split && !quick) { -+ char firstpage[512]; -+ struct stat st; -+#ifndef USE_MKSTEMP -+ int tmpfd; -+#endif -+ -+#ifndef VMS -+ sprintf(pic2.pagebname, "%s/xvpic2XXXXXX", tmpdir); -+#else -+ sprintf(pic2.pagebname, "Sys$Scratch:xvpic2XXXXXX"); -+#endif -+#ifdef USE_MKSTEMP -+ close(mkstemp(pic2.pagebname)); -+#else -+ mktemp(pic2.pagebname); -+ tmpfd = open(pic2.pagebname, O_WRONLY|O_CREAT|O_EXCL, S_IRWUSR); -+ if (tmpfd < 0) FatalError("LoadPIC2(): can't create temporary file"); -+ close(tmpfd); -+#endif -+ if (pic2.pagebname[0] == '\0') -+ pic2_error(&pic2, PIC2_TMPFILE); -+ strcat(pic2.pagebname, "."); -+ -+ sprintf(firstpage, "%s%d", pic2.pagebname, 1); -+ if (stat(firstpage, &st)) { -+ for (pic2.pnum = 1; i >= 1; pic2.pnum++) { -+ pic2_load_block(&pic2); -+ pic2_make_pagefile(&pic2, pic2.pagebname, pic2.pnum); -+ while(block++, (i = pic2_next_block(&pic2)) == 2) -+ SetISTR(ISTR_WARNING, -+ "unknown or invalid block #%d.", block); -+ } -+ pinfo->numpages = --pic2.pnum; -+ if (!LoadPIC2(firstpage, pinfo, 1)) -+ pic2_error(&pic2, PIC2_PAGE); -+ if (pic2.pnum == 1) -+ unlink(firstpage); -+ else -+ strcpy(pinfo->pagebname, pic2.pagebname); -+ } else -+ if (!LoadPIC2(fname, pinfo, 1)) -+ pic2_error(&pic2, PIC2_PAGE); -+ } else { -+ char buf[128], format[64]; -+ int j; -+ -+ pinfo->w = pic2.x_max; -+ pinfo->h = pic2.y_max; -+ pinfo->normw = pinfo->w; -+ pinfo->normh = pinfo->h; -+ pinfo->type = PIC24; -+ for (j = 0; j < n_form_tab; j++) { -+ if (xvbcmp(pic2.block->id, form_tab[j].id, (size_t) 4) == 0) -+ break; -+ } -+ pinfo->frmType = F_PIC2; -+ pinfo->colType = F_FULLCOLOR; -+ pinfo->comment = pic2.comment; -+ -+ if (pic2split) { -+ pic2_make_xvpic(&pic2, &pinfo->pic, pinfo->r, pinfo->g, pinfo->b); -+ strcpy(format, form_tab[j].id); -+ } else { -+ for (pic2.pnum = 1; i >= 1; pic2.pnum++) { -+ SetISTR(ISTR_INFO, "composing block #%d", block); -+ pic2_make_xvpic(&pic2, &pinfo->pic, -+ pinfo->r, pinfo->g, pinfo->b); -+ while(block++, (i = pic2_next_block(&pic2)) == 2) -+ SetISTR(ISTR_WARNING, -+ "unknown or invalid block #%d.", block); -+ } -+ if (--block > 1) -+ if (block != --pic2.pnum) -+ sprintf(format, "MultiBlock[%d/%d]", block, pic2.pnum); -+ else -+ sprintf(format, "MultiBlock[%d]", block); -+ else -+ strcpy(format, form_tab[j].id); -+ } -+ sprintf(buf, "PIC2(%s). %d colors (%ld bytes)", format, -+ (int) 1 << pic2.header->depth, pic2.fsize); -+ strcat(pinfo->fullInfo, buf); -+ sprintf(pinfo->shrtInfo, "%dx%d(aspect %4.2f) PIC2(%s).", -+ pinfo->w, pinfo->h, -+ (float) pic2.header->x_aspect / (float) pic2.header->y_aspect, -+ format); -+ if (!nopicadjust) -+ normaspect = (float) pic2.header->x_aspect -+ / (float) pic2.header->y_aspect; -+ } -+ pic2_cleanup_pic2_info(&pic2, 0); -+ SetCursors(-1); -+ if (DEBUG) -+ fputs("\n", stderr); -+ return (1); -+} -+ -+/* -+ * This function opens the file, and set its size. -+ */ -+static void pic2_open_file(pi, fname) -+ struct pic2_info *pi; -+ char *fname; -+{ -+ if ((pi->fp = fopen(fname, "rb")) == NULL) -+ pic2_file_error(pi, PIC2_OPEN); -+ fseek(pi->fp, (size_t) 0, SEEK_END); -+ pi->fsize = ftell(pi->fp); -+ fseek(pi->fp, (size_t) 0, SEEK_SET); -+} -+ -+/* -+ * These functions read the PIC2 header informations. -+ * pic2_read_header: -+ * reads the PIC2 header. -+ * pic2_read_block_header1: -+ * reads the id number of block header and the size of block. -+ * pic2_read_block_header2: -+ * reads the rest of block header. -+ */ -+static void pic2_read_header(pi) -+struct pic2_info *pi; -+{ -+ long s_comment; -+ -+ pi->mode = PIC2_READ_MODE; -+ -+ /* read header image */ -+ pic2_read_file(pi, pi->header->magic, 4); -+ pic2_read_file(pi, pi->header->name, 18); -+ pic2_read_file(pi, pi->header->subtitle, 8); -+ pic2_read_file(pi, pi->header->crlf0, 2); -+ pic2_read_file(pi, pi->header->title, 30); -+ pic2_read_file(pi, pi->header->crlf1, 2); -+ pic2_read_file(pi, pi->header->saver, 30); -+ pic2_read_file(pi, pi->header->crlf2, 2); -+ pic2_read_file(pi, pi->header->eof, 1); -+ pic2_read_file(pi, pi->header->reserve0, 1); -+ pi->header->flag = pic2_read_short(pi); -+ pi->header->no = pic2_read_short(pi); -+ pi->header->time = pic2_read_long(pi); -+ pi->header->size = pic2_read_long(pi); -+ pi->header->depth = pic2_read_short(pi); -+ pi->header->x_aspect = pic2_read_short(pi); -+ pi->header->y_aspect = pic2_read_short(pi); -+ pi->header->x_max = pic2_read_short(pi); -+ pi->header->y_max = pic2_read_short(pi); -+ pi->header->reserve1 = pic2_read_long(pi); -+ -+ /* check magic number */ -+ if (strncmp(pi->header->magic, pic2_id, (size_t) 4) != 0) -+ pic2_error(pi, PIC2_FORMAT); -+ -+ /* read palette data, if exists */ -+ if (pi->header->flag & 1) { -+ pi->pal_bits = pic2_read_char(pi); -+ pi->n_pal = pic2_read_short(pi); -+ pic2_read_file(pi, pi->pal, (size_t) (pi->n_pal * 3)); -+ } -+ -+ /* read comments */ -+ s_comment = pi->header->size - pic2_tell_file(pi); -+ pi->comment = pic2_new(s_comment + 1, "pic2_read_header"); -+ pic2_read_file(pi, pi->comment, (size_t) s_comment); -+ pi->comment[s_comment] = '\0'; -+ -+ pi->x_max = pi->header->x_max; -+ pi->y_max = pi->header->y_max; -+ -+ /* set initial block point */ -+ pi->next_pos = pic2_tell_file(pi); -+} -+ -+static void pic2_read_block_header1(pi) -+struct pic2_info *pi; -+{ -+ pic2_read_file(pi, pi->block->id, 4); -+ pi->block->size = pic2_read_long(pi); -+} -+ -+static void pic2_read_block_header2(pi) -+struct pic2_info *pi; -+{ -+ pi->block->flag = pic2_read_short(pi); -+ pi->block->x_wid = pic2_read_short(pi); -+ pi->block->y_wid = pic2_read_short(pi); -+ pi->block->x_offset = pic2_read_short(pi); -+ pi->block->y_offset = pic2_read_short(pi); -+ pi->block->opaque = pic2_read_long(pi); -+ pi->block->reserve = pic2_read_long(pi); -+} -+ -+/* -+ * These functions are arithmetic pic2 format extractor. -+ */ -+static short pic2_arith_decode_bit(pi, c) -+struct pic2_info *pi; -+int c; -+{ -+ unsigned short pp; -+ -+ pp = pi->mulu_tab[(pi->aa & 0x7f00) / 2 + c]; -+ if (pi->dd >= (int) pp) { -+ pi->dd -= pp; -+ pi->aa -= pp; -+ -+ while ((short) pi->aa >= 0) { -+ pi->dd *= 2; -+ if (pic2_read_bits(pi, 1)) -+ pi->dd++; -+ pi->aa *= 2; -+ } -+ return (1); -+ } else { -+ pi->aa = pp; -+ -+ while ((short) pi->aa >= 0) { -+ pi->dd *= 2; -+ if (pic2_read_bits(pi, 1)) -+ pi->dd++; -+ pi->aa *= 2; -+ } -+ return (0); -+ } -+} -+ -+static short pic2_arith_decode_nn(pi, c) -+struct pic2_info *pi; -+int c; -+{ -+ int n; -+ -+ if (pic2_arith_decode_bit(pi, c)) { -+ /* n < 1 */ -+ n = 0; -+ } else if (pic2_arith_decode_bit(pi, c + 1)) { -+ /* n < 1 + 2 */ -+ n = 1; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ } else if (pic2_arith_decode_bit(pi, c + 2)) { -+ /* n < 1 + 2 + 4 */ -+ n = 1 + 2; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ } else if (pic2_arith_decode_bit(pi, c + 3)) { -+ /* n < 1 + 2 + 4 + 8 */ -+ n = 1 + 2 + 4; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ if (pic2_arith_decode_bit(pi, c + 10)) -+ n += 4; -+ } else if (pic2_arith_decode_bit(pi, c + 4)) { -+ /* n < 1 + 2 + 4 + 8 + 16 */ -+ n = 1 + 2 + 4 + 8; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ if (pic2_arith_decode_bit(pi, c + 10)) -+ n += 4; -+ if (pic2_arith_decode_bit(pi, c + 11)) -+ n += 8; -+ } else if (pic2_arith_decode_bit(pi, c + 5)) { -+ /* n < 1 + 2 + 4 + 8 + 16 + 32 */ -+ n = 1 + 2 + 4 + 8 + 16; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ if (pic2_arith_decode_bit(pi, c + 10)) -+ n += 4; -+ if (pic2_arith_decode_bit(pi, c + 11)) -+ n += 8; -+ if (pic2_arith_decode_bit(pi, c + 12)) -+ n += 16; -+ -+ } else if (pic2_arith_decode_bit(pi, c + 6)) { -+ /* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 */ -+ n = 1 + 2 + 4 + 8 + 16 + 32; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ if (pic2_arith_decode_bit(pi, c + 10)) -+ n += 4; -+ if (pic2_arith_decode_bit(pi, c + 11)) -+ n += 8; -+ if (pic2_arith_decode_bit(pi, c + 12)) -+ n += 16; -+ if (pic2_arith_decode_bit(pi, c + 13)) -+ n += 32; -+ -+ } else if (pic2_arith_decode_bit(pi, c + 7)) { -+ /* n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 */ -+ n = 1 + 2 + 4 + 8 + 16 + 32 + 64; -+ if (pic2_arith_decode_bit(pi, c + 8)) -+ n += 1; -+ if (pic2_arith_decode_bit(pi, c + 9)) -+ n += 2; -+ if (pic2_arith_decode_bit(pi, c + 10)) -+ n += 4; -+ if (pic2_arith_decode_bit(pi, c + 11)) -+ n += 8; -+ if (pic2_arith_decode_bit(pi, c + 12)) -+ n += 16; -+ if (pic2_arith_decode_bit(pi, c + 13)) -+ n += 32; -+ if (pic2_arith_decode_bit(pi, c + 14)) -+ n += 64; -+ -+ } else { -+ n = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128; -+ } -+ return (n); -+} -+ -+static void pic2_arith_expand_chain(pi, x, y, cc) -+struct pic2_info *pi; -+int x, y; -+pixel cc; -+{ -+ static const unsigned short c_tab[] = { -+ 80 + 6 * 5, /* -5 */ -+ 80 + 6 * 4, -+ 80 + 6 * 3, -+ 80 + 6 * 2, -+ 80 + 6 * 1, -+ 80 + 6 * 0, /* 0 */ -+ 80 + 6 * 0, /* 1 */ -+ }; -+ unsigned short b; -+ -+ b = c_tab[pi->flag_now[x] + 5]; -+ if (!pic2_arith_decode_bit(pi, b++)) { -+ if (pic2_arith_decode_bit(pi, b++)) { /* down */ -+ pi->vram_next[x ] = cc; -+ pi->flag_next[x ] = -1; -+ } else if (pic2_arith_decode_bit(pi, b++)) { /* left */ -+ pi->vram_next[x - 1] = cc; -+ pi->flag_next[x - 1] = -2; -+ } else if (pic2_arith_decode_bit(pi, b++)) { /* right */ -+ pi->vram_next[x + 1] = cc; -+ pi->flag_next[x + 1] = -3; -+ } else if (pic2_arith_decode_bit(pi, b++)) { /* left2 */ -+ pi->vram_next[x - 2] = cc; -+ pi->flag_next[x - 2] = -4; -+ } else { /* right2 */ -+ pi->vram_next[x + 2] = cc; -+ pi->flag_next[x + 2] = -5; -+ } -+ } -+} -+ -+static short pic2_arith_get_number(pi, c, bef) -+struct pic2_info *pi; -+int c, bef; -+{ -+ unsigned short n; -+ byte maxcol; -+ -+ maxcol = 0xff >> (8 - pi->header->depth / 3); -+ -+ n = pic2_arith_decode_nn(pi, c); -+ if (bef > ((int) maxcol >> 1)) { -+ if (n > ((int) maxcol - bef) * 2) -+ n = maxcol - n; -+ else if (n & 1) -+ n = n / 2 + bef + 1; -+ else -+ n = bef - n / 2; -+ } else { -+ if ((int) n > (bef * 2)) -+ n = n; -+ else if (n & 1) -+ n = n / 2 + bef + 1; -+ else -+ n = bef - n / 2; -+ } -+ return (n); -+} -+ -+static pixel pic2_arith_read_color(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ pixel c1, c2, cc; -+ unsigned short i, j, k, m; -+ short r, g, b, r0, g0, b0; -+ short colbits; -+ pixel rmask, gmask, bmask; -+ byte maxcol; -+ -+ colbits = pi->header->depth / 3; -+ rmask = (0xff >> (8 - colbits)) << (colbits * 2); -+ gmask = (0xff >> (8 - colbits)) << colbits; -+ bmask = (0xff >> (8 - colbits)); -+ maxcol = (byte) bmask; -+ -+ c1 = pi->vram_prev[x]; -+ k = ((c1 >> ((colbits - 3) * 3)) & 0x1c0) -+ | ((c1 >> ((colbits - 3) * 2)) & 0x038) -+ | ((c1 >> (colbits - 3) ) & 0x007); -+ if (colbits == 5) -+ k = pic2_exchange_rg(k, 3); -+ -+ if (pic2_arith_decode_bit(pi, pi->cache_hit_c)) { /* ouch */ -+ pi->cache_hit_c = 16; -+ -+ c2 = pi->vram_now[x - 1]; -+ r = ((c1 & rmask) + (c2 & rmask)) >> (colbits * 2 + 1); -+ g = ((c1 & gmask) + (c2 & gmask)) >> (colbits + 1); -+ b = ((c1 & bmask) + (c2 & bmask)) >> ( 1); -+ -+ g0 = pic2_arith_get_number(pi, 32, g); -+ r = r + g0 - g; -+ if (r > (short) maxcol) -+ r = maxcol; -+ else if (r < 0) -+ r = 0; -+ -+ b = b + g0 - g; -+ if (b > (short) maxcol) -+ b = maxcol; -+ else if (b < 0) -+ b = 0; -+ -+ r0 = pic2_arith_get_number(pi, 48, r); -+ b0 = pic2_arith_get_number(pi, 64, b); -+ -+ pi->cache_pos[k] = j = (pi->cache_pos[k] - 1) & (PIC2_ARITH_CACHE - 1); -+ pi->cache[k][j] = cc = (r0 << (colbits * 2)) | (g0 << colbits) | b0; -+ } else { -+ pi->cache_hit_c = 15; -+ -+ j = pic2_arith_decode_nn(pi, 17); -+ m = pi->cache_pos[k]; -+ i = (m + j / 2) & (PIC2_ARITH_CACHE - 1); -+ j = (m + j) & (PIC2_ARITH_CACHE - 1); -+ -+ cc = pi->cache[k][j]; -+ pi->cache[k][j] = pi->cache[k][i]; -+ pi->cache[k][i] = pi->cache[k][m]; -+ pi->cache[k][m] = cc; -+ } -+ return (cc); -+} -+ -+static int pic2_arith_expand_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int ymax; -+ int x, xw; -+ pixel cc; -+ -+ pic2_handle_para(pi, 0); -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid - 1; -+ -+ if (pi->ynow > ymax) -+ return (-2); /* end */ -+ -+ /* set right end of previous line before left end of current line. */ -+ if (pi->ynow == 0) { -+ cc = 0; -+ } else -+ cc = pi->vram_prev[xw - 1]; -+ pi->vram_now[-1] = cc; -+ -+ /* clear flag for change point */ -+ xvbzero((char *) pi->flag_next, xw * sizeof(pi->flag_next[0])); -+ -+ /* clear flag for position probability space */ -+ xvbzero((char *) pi->flag2_next2, xw * sizeof(pi->flag2_next2[0])); -+ -+ for (x = 0; x < xw; x++) { -+ if (pi->flag_now[x] < 0) { -+ cc = pi->vram_now[x]; -+ if (pi->ynow < ymax) -+ pic2_arith_expand_chain(pi, x, pi->ynow, cc); -+ } else if (pic2_arith_decode_bit(pi, pi->flag2_now[x])) { -+ /* ajust probability space around of change point */ -+ pi->flag2_now [x + 1]++; -+ pi->flag2_now [x + 2]++; -+ pi->flag2_next [x - 1]++; -+ pi->flag2_next [x ]++; -+ pi->flag2_next [x + 1]++; -+ pi->flag2_next2[x - 1]++; -+ pi->flag2_next2[x ]++; -+ pi->flag2_next2[x + 1]++; -+ -+ pi->vram_now[x] = cc = pic2_arith_read_color(pi, x); -+ if (pi->ynow < ymax) -+ pic2_arith_expand_chain(pi, x, pi->ynow, cc); -+ } else -+ pi->vram_now[x] = cc; -+ } -+ if (line != NULL) -+ *line = pi->vram_now; -+ pi->ynow++; -+ -+ pic2_handle_para(pi, 1); -+ -+ return (pi->ynow - 1); -+} -+ -+static int pic2_arith_loader_init(pi) -+struct pic2_info *pi; -+{ -+ unsigned short p2b[256]; -+ int i, xw; -+ -+ pi->ynow = 0; -+ -+ /* check the color depth */ -+ if (pi->header->depth % 3) -+ pic2_error(pi, PIC2_DEPTH); -+ -+ /* set function for extract next line */ -+ pi->next_line = pic2_arith_expand_line; -+ -+ /* clear cache and flags */ -+ xw = pi->block->x_wid; -+ xvbzero((char *) pi->cache, 8 * 8 * 8 * sizeof(pi->cache[0])); -+ xvbzero((char *) pi->cache_pos, 8 * 8 * 8 * sizeof(pi->cache_pos[0])); -+ -+ xvbzero((char *) pi->flag_now, xw * sizeof(pi->flag_now[0])); -+ xvbzero((char *) pi->flag2_now, 8 + xw * sizeof(pi->flag2_now[0])); -+ xvbzero((char *) pi->flag2_next, 8 + xw * sizeof(pi->flag2_next[0])); -+ -+ /* go to picture data field */ -+ pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ -+ /* clear bit field marker */ -+ pi->bs.rest = 0; -+ pi->bs.cur = 0; -+ -+ /* read probability table */ -+ for (i = 0; i < PIC2_ARITH_CONTEXT; i++) -+ p2b[i] = pic2_read_short(pi); -+ -+ /* make multiplication table */ -+ for (i = 0; i < 16384; i++) { -+ pi->mulu_tab[i] = (long) (i / 128 + 128) * (int) p2b[i & 127] / 256; -+ if (pi->mulu_tab[i] == 0) pi->mulu_tab[i] = 1; -+ } -+ /* initialize some valuables */ -+ pi->aa = 0xffff; -+ pi->dd = 0; -+ for (i = 0; i < 16; i++) { -+ pi->dd *= 2; -+ if (pic2_read_bits(pi, 1)) -+ pi->dd |= 1; -+ } -+ pi->cache_hit_c = 16; -+ -+ return (0); -+} -+ -+/* -+ * These functions are fast pic2 compression extractor. -+ */ -+static int pic2_fast_read_length(pi) -+struct pic2_info *pi; -+{ -+ int a; -+ -+ a = 0; -+ while (pic2_read_bits(pi, 1)) { -+ a++; -+ } -+ if (a == 0) -+ return (0); -+ return (pic2_read_bits(pi, a) + (1 << a) - 1); -+} -+ -+static void pic2_fast_expand_chain(pi, x, cc) -+struct pic2_info *pi; -+int x; -+pixel cc; -+{ -+ if (pic2_read_bits(pi, 1) != 0) { -+ if (pic2_read_bits(pi, 1) != 0) { /* down */ -+ pi->vram_next[x] = cc; -+ pi->flag_next[x] = -1; -+ } else if (pic2_read_bits(pi, 1) != 0) { -+ if (pic2_read_bits(pi, 1) == 0) { /* left2down */ -+ pi->vram_next[x - 2] = cc; -+ pi->flag_next[x - 2] = -1; -+ } else { /* left1down */ -+ pi->vram_next[x - 1] = cc; -+ pi->flag_next[x - 1] = -1; -+ } -+ } else { -+ if (pic2_read_bits(pi, 1) == 0) { /* right2down */ -+ pi->vram_next[x + 2] = cc; -+ pi->flag_next[x + 2] = -1; -+ } else { /* left1down */ -+ pi->vram_next[x + 1] = cc; -+ pi->flag_next[x + 1] = -1; -+ } -+ } -+ } -+} -+ -+static pixel pic2_fast_read_color(pi, bc) -+struct pic2_info *pi; -+pixel bc; -+{ -+ pixel cc; -+ unsigned short j, k, m; -+ short depth, colbits; -+ pixel (*cache)[PIC2_FAST_CACHE]; -+ -+ depth = pi->header->depth; -+ colbits = depth / 3; -+ cache = (pixel (*)[PIC2_FAST_CACHE]) pi->cache; -+ -+ bc = pic2_exchange_rg(bc, colbits); -+ k = pic2_shift_bits(bc, 8 - depth); -+ if (pic2_read_bits(pi, 1) == 0) { -+ pi->cache_pos[k] = m = (pi->cache_pos[k] - 1) & (PIC2_FAST_CACHE - 1); -+ cc = pic2_read_bits(pi, depth); -+ cc = pic2_exchange_rg(cc, colbits); -+ cache[k][m] = cc; -+ } else { -+ j = pic2_read_bits(pi, 6); /* 6= log2(PIC2_FAST_CACHE) */ -+ m = pi->cache_pos[k]; -+ cc = cache[k][(m + j) & (PIC2_FAST_CACHE - 1)]; -+ } -+ return (cc); -+} -+ -+static int pic2_fast_expand_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int ymax; -+ int x, xw; -+ pixel cc; -+ -+ pic2_handle_para(pi, 0); -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid - 1; -+ -+ if (pi->ynow > ymax) -+ return (-2); -+ -+ if (pi->ynow == 0) { -+ pi->dd = 0; -+ pi->aa = pic2_fast_read_length(pi); -+ if (pi->aa == 1023) -+ pi->dd = 1023; -+ else if (pi->aa > 1023) -+ pi->aa--; -+ cc = 0; -+ } else -+ cc = pi->vram_prev[xw - 1]; -+ -+ xvbzero((char *) pi->flag_next, xw * sizeof(pi->flag_next[0])); -+ -+ for (x = 0; x < xw; x++) { -+ if (pi->dd > 0) { -+ if (pi->flag_now[x] < 0) { /* on chain ? */ -+ cc = pi->vram_now[x]; -+ pic2_fast_expand_chain(pi, x, cc); -+ if (--pi->dd == 0) { -+ pi->aa = pic2_fast_read_length(pi); -+ if (pi->aa == 1023) -+ pi->dd = 1023; -+ else if (pi->aa > 1023) -+ pi->aa--; -+ } -+ } else -+ pi->vram_now[x] = cc; -+ } else { -+ if (pi->flag_now[x] < 0) { /* on chain ? */ -+ cc = pi->vram_now[x]; -+ pic2_fast_expand_chain(pi, x, cc); -+ } else if (--pi->aa < 0) { -+ cc = pi->vram_now[x] = pic2_fast_read_color(pi, cc); -+ pic2_fast_expand_chain(pi, x, cc); -+ pi->aa = pic2_fast_read_length(pi); -+ if (pi->aa == 1023) -+ pi->dd = 1023; -+ else if (pi->aa > 1023) -+ pi->aa--; -+ } else -+ pi->vram_now[x] = cc; -+ } -+ } -+ if (line != NULL) -+ *line = pi->vram_now; -+ pi->ynow++; -+ -+ pic2_handle_para(pi, 1); -+ -+ return (pi->ynow - 1); -+} -+ -+static int pic2_fast_loader_init(pi) -+struct pic2_info *pi; -+{ -+ int xw; -+ -+ pi->ynow = 0; -+ -+ /* check the color depth */ -+ if (pi->header->depth % 3) -+ pic2_error(pi, PIC2_DEPTH); -+ -+ /* set function for extract next line */ -+ pi->next_line = pic2_fast_expand_line; -+ -+ /* clear cache and flags */ -+ xw = pi->block->x_wid; -+ xvbzero((char *) pi->cache, sizeof(pi->cache[0]) * 256); -+ xvbzero((char *) pi->cache_pos, sizeof(pi->cache_pos[0]) * 8 * 8 * 8); -+ xvbzero((char *) pi->flag_now, (xw + 8) * sizeof(pi->flag_now[0])); -+ xvbzero((char *) pi->flag_next, (xw + 8) * sizeof(pi->flag_next[0])); -+ -+ /* go to picture data field */ -+ pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ -+ /* clear bit field marker */ -+ pi->bs.rest = 0; -+ pi->bs.cur = 0; -+ -+ return (0); -+} -+ -+/* -+ * These functions are beta pic2 format extractor. -+ */ -+static int pic2_beta_expand_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int i, xw, ymax; -+ byte a, b, c, *p; -+ pixel *pc; -+ short depth, pixbyte, colbits; -+ -+ depth = pi->header->depth; -+ pixbyte = depth / 8 + ((depth % 8) > 0); -+ colbits = depth / 3; -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid - 1; -+ -+ if (pi->ynow > ymax) -+ return (-2); /* end */ -+ -+ pc = pi->vram_now; -+ p = (byte *) pi->vram_prev; -+ if (pixbyte == 3) { -+ pic2_read_file(pi, pi->vram_prev, (size_t) (xw * pixbyte)); -+ for (i = 0; i < xw; i++, pc++) { -+ a = *p++; -+ b = *p++; -+ c = *p++; -+ *pc = ((pixel) a << 16) | ((pixel) b << 8) | (pixel) c; -+ } -+ } else if (pixbyte == 2) { -+ pic2_read_file(pi, pi->vram_prev, (size_t) (xw * 2)); -+ if (strncmp(pi->block->id, "P2BM", 4) == 0) { -+ for (i = 0; i < xw; i++, pc++) { -+ a = *p++; -+ b = *p++; -+ *pc = ((pixel) a << 8) | (pixel) b; -+ if (colbits == 5) { -+ *pc >>= 1; -+ *pc = pic2_exchange_rg(*pc, colbits); -+ } -+ } -+ } else { -+ for (i = 0; i < xw; i++, pc++) { -+ a = *p++; -+ b = *p++; -+ *pc = ((pixel) b << 8) | (pixel) a; -+ if (colbits == 5) { -+ *pc >>= 1; -+ *pc = pic2_exchange_rg(*pc, colbits); -+ } -+ } -+ } -+ } else { -+ pic2_read_file(pi, pi->vram_prev, (size_t) xw); -+ for (i = 0; i < xw; i++) -+ *pc++ = *p++; -+ } -+ if (line != NULL) -+ *line = pi->vram_now; -+ -+ pc = pi->vram_prev; -+ pi->vram_prev = pi->vram_now; -+ pi->vram_now = pi->vram_next; -+ pi->vram_next = pc; -+ -+ pi->ynow++; -+ return (pi->ynow - 1); -+} -+ -+static int pic2_beta_loader_init(pi) -+struct pic2_info *pi; -+{ -+ pi->ynow = 0; -+ pi->next_line = pic2_beta_expand_line; -+ pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ return (0); -+} -+ -+/* -+ * Make a picture from the expanded data. -+ */ -+static void pic2_make_xvpic(pi, xp, rp, gp, bp) -+struct pic2_info *pi; -+byte **xp, *rp, *gp, *bp; -+{ -+ int line, i; -+ pixel *linep, opaque; -+ short colbits; -+ byte colmask; -+ -+ if (*xp == NULL) -+ *xp = pic2_new((size_t) pi->x_max * pi->y_max * 3, "pic2_make_xvpic"); // GRR POSSIBLE OVERFLOW / FIXME -+ -+ if (pi->block->flag & 1) -+ opaque = pi->block->opaque; -+ else -+ opaque = 0xffffffff; -+ -+ colbits = pi->header->depth / 3; -+ colmask = 0xff >> (8 - colbits); -+ -+ line = pic2_load_block(pi); -+ for (;;) { -+ int pic_idx; -+ -+ line = pic2_next_line(pi, &linep); -+ if (line < 0) -+ break; -+ pic_idx = ((line + pi->block->y_offset) * pi->x_max -+ + pi->block->x_offset) * 3; -+ -+ for (i = 0; i < pi->block->x_wid; i++, linep++) { -+ byte r, g, b; -+ -+ if (*linep != opaque) { -+ r = ((*linep >> (colbits * 2)) & colmask); -+ r = pic2_convert_color_bits(r, colbits, 8); -+ g = ((*linep >> colbits ) & colmask); -+ g = pic2_convert_color_bits(g, colbits, 8); -+ b = ( *linep & colmask); -+ b = pic2_convert_color_bits(b, colbits, 8); -+ (*xp)[pic_idx++] = r; -+ (*xp)[pic_idx++] = g; -+ (*xp)[pic_idx++] = b; -+ } else -+ pic_idx += 3; -+ -+ WaitCursor(); -+ } -+ } -+} -+ -+/* -+ * This function splits a multiblock PIC2 file into several pages. -+ */ -+static void pic2_make_pagefile(pi, pagebname, pnum) -+struct pic2_info *pi; -+char *pagebname; -+int pnum; -+{ -+ struct pic2_info pic2; -+ FILE *fp; -+ char pagefile[64], *buf; -+ size_t imagesize; -+ -+ sprintf(pagefile, "%s%d", pagebname, pnum); -+ if ((fp = fopen(pagefile, "wb")) == NULL) -+ pic2_error(pi, PIC2_WRITE); -+ -+ xvbcopy((char *) pi, (char *) &pic2, sizeof(struct pic2_info)); -+ pic2.fp = fp; -+ -+ pic2_write_header1(&pic2); -+ -+ pic2_write_block_header(&pic2); -+ -+ imagesize = pi->block->size - PIC2_BLOCK_HEADER_SIZE; -+ buf = (char *) pic2_malloc(imagesize, "pic2_make_pagefile"); -+ -+ pic2_seek_file(pi, pi->block_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ if (fread(buf, (size_t) 1, imagesize, pi->fp) < imagesize) { -+ free(buf); -+ pic2_file_error(pi, PIC2_CORRUPT); -+ } -+ if (fwrite(buf, (size_t) 1, imagesize, fp) < imagesize) { -+ free(buf); -+ pic2_error(pi, PIC2_WRITE); -+ } -+ free(buf); -+ -+ pic2.next_pos = pic2_tell_file(&pic2); -+ pic2_write_header2(&pic2); -+ -+ fclose(fp); -+} -+ -+/* The main routine to save a PIC2 file. */ -+static int WritePIC2(fp, pic0, ptype, w, h, rmap, gmap, bmap, numcols, -+ colorstyle, fname, type, depth, x_offset, y_offset, -+ append, comment) -+FILE *fp; -+byte *pic0; -+int ptype, w, h; -+byte *rmap, *gmap, *bmap; -+int numcols, colorstyle; -+char *fname; -+int type, depth; -+int x_offset, y_offset; -+int append; -+char *comment; -+{ -+ struct pic2_info pic2; -+ char creator[256], title[256], saver[256]; -+ int e; -+ -+ if (DEBUG) -+ fputs("WritePIC2:\n", stderr); -+ -+ pic2_init_info(&pic2); -+ pic2.fp = fp; -+ pic2.writing_grey = (colorstyle == F_GREYSCALE); -+ -+ if ((e = setjmp(pic2.jmp)) != 0){ -+ /* When an error occurs while writing, comes here. */ -+ pic2_free_buffer(&pic2); -+ pic2_cleanup_pic2_info(&pic2, 1); -+ SetCursors(-1); -+ if (DEBUG) -+ fputs("\n", stderr); -+ return (-1); -+ } -+ sprintf(creator, "XV Version %s", VERSTR); -+ pic2_strncpy(title, comment, 30); -+ sprintf(saver, "XV %s/UNIX/Bradley", VERSTR); -+ -+ if (!append) { -+ pic2_setup_pic2_info(&pic2, creator, fname, title, saver, -+ 0, depth, 1, 1, w, h, comment); -+ pic2_write_header1(&pic2); -+ } else { -+ pic2_read_header(&pic2); -+ pic2_append(&pic2); -+ free(pic2.comment); -+ pic2_setup_pic2_info(&pic2, creator, fname, title, saver, -+ 0, depth, 1, 1, w, h, comment); -+ } -+ -+ pic2_write_data(&pic2, pic0, ptype, x_offset, y_offset, w, h, -+ rmap, gmap, bmap, type, depth); -+ pic2_write_header2(&pic2); -+ -+ pic2_cleanup_pic2_info(&pic2, 1); -+ SetCursors(-1); -+ if (DEBUG) -+ fputs("\n", stderr); -+ return (0); -+} -+ -+/* -+ * This function initializes pic2_info. -+ */ -+static void pic2_setup_pic2_info(pi, name, fname, title, saver, no, depth, -+ x_aspect, y_aspect, x_max, y_max, comment) -+struct pic2_info *pi; -+char *name, *fname, *title, *saver; -+int no, depth; -+int x_aspect, y_aspect; -+int x_max, y_max; -+char *comment; -+{ -+ char basename[256], *suffix; -+ -+ pi->mode = PIC2_WRITE_MODE; -+ -+ /* set magic number */ -+ strncpy(pi->header->magic, pic2_id, 4); -+ -+ /* set creator's name */ -+ pic2_strncpy(pi->header->name, (char *) name, 18); -+ -+ /* set title and subtitle */ -+ pic2_strncpy(pi->header->title, (char *) title, 30); -+ strcpy(basename, BaseName(fname)); -+ suffix = (char *) rindex(basename, '.'); -+ if (suffix) { -+ suffix++; -+ if (!strcmp(suffix, "p2") || !strcmp(suffix, "P2")) -+ *(suffix - 1) = '\0'; -+ } -+ pic2_strncpy(pi->header->subtitle, basename, 8); -+ -+ /* set saver */ -+ pic2_strncpy(pi->header->saver, saver, 30); -+ -+ /* set picture number */ -+ pi->header->no = no; -+ -+ /* import comment */ -+ pi->comment = comment; -+ -+ /* set some picture's info */ -+ pi->header->depth = depth; -+ pi->header->x_aspect = x_aspect; -+ pi->header->y_aspect = y_aspect; -+ pi->header->x_max = x_max; -+ pi->header->y_max = y_max; -+ -+ /* set some gaps */ -+ pi->header->crlf0[0] = pi->header->crlf1[0] = pi->header->crlf2[0] = 0x0d; -+ pi->header->crlf0[1] = pi->header->crlf1[1] = pi->header->crlf2[1] = 0x0a; -+ -+ pi->header->eof[0] = 0x1a; -+ pi->header->reserve0[0] = 0; -+ pi->header->reserve1 = 0; -+ -+ /* set palettes */ -+ if (pi->n_pal > 0) -+ pi->header->flag = 1; -+ else -+ pi->header->flag = 0; -+} -+ -+/* -+ * This function appends to existing pic2 file. -+ */ -+static void pic2_append(pi) -+struct pic2_info *pi; -+{ -+ int block; -+ -+ block = pic2_find_block(pi); -+ while (block > 0) -+ block = pic2_next_block(pi); -+ -+ if (block != 0) -+ pic2_error(pi, PIC2_APPEND); -+} -+ -+/* -+ * These functions write the PIC2 header. -+ * pic2_write_header1: -+ * write palette data and comment. -+ * pic2_write_header2: -+ * write the terminate block and rest header. -+ * pic2_write_block_header: -+ * write the block header. -+ */ -+static void pic2_write_header1(pi) -+struct pic2_info *pi; -+{ -+ char *comment; -+ -+ /* seek to block start position */ -+ pic2_seek_file(pi, PIC2_HEADER_SIZE, SEEK_SET); -+ -+ /* write palette */ -+ if (pi->n_pal > 0) { -+ pic2_write_char(pi, pi->pal_bits); -+ pic2_write_short(pi, pi->n_pal); -+ pic2_write_file(pi, pi->pal, (size_t) (pi->n_pal * 3)); -+ } -+ /* save comment */ -+ comment = pi->comment; -+ if (pi->comment != NULL) { -+ for (comment = pi->comment; *comment; comment++) { -+ if (*comment == '\n') { -+ pic2_write_char(pi, '\r'); -+ pic2_write_char(pi, '\n'); -+ } else if (*comment != '\r') -+ pic2_write_char(pi, *comment); -+ } -+ pic2_write_char(pi, 0); -+ } -+ /* set the next block position */ -+ pi->next_pos = pic2_tell_file(pi); -+ pi->header->size = pi->next_pos; -+} -+ -+static void pic2_write_header2(pi) -+struct pic2_info *pi; -+{ -+ pic2_seek_file(pi, pi->next_pos, SEEK_SET); -+ -+ /* write terminate block */ -+ pic2_write_long(pi, 0); -+ pic2_write_long(pi, 0); -+ -+ /* set some header information */ -+ if (pi->header->x_max < pi->x_max) -+ pi->header->x_max = pi->x_max; -+ if (pi->header->y_max < pi->x_max) -+ pi->header->y_max = pi->y_max; -+ -+ pi->header->time = time(NULL); -+ pic2_seek_file(pi, 0, SEEK_SET); -+ -+ /* write header image */ -+ pic2_write_file(pi, pi->header->magic, 4); -+ pic2_write_file(pi, pi->header->name, 18); -+ pic2_write_file(pi, pi->header->subtitle, 8); -+ pic2_write_file(pi, pi->header->crlf0, 2); -+ pic2_write_file(pi, pi->header->title, 30); -+ pic2_write_file(pi, pi->header->crlf1, 2); -+ pic2_write_file(pi, pi->header->saver, 30); -+ pic2_write_file(pi, pi->header->crlf2, 2); -+ pic2_write_file(pi, pi->header->eof, 1); -+ pic2_write_file(pi, pi->header->reserve0, 1); -+ pic2_write_short(pi, pi->header->flag); -+ pic2_write_short(pi, pi->header->no); -+ pic2_write_long(pi, pi->header->time); -+ pic2_write_long(pi, pi->header->size); -+ pic2_write_short(pi, pi->header->depth); -+ pic2_write_short(pi, pi->header->x_aspect); -+ pic2_write_short(pi, pi->header->y_aspect); -+ pic2_write_short(pi, pi->header->x_max); -+ pic2_write_short(pi, pi->header->y_max); -+ pic2_write_long(pi, pi->header->reserve1); -+} -+ -+static void pic2_write_block_header(pi) -+struct pic2_info *pi; -+{ -+ pic2_write_file(pi, pi->block->id, 4); -+ pic2_write_long(pi, pi->block->size); -+ pic2_write_short(pi, pi->block->flag); -+ pic2_write_short(pi, pi->block->x_wid); -+ pic2_write_short(pi, pi->block->y_wid); -+ pic2_write_short(pi, pi->block->x_offset); -+ pic2_write_short(pi, pi->block->y_offset); -+ pic2_write_long(pi, pi->block->opaque); -+ pic2_write_long(pi, pi->block->reserve); -+} -+ -+/* -+ * These functions implement the arithmetic-format compressor. -+ */ -+#define pic2_arith_write_one_bit(pi) (pi->bs.bits++) -+ -+static void pic2_arith_write_zero_bit(pi) -+struct pic2_info *pi; -+{ -+ if (pi->bs.zero) -+ pic2_write_bits(pi, 0, 1); -+ -+ while (pi->bs.bits--) -+ pic2_write_bits(pi, 1, 1); -+ -+ pi->bs.bits = 0; -+ pi->bs.zero = 1; -+} -+ -+static void pic2_arith_flush_bit_buf(pi) -+struct pic2_info *pi; -+{ -+ int i; -+ -+ for (i = 0; i < 16; i++) { -+ if (pi->cc & 0x8000) -+ pic2_arith_write_one_bit(pi); -+ else -+ pic2_arith_write_zero_bit(pi); -+ pi->cc <<= 1; -+ } -+ pic2_arith_write_zero_bit(pi); -+ pic2_flush_bits(pi); -+} -+ -+static void pic2_arith_carry_bit(pi) -+struct pic2_info *pi; -+{ -+ pic2_write_bits(pi, 1, 1); -+ -+ if (pi->bs.bits == 0) { -+ pi->bs.zero = 0; -+ } else { -+ while (--pi->bs.bits) -+ pic2_write_bits(pi, 0, 1); -+ pi->bs.zero = 1; -+ } -+} -+ -+static void pic2_arith_encode_bit(pi, n, c) -+struct pic2_info *pi; -+int n, c; -+{ -+ int pp; -+ long *c_sum, *c_0_sum; -+ -+ c_sum = (long *) pi->mulu_tab; -+ c_0_sum = c_sum + PIC2_ARITH_CONTEXT + 1; -+ -+ if (pi->dd == 0) { -+ c_sum[c]++; -+ if (n == 0) -+ c_0_sum[c]++; -+ return; -+ } -+ pp = pi->mulu_tab[(pi->aa & 0x7f00) / 2 + c]; -+ if (n != 0) { -+ pi->cc = pi->cc + pp; -+ if (pi->cc > 0xffff) { -+ pic2_arith_carry_bit(pi); -+ pi->cc = pi->cc & 0xffff; -+ } -+ pi->aa = pi->aa - pp; -+ while (pi->aa < 0x8000) { -+ if (pi->cc & 0x8000) -+ pic2_arith_write_one_bit(pi); -+ else -+ pic2_arith_write_zero_bit(pi); -+ pi->cc = (pi->cc * 2) & 0xffff; -+ pi->aa = pi->aa * 2; -+ } -+ } else { -+ pi->aa = pp; -+ -+ while (pi->aa < 0x8000) { -+ if (pi->cc & 0x8000) -+ pic2_arith_write_one_bit(pi); -+ else -+ pic2_arith_write_zero_bit(pi); -+ pi->cc = (pi->cc * 2) & 0xffff; -+ pi->aa = pi->aa * 2; -+ } -+ } -+} -+ -+static void pic2_arith_encode_nbyte(pi, n, c, max) -+struct pic2_info *pi; -+int n, c, max; -+{ -+ short i; -+ -+ for (i = 0; i < n; i++) { -+ pic2_arith_encode_bit(pi, 0, c + i); -+ } -+ if (n < max) -+ pic2_arith_encode_bit(pi, 1, c + n); -+} -+ -+static void pic2_arith_encode_nn(pi, n, c) -+struct pic2_info *pi; -+int n, c; -+{ -+ if (n < 1) { -+ pic2_arith_encode_bit(pi, 1, c); -+ } else if (n < 1 + 2) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 1, c + 1); -+ n -= 1; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ } else if (n < 1 + 2 + 4) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 1, c + 2); -+ n -= 1 + 2; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ } else if (n < 1 + 2 + 4 + 8) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 1, c + 3); -+ n -= 1 + 2 + 4; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ pic2_arith_encode_bit(pi, n & 4, c + 10); -+ } else if (n < 1 + 2 + 4 + 8 + 16) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 0, c + 3); -+ pic2_arith_encode_bit(pi, 1, c + 4); -+ n -= 1 + 2 + 4 + 8; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ pic2_arith_encode_bit(pi, n & 4, c + 10); -+ pic2_arith_encode_bit(pi, n & 8, c + 11); -+ } else if (n < 1 + 2 + 4 + 8 + 16 + 32) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 0, c + 3); -+ pic2_arith_encode_bit(pi, 0, c + 4); -+ pic2_arith_encode_bit(pi, 1, c + 5); -+ n -= 1 + 2 + 4 + 8 + 16; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ pic2_arith_encode_bit(pi, n & 4, c + 10); -+ pic2_arith_encode_bit(pi, n & 8, c + 11); -+ pic2_arith_encode_bit(pi, n & 16, c + 12); -+ } else if (n < 1 + 2 + 4 + 8 + 16 + 32 + 64) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 0, c + 3); -+ pic2_arith_encode_bit(pi, 0, c + 4); -+ pic2_arith_encode_bit(pi, 0, c + 5); -+ pic2_arith_encode_bit(pi, 1, c + 6); -+ n -= 1 + 2 + 4 + 8 + 16 + 32; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ pic2_arith_encode_bit(pi, n & 4, c + 10); -+ pic2_arith_encode_bit(pi, n & 8, c + 11); -+ pic2_arith_encode_bit(pi, n & 16, c + 12); -+ pic2_arith_encode_bit(pi, n & 32, c + 13); -+ } else if (n < 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128) { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 0, c + 3); -+ pic2_arith_encode_bit(pi, 0, c + 4); -+ pic2_arith_encode_bit(pi, 0, c + 5); -+ pic2_arith_encode_bit(pi, 0, c + 6); -+ pic2_arith_encode_bit(pi, 1, c + 7); -+ n -= 1 + 2 + 4 + 8 + 16 + 32 + 64; -+ pic2_arith_encode_bit(pi, n & 1, c + 8); -+ pic2_arith_encode_bit(pi, n & 2, c + 9); -+ pic2_arith_encode_bit(pi, n & 4, c + 10); -+ pic2_arith_encode_bit(pi, n & 8, c + 11); -+ pic2_arith_encode_bit(pi, n & 16, c + 12); -+ pic2_arith_encode_bit(pi, n & 32, c + 13); -+ pic2_arith_encode_bit(pi, n & 64, c + 14); -+ } else { -+ pic2_arith_encode_bit(pi, 0, c); -+ pic2_arith_encode_bit(pi, 0, c + 1); -+ pic2_arith_encode_bit(pi, 0, c + 2); -+ pic2_arith_encode_bit(pi, 0, c + 3); -+ pic2_arith_encode_bit(pi, 0, c + 4); -+ pic2_arith_encode_bit(pi, 0, c + 5); -+ pic2_arith_encode_bit(pi, 0, c + 6); -+ pic2_arith_encode_bit(pi, 0, c + 7); -+ } -+} -+ -+static void pic2_arith_press_chain(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ int b, d; -+ pixel c; -+ -+ b = -(pi->flag_now[x]); -+ c = pi->vram_now[x]; -+ d = 0; -+ -+ if (b < 0) -+ b = 0; -+ -+ if (pi->flag_next[x] == 1 && pi->vram_next[x] == c) { -+ d = 1; -+ pi->flag_next[x] = -1; -+ } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == c) { -+ d = 2; -+ pi->flag_next[x - 1] = -2; -+ } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == c) { -+ d = 3; -+ pi->flag_next[x + 1] = -3; -+ } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == c) { -+ d = 4; -+ pi->flag_next[x - 2] = -4; -+ } else if (pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == c) { -+ if ((pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == c) -+ || (pi->flag_now[x + 1] != 0 && pi->vram_now[x + 1] == c) -+ || (pi->flag_now[x + 3] != 0 && pi->vram_now[x + 3] == c)) { -+ pic2_arith_encode_nbyte(pi, 0, 80 + 6 * b, 5); -+ return; -+ } -+ d = 5; -+ pi->flag_next[x + 2] = -5; -+ } -+ pic2_arith_encode_nbyte(pi, d, 80 + 6 * b, 5); -+} -+ -+static void pic2_arith_put_number(pi, xn, xa, xb) -+struct pic2_info *pi; -+int xn, xa, xb; -+{ -+ short n; -+ byte maxcol; -+ -+ maxcol = 0xff >> (8 - pi->header->depth / 3); -+ -+ if (xa > ((int) maxcol >> 1)) { -+ if (xb > xa) -+ n = (xb - xa) * 2 - 1; -+ else if (xa - ((int) maxcol - xa) > xb) -+ n = maxcol - xb; -+ else -+ n = (xa - xb) * 2; -+ } else { -+ if (xb <= xa) -+ n = (xa - xb) * 2; -+ else if (2 * xa < xb) -+ n = xb; -+ else -+ n = (xb - xa) * 2 - 1; -+ } -+ pic2_arith_encode_nn(pi, n, xn); -+} -+ -+static void pic2_arith_write_color(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ pixel c1, c2, cc; -+ short g0, r0, b0, r, g, b; -+ int i, j; -+ unsigned short k; -+ pixel *p, *pp; -+ short colbits; -+ pixel rmask, gmask, bmask; -+ byte maxcol; -+ -+ colbits = pi->header->depth / 3; -+ rmask = (0xff >> (8 - colbits)) << (colbits * 2); -+ gmask = (0xff >> (8 - colbits)) << colbits; -+ bmask = (0xff >> (8 - colbits)); -+ maxcol = (byte) bmask; -+ -+ cc = pi->vram_now[x]; -+ c1 = pi->vram_prev[x]; -+ k = ((c1 >> ((colbits - 3) * 3)) & 0x1c0) -+ | ((c1 >> ((colbits - 3) * 2)) & 0x038) -+ | ((c1 >> (colbits - 3) ) & 0x007); -+ if (colbits == 5) -+ k = pic2_exchange_rg(k, 3); -+ -+ p = pi->cache[k]; -+ for (i = 0; i < (PIC2_ARITH_CACHE - 1); i++) { -+ if (cc == *p++) -+ break; -+ } -+ if (i == (PIC2_ARITH_CACHE - 1)) { -+ pp = p - 1; -+ for (j = i; j > 0; j--) { -+ *--p = *--pp; -+ } -+ pi->cache[k][0] = cc; -+ pic2_arith_encode_bit(pi, 1, pi->cache_hit_c); -+ pi->cache_hit_c = 16; -+ -+ c2 = pi->vram_now[x - 1]; -+ r = ((c1 & rmask) + (c2 & rmask)) >> (colbits * 2 + 1); -+ g = ((c1 & gmask) + (c2 & gmask)) >> (colbits + 1); -+ b = ((c1 & bmask) + (c2 & bmask)) >> ( 1); -+ -+ r0 = (cc >> (colbits * 2)) & maxcol; -+ g0 = (cc >> colbits ) & maxcol; -+ b0 = cc & maxcol; -+ -+ r = r + g0 - g; -+ if (r < 0) -+ r = 0; -+ else if (r > (short) maxcol) -+ r = maxcol; -+ -+ b = b + g0 - g; -+ if (b < 0) -+ b = 0; -+ else if (b > (short) maxcol) -+ b = maxcol; -+ -+ pic2_arith_put_number(pi, 32, g, g0); -+ pic2_arith_put_number(pi, 48, r, r0); -+ pic2_arith_put_number(pi, 64, b, b0); -+ } else { -+ *--p = pi->cache[k][i / 2]; -+ pi->cache[k][i / 2] = pi->cache[k][0]; -+ pi->cache[k][0] = cc; -+ -+ pic2_arith_encode_bit(pi, 0, pi->cache_hit_c); -+ pi->cache_hit_c = 15; -+ pic2_arith_encode_nn(pi, i, 17); -+ } -+} -+ -+static void pic2_arith_press_line2(pi) -+struct pic2_info *pi; -+{ -+ int x, xw, ymax; -+ pixel cc; -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid -1; -+ cc = pi->vram_now[xw - 1]; /* last color */ -+ pi->vram_next[-1] = cc; -+ -+ /* mark change point */ -+ for (x = 0; x < xw; x++) -+ if (cc != pi->vram_next[x]) { -+ pi->flag_next[x] = 1; -+ cc = pi->vram_next[x]; -+ } else -+ pi->flag_next[x] = 0; -+ -+ for (x = 0; x < xw; x++) { -+ if (pi->flag_now[x] == 1) { /* change point */ -+ pi->flag2_now [x + 1]++; -+ pi->flag2_now [x + 2]++; -+ pi->flag2_next [x - 1]++; -+ pi->flag2_next [x ]++; -+ pi->flag2_next [x + 1]++; -+ pi->flag2_next2[x - 1]++; -+ pi->flag2_next2[x ]++; -+ pi->flag2_next2[x + 1]++; -+ -+ /* write change point */ -+ pic2_arith_encode_bit(pi, 1, pi->flag2_now[x]); -+ -+ /* write color */ -+ pic2_arith_write_color(pi, x); -+ -+ /* if not last line, write chain */ -+ if (pi->ynow - 1 < ymax) -+ pic2_arith_press_chain(pi, x); -+ } else if (pi->flag_now[x] == 0) /* not on chain */ -+ /* write change point */ -+ pic2_arith_encode_bit(pi, 0, pi->flag2_now[x]); -+ else /* on chain */ -+ /* if not on last line, write next chain */ -+ if (pi->ynow - 1 < ymax) -+ pic2_arith_press_chain(pi, x); -+ } -+} -+ -+static int pic2_arith_press_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int i, xw, ymax; -+ long *c_sum, *c_0_sum; -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid -1; -+ c_sum = (long *) pi->mulu_tab; -+ c_0_sum = c_sum + PIC2_ARITH_CONTEXT +1; -+ -+ pic2_handle_para(pi, 0); -+ -+ xvbzero((char *) pi->flag2_next2 - 4, -+ (8 + xw) * sizeof(pi->flag2_next2[0])); -+ -+ if (pi->ynow == 0) { /* first line */ -+ int x; -+ pixel cc = 0; -+ -+ if (pi->dd != 0) { /* compress pass */ -+ unsigned short c_tab[PIC2_ARITH_CONTEXT]; -+ -+ for (i = 0; i < PIC2_ARITH_CONTEXT; i++) { -+ unsigned long a, b; -+ a = c_0_sum[i]; -+ b = c_sum[i]; -+ while (a > 32767) { -+ a /= 2; -+ b /= 2; -+ } -+ if (a == b) -+ c_tab[i] = 0xffff; /* b==0 here, too */ -+ else -+ c_tab[i] = (65536 * a) / b; /* a < b, so less 65536 */ -+ } -+ for (i = 0; i < 16384; i++) { -+ pi->mulu_tab[i] = (long) (i / 128 + 128) * (int) c_tab[i & 127] / 256; -+ if (pi->mulu_tab[i] == 0) -+ pi->mulu_tab[i] = 1; /* 0 is wrong */ -+ } -+ for (i = 0; i < PIC2_ARITH_CONTEXT; i++) -+ pic2_write_short(pi, c_tab[i]); -+ -+ xvbzero((char *) pi->vram_now, xw * sizeof(pi->vram_now[0])); -+ } else { /* statistical pass */ -+ xvbzero((char *) c_0_sum, PIC2_ARITH_CONTEXT * sizeof(c_0_sum[0])); -+ xvbzero((char *) c_sum, PIC2_ARITH_CONTEXT * sizeof(c_sum[0])); -+ } -+ -+ /* initialize flags */ -+ xvbzero((char *) pi->cache, 8 * 8 * 8 * sizeof(pi->cache[0])); -+ xvbzero((char *) pi->cache_pos, 8 * 8 * 8 * sizeof(pi->cache_pos[0])); -+ -+ xvbzero((char *) pi->flag2_next - 4, -+ (8 + xw) * sizeof(pi->flag2_next[0])); -+ xvbzero((char *) pi->flag2_next2 - 4, -+ (8 + xw) * sizeof(pi->flag2_next2[0])); -+ -+ pi->vram_next[-1] = cc; -+ for (x = 0; x < xw; x++) -+ if (cc != pi->vram_next[x]) { -+ pi->flag_next[x] = 1; -+ cc = pi->vram_next[x]; -+ } else -+ pi->flag_next[x] = 0; -+ -+ pi->aa = 0xffff; -+ cc = 0; -+ pi->cache_hit_c = 16; -+ } else /* after second line */ -+ pic2_arith_press_line2(pi); -+ -+ if (pi->ynow == ymax) { -+ pi->ynow++; -+ pic2_handle_para(pi, 1); -+ pic2_handle_para(pi, 0); -+ pic2_arith_press_line2(pi); -+ } -+ /* line buffer for next data */ -+ if (line != NULL) -+ *line = pi->vram_prev; -+ -+ pi->ynow++; -+ -+ if (pi->ynow - 1 < ymax) { -+ pic2_handle_para(pi, 1); -+ return (pi->ynow); -+ } else { /* end */ -+ if (pi->dd == 0) { /* statistical pass */ -+ pi->dd = 1; -+ pi->ynow = 0; -+ pic2_handle_para(pi, 1); -+ return (0); -+ } else { -+ pic2_handle_para(pi, 1); -+ pic2_arith_flush_bit_buf(pi); -+ return (-2); /* end */ -+ } -+ } -+} -+ -+static int pic2_arith_saver_init(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ pi->ynow = 0; -+ -+ /* check the color depth */ -+ if (pi->header->depth % 3) -+ pic2_error(pi, PIC2_DEPTH); -+ -+ /* set next line function */ -+ pi->next_line = pic2_arith_press_line; -+ -+ if (line != NULL) -+ *line = pi->vram_next + 4; -+ -+ pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ -+ /* clear bit field marker */ -+ pi->bs.rest = 0; -+ pi->bs.cur = 0; -+ pi->bs.zero = 0; -+ pi->bs.bits = 0; -+ -+ return (0); -+} -+ -+/* -+ * These functions are fast pic2 format compressor. -+ */ -+static void pic2_fast_write_length(pi, n) -+struct pic2_info *pi; -+int n; -+{ -+ int a, b; -+ static const unsigned short len_data[8][2] = { -+ {1, 0}, -+ {1, 0}, -+ {3, 4}, -+ {3, 5}, -+ {5, 24}, -+ {5, 25}, -+ {5, 26}, -+ {5, 27}, -+ }; -+ -+ n++; -+ if (n < 8) -+ pic2_write_bits(pi, len_data[n][1], len_data[n][0]); -+ else { -+ a = 0; -+ b = 2; -+ while (n > b - 1) { -+ a = a + 1; -+ b = b * 2; -+ } -+ pic2_write_bits(pi, 0xfffffffe, a + 1); -+ if (a > 0) -+ pic2_write_bits(pi, n - b / 2, a); -+ } -+} -+ -+static void pic2_fast_press_chain(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ int ymax; -+ pixel cc; -+ -+ ymax = pi->block->y_wid -1; -+ cc = pi->vram_now[x]; -+ -+ if (pi->ynow - 1 == ymax) { -+ pic2_write_bits(pi, 0, 1); -+ return; -+ } -+ if (pi->flag_next[x] == 1 && pi->vram_next[x] == cc) { -+ pi->flag_next[x] = -1; -+ pic2_write_bits(pi, 3, 2); -+ } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == cc) { -+ pi->flag_next[x - 1] = -1; -+ pic2_write_bits(pi, 11, 4); -+ } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == cc) { -+ pi->flag_next[x + 1] = -1; -+ pic2_write_bits(pi, 9, 4); -+ } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == cc) { -+ pi->flag_next[x - 2] = -1; -+ pic2_write_bits(pi, 10, 4); -+ } else if ((pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == cc) -+ && !(pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == cc)) { -+ pi->flag_next[x + 2] = -1; -+ pic2_write_bits(pi, 8, 4); -+ } else -+ pic2_write_bits(pi, 0, 1); -+} -+ -+static void pic2_fast_press_chain2(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ int ymax; -+ pixel cc; -+ char *chain_buff; -+ -+ ymax = pi->block->y_wid -1; -+ chain_buff = (char *) pi->mulu_tab; -+ cc = pi->vram_now[x]; -+ -+ if (pi->ynow - 1 == ymax) { -+ chain_buff[pi->cc++] = 0; -+ return; -+ } -+ if (pi->flag_next[x] == 1 && pi->vram_next[x] == cc) { -+ pi->flag_next[x] = -1; -+ chain_buff[pi->cc++] = 1; -+ } else if (pi->flag_next[x - 1] == 1 && pi->vram_next[x - 1] == cc) { -+ pi->flag_next[x - 1] = -1; -+ chain_buff[pi->cc++] = 2; -+ } else if (pi->flag_next[x + 1] == 1 && pi->vram_next[x + 1] == cc) { -+ pi->flag_next[x + 1] = -1; -+ chain_buff[pi->cc++] = 3; -+ } else if (pi->flag_next[x - 2] == 1 && pi->vram_next[x - 2] == cc) { -+ pi->flag_next[x - 2] = -1; -+ chain_buff[pi->cc++] = 4; -+ } else if ((pi->flag_next[x + 2] == 1 && pi->vram_next[x + 2] == cc) -+ && !(pi->flag_now[x + 2] != 0 && pi->vram_now[x + 2] == cc)) { -+ pi->flag_next[x + 2] = -1; -+ chain_buff[pi->cc++] = 5; -+ } else -+ chain_buff[pi->cc++] = 0; -+} -+ -+static void pic2_fast_flush_chain(pi) -+struct pic2_info *pi; -+{ -+ int i; -+ char *chain_buf; -+ -+ chain_buf = (char *) pi->mulu_tab; -+ for (i = 0; i < pi->cc; i++){ -+ switch (chain_buf[i]) { -+ case 0: -+ pic2_write_bits(pi, 0, 1); -+ break; -+ case 1: -+ pic2_write_bits(pi, 3, 2); -+ break; -+ case 2: -+ pic2_write_bits(pi, 11, 4); -+ break; -+ case 3: -+ pic2_write_bits(pi, 9, 4); -+ break; -+ case 4: -+ pic2_write_bits(pi, 10, 4); -+ break; -+ case 5: -+ pic2_write_bits(pi, 8, 4); -+ break; -+ } -+ } -+ pi->cc = 0; -+} -+ -+static void pic2_fast_write_color(pi, x) -+struct pic2_info *pi; -+int x; -+{ -+ pixel cc, bc; -+ unsigned short j, k, m; -+ short depth, colbits; -+ pixel (*cache)[PIC2_FAST_CACHE]; -+ -+ depth = pi->header->depth; -+ colbits = depth / 3; -+ cache = (pixel (*)[PIC2_FAST_CACHE]) pi->cache; -+ -+ bc = pi->vram_now[x - 1]; -+ bc = pic2_exchange_rg(bc, colbits); -+ k = pic2_shift_bits(bc, 8 - depth); -+ cc = pi->vram_now[x]; -+ m = pi->cache_pos[k]; -+ -+ for (j = 0; j < PIC2_FAST_CACHE; j++) -+ if (cache[k][(m + j) & (PIC2_FAST_CACHE - 1)] == cc) -+ break; -+ -+ if (j == PIC2_FAST_CACHE) { -+ m = (m - 1) & (PIC2_FAST_CACHE - 1); -+ pi->cache_pos[k] = m; -+ cache[k][m] = cc; -+ -+ cc = pic2_exchange_rg(cc, colbits); -+ pic2_write_bits(pi, 0, 1); -+ pic2_write_bits(pi, cc, depth); -+ } else { -+ pic2_write_bits(pi, 1, 1); -+ pic2_write_bits(pi, j, 6); -+ } -+} -+ -+static void pic2_fast_press_line2(pi) -+struct pic2_info *pi; -+{ -+ int x, xw; -+ pixel cc; -+ -+ xw = pi->block->x_wid; -+ cc = pi->vram_now[xw - 1]; /* last color */ -+ pi->vram_next[-1] = cc; -+ -+ /* mark change point */ -+ for (x = 0; x < xw; x++) -+ if (cc != pi->vram_next[x]) { -+ pi->flag_next[x] = 1; -+ cc = pi->vram_next[x]; -+ } else -+ pi->flag_next[x] = 0; -+ -+ for (x = 0; x < xw; x++) -+ if (pi->flag_now[x] == 1) { /* change point */ -+ if (pi->aa >= 1023) -+ pi->aa++; -+ pic2_fast_write_length(pi, pi->aa); -+ pic2_fast_flush_chain(pi); -+ pi->aa = 0; -+ pic2_fast_write_color(pi, x); -+ pic2_fast_press_chain(pi, x); -+ } else if (pi->flag_now[x] == 0) { -+ pi->aa++; -+ } else { -+ pic2_fast_press_chain2(pi, x); -+ if (pi->cc == 1023) { -+ pic2_fast_write_length(pi, 1023); -+ pic2_fast_flush_chain(pi); -+ pi->aa = 0; -+ } -+ } -+} -+ -+static int pic2_fast_press_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int xw, ymax; -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid -1; -+ -+ pic2_handle_para(pi, 0); -+ -+ if (pi->ynow == 0) { /* first line */ -+ int x; -+ pixel cc = 0; -+ -+ /* initialize flags */ -+ xvbzero((char *) pi->cache, 256 * sizeof(pi->cache[0])); -+ xvbzero((char *) pi->cache_pos, -+ PIC2_FAST_CACHE * sizeof(pi->cache_pos[0])); -+ -+ /* mark change point */ -+ pi->vram_next[-1] = cc; -+ for (x = 0; x < xw; x++) -+ if (cc != pi->vram_next[x]) { -+ pi->flag_next[x] = 1; -+ cc = pi->vram_next[x]; -+ } else -+ pi->flag_next[x] = 0; -+ -+ pi->cc = 0; -+ pi->aa = 0; -+ } else /* after second line */ -+ pic2_fast_press_line2(pi); -+ -+ if (pi->ynow == ymax) { -+ pi->ynow++; -+ pic2_handle_para(pi, 1); -+ pic2_handle_para(pi, 0); -+ pic2_fast_press_line2(pi); -+ } -+ /* line buffer for next data */ -+ if (line != NULL) -+ *line = pi->vram_prev; -+ -+ pi->ynow++; -+ -+ if (pi->ynow - 1 < ymax) { -+ pic2_handle_para(pi, 1); -+ return (pi->ynow); -+ } else { /* end */ -+ pic2_handle_para(pi, 1); -+ if (pi->aa >= 1023) -+ pi->aa++; -+ pic2_fast_write_length(pi, pi->aa); -+ pic2_fast_flush_chain(pi); -+ return (-2); /* end */ -+ } -+} -+ -+static int pic2_fast_saver_init(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ pi->ynow = 0; -+ -+ /* check the color depth */ -+ if (pi->header->depth % 3) -+ pic2_error(pi, PIC2_DEPTH); -+ -+ /* set next line function */ -+ pi->next_line = pic2_fast_press_line; -+ if (line != NULL) -+ *line = pi->vram_next + 4; -+ -+ pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ -+ /* clear bit field marker */ -+ pi->bs.rest = 0; -+ pi->bs.cur = 0; -+ -+ return (0); -+} -+ -+/* -+ * These functions are beta pic2 format compressor. -+ */ -+static int pic2_beta_press_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int i, xw, ymax; -+ byte *p; -+ pixel *pc; -+ short depth, pixbyte, colbits; -+ -+ depth = pi->header->depth; -+ pixbyte = depth / 8 + ((depth % 8) > 0); -+ colbits = depth / 3; -+ -+ xw = pi->block->x_wid; -+ ymax = pi->block->y_wid - 1; -+ -+ pc = pi->vram_now; -+ p = (byte *) pi->vram_prev; -+ if (pixbyte == 3) { -+ for (i = 0; i < xw; i++, pc++) { -+ *p++ = *pc >> 16; -+ *p++ = *pc >> 8; -+ *p++ = *pc; -+ } -+ pic2_write_file(pi, pi->vram_prev, (size_t) (xw * 3)); -+ } else if (pixbyte == 2) { -+ if (strncmp(pi->block->id, "P2BM", 4) == 0) -+ for (i = 0; i < xw; i++, pc++) { -+ if (colbits == 5) { -+ *pc = pic2_exchange_rg(*pc, colbits); -+ *pc <<= 1; -+ } -+ *p++ = *pc >> 8; -+ *p++ = *pc; -+ } -+ else -+ for (i = 0; i < xw; i++, pc++) { -+ if (colbits == 5) { -+ *pc = pic2_exchange_rg(*pc, colbits); -+ *pc <<= 1; -+ } -+ *p++ = *pc; -+ *p++ = *pc >> 8; -+ } -+ pic2_write_file(pi, pi->vram_prev, (size_t) (xw * 2)); -+ } else { -+ for (i = 0; i < xw; i++, pc++) -+ *p++ = *pc; -+ pic2_write_file(pi, pi->vram_prev, (size_t) xw); -+ } -+ if (line != NULL) -+ *line = pi->vram_now; -+ -+ pi->ynow++; -+ if (pi->ynow > ymax) -+ return (-2); -+ return (pi->ynow); -+} -+ -+static int pic2_beta_saver_init(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ pi->ynow = 0; -+ -+ *line = pi->vram_now; -+ pi->next_line = pic2_beta_press_line; -+ pic2_seek_file(pi, pi->next_pos + PIC2_BLOCK_HEADER_SIZE, SEEK_SET); -+ return (0); -+} -+ -+/* -+ * This function saves compressed data. -+ */ -+static void pic2_write_data(pi, data, ptype, x_offset, y_offset, w, h, -+ rmap, gmap, bmap, type, depth) -+struct pic2_info *pi; -+byte *data; -+int ptype; -+int x_offset, y_offset; -+int w, h; -+byte *rmap, *gmap, *bmap; -+int type, depth; -+{ -+ int i, line; -+ pixel *linep; -+ short colbits; -+ -+ colbits = pi->header->depth / 3; -+ -+ line = pic2_save_block(pi, &linep, x_offset, y_offset, w, h, -+ form_tab[type].id, 0xffffffff); -+ while (line >= 0) { -+ byte r, g, b; -+ int pic_idx; -+ -+ pic_idx = line * w * ((ptype == PIC24) ? 3 : 1); -+ -+ for (i = 0; i < w; i++) { -+ if (ptype != PIC24) { -+ r = rmap[data[pic_idx]]; -+ g = gmap[data[pic_idx]]; -+ b = bmap[data[pic_idx]]; -+ pic_idx++; -+ } else { -+ r = data[pic_idx++]; -+ g = data[pic_idx++]; -+ b = data[pic_idx++]; -+ } -+ if (pi->writing_grey) -+ r = g = b = MONO(r, g, b); -+ -+ r = pic2_convert_color_bits(r, 8, colbits); -+ g = pic2_convert_color_bits(g, 8, colbits); -+ b = pic2_convert_color_bits(b, 8, colbits); -+ -+ linep[i] = ((pixel) r << (colbits * 2)) -+ | ((pixel) g << colbits ) -+ | ((pixel) b ); -+ } -+ line = pic2_next_line(pi, &linep); -+ WaitCursor(); -+ } -+} -+ -+/* -+ * This function compresses/extracts one line buffer. -+ */ -+static int pic2_next_line(pi, line) -+struct pic2_info *pi; -+pixel **line; -+{ -+ int res; -+ -+ res = pi->next_line(pi, line); -+ if (res == -2) { -+ if (pi->mode == PIC2_WRITE_MODE) { -+ long new_pos; -+ -+ new_pos = pic2_tell_file(pi); -+ pi->block->size = new_pos - pi->next_pos; -+ pic2_seek_file(pi, pi->next_pos, SEEK_SET); -+ pic2_write_block_header(pi); -+ pi->next_pos = new_pos; -+ if (DEBUG) -+ pic2_show_pic2_info(pi); -+ } -+ pic2_free_buffer(pi); -+ } -+ return (res); -+} -+ -+/* -+ * These functions find the pic2 image block. -+ * pic2_next_block: -+ * moves the file pointer to the next image block. -+ * pic2_find_block: -+ * finds the first image block and moves the file pointer there. -+ */ -+static int pic2_next_block(pi) -+struct pic2_info *pi; -+{ -+ int i; -+ -+ if (pi->mode != PIC2_READ_MODE) -+ return (-1); -+ -+ /* go to block for read */ -+ pic2_seek_file(pi, pi->next_pos, SEEK_SET); -+ -+ /* read the head of block header */ -+ pic2_read_block_header1(pi); -+ -+ /* end block ? */ -+ if (pi->block->id[0] == 0) -+ return (0); -+ -+ /* set current block */ -+ pi->block_pos = pi->next_pos; -+ -+ /* set next block */ -+ pi->next_pos += pi->block->size; -+ -+ /* check block id */ -+ for (i = 0; i < n_form_tab; i++) { -+ if (xvbcmp(pi->block->id, form_tab[i].id, (size_t) 4) == 0) -+ break; -+ } -+ if (i == n_form_tab) -+ return (2); -+ -+ /* read the rest of block header */ -+ pic2_read_block_header2(pi); -+ -+ if (pi->block->x_offset + pi->block->x_wid > pi->x_max) -+ pi->x_max = pi->block->x_offset + pi->block->x_wid; -+ -+ if (pi->block->y_offset + pi->block->y_wid > pi->y_max) -+ pi->y_max = pi->block->y_offset + pi->block->y_wid; -+ -+ if (DEBUG) -+ pic2_show_pic2_info(pi); -+ return (1); -+} -+ -+static int pic2_find_block(pi) -+struct pic2_info *pi; -+{ -+ if (pi->mode != PIC2_READ_MODE) -+ return (-1); -+ -+ pi->next_pos = pi->header->size; -+ return (pic2_next_block(pi)); -+} -+ -+/* -+ * These functions load/save the pic2 image block. -+ * pic2_load_block: -+ * initializes loader information with current block information. -+ * pic2_save_block: -+ * initializes saver information. -+ */ -+static int pic2_load_block(pi) -+struct pic2_info *pi; -+{ -+ int i; -+ -+ for (i = 0; i < n_form_tab; i++) { -+ if (xvbcmp(pi->block->id, form_tab[i].id, (size_t) 4) == 0) -+ break; -+ } -+ if (i == n_form_tab) -+ return (2); -+ -+ pic2_alloc_buffer(pi); -+ return (form_tab[i].loader_init(pi)); -+} -+ -+static int pic2_save_block(pi, line, x, y, xw, yw, id, opaque) -+struct pic2_info *pi; -+pixel **line; -+int x, y, xw, yw; -+char *id; -+pixel opaque; -+{ -+ int i; -+ -+ for (i = 0; i < n_form_tab; i++) { -+ if (xvbcmp(id, form_tab[i].id, (size_t) 4) == 0) -+ break; -+ } -+ if (i == n_form_tab) -+ return (2); -+ -+ strncpy(pi->block->id, id, 4); -+ pi->block->x_wid = xw; -+ pi->block->y_wid = yw; -+ pi->block->x_offset = x; -+ pi->block->y_offset = y; -+ pi->block->reserve = 0; -+ -+ if (x < 0) -+ x = 0; -+ if (y < 0) -+ y = 0; -+ if (x + xw > pi->x_max) -+ pi->x_max = x + xw; -+ if (y + yw > pi->y_max) -+ pi->y_max = y + yw; -+ -+ if (opaque != 0xffffffff) { -+ pi->block->flag = 1; -+ pi->block->opaque = opaque; -+ } else { -+ pi->block->flag = 0; -+ pi->block->opaque = 0; -+ } -+ pic2_alloc_buffer(pi); -+ -+ return (form_tab[i].saver_init(pi, line)); -+} -+ -+/* -+ * These functions set/get palettes. -+ * pic2_read_palette: -+ * copy the palettes from pic2_info to PICINFO. -+ * pic2_write_palette: -+ * copy the palettes from PICINFO to pic2_info. -+ */ -+#ifndef PIC2_IGNORE_UNUSED_FUNCTIONS -+static void pic2_read_palette(pi, r, g, b) -+struct pic2_info *pi; -+byte *r, *g, *b; -+{ -+ int i; -+ -+ if (pi->n_pal > 256) -+ pi->n_pal = 256; -+ -+ if (pi->pal_bits > 8) -+ pi->pal_bits = 8; -+ -+ for (i = 0; i < pi->n_pal; i++) { -+ *r++ =pic2_convert_color_bits(pi->pal[i][0] >> (8 - pi->pal_bits), -+ pi->pal_bits, 8); -+ *g++ =pic2_convert_color_bits(pi->pal[i][1] >> (8 - pi->pal_bits), -+ pi->pal_bits, 8); -+ *b++ =pic2_convert_color_bits(pi->pal[i][2] >> (8 - pi->pal_bits), -+ pi->pal_bits, 8); -+ } -+} -+ -+static void pic2_write_palette(pi, n_pal, pal_bits, r, g, b) -+struct pic2_info *pi; -+int n_pal, pal_bits; -+byte *r, *g, *b; -+{ -+ int i; -+ -+ if (n_pal > 256) -+ pi->n_pal = 256; -+ else -+ pi->n_pal = n_pal; -+ -+ if (pal_bits > 8) -+ pi->pal_bits = 8; -+ else -+ pi->pal_bits = pal_bits; -+ -+ for (i = 0; i < n_pal; i++) { -+ pi->pal[i][0] = pic2_convert_color_bits(*r++, 8, pal_bits) -+ << (8 - pal_bits); -+ pi->pal[i][1] = pic2_convert_color_bits(*g++, 8, pal_bits) -+ << (8 - pal_bits); -+ pi->pal[i][2] = pic2_convert_color_bits(*b++, 8, pal_bits) -+ << (8 - pal_bits); -+ } -+} -+#endif /* PIC2_IGNORE_UNUSED_FUNCTIONS */ -+ -+/* -+ * These functions handle color bits. -+ * pic2_convert_color_bits: -+ * converts color bits. -+ * pic2_pad_color_bits: -+ * pads color bits. -+ * pic2_reduce_color_bits: -+ * reduces color bits. -+ * pic2_exchange_rg: -+ * exchanges red and green values. -+ */ -+static byte pic2_convert_color_bits(c, from, to) -+int c, from, to; -+{ -+ if (from == to) -+ return ((byte) c); -+ else if (from < to) -+ return (pic2_pad_color_bits(c, from, to)); -+ else -+ return (pic2_reduce_color_bits(c, from, to)); -+} -+ -+static byte pic2_pad_color_bits(c, from, to) -+int c, from, to; -+{ -+ byte p = 0; -+ -+ do { -+ to -= from; -+ p |= pic2_shift_bits(c, to); -+ } while (to >= 0); -+ return (p); -+} -+ -+static byte pic2_reduce_color_bits(c, from, to) -+int c, from, to; -+{ -+ return ((byte) (c >> (from - to))); -+} -+ -+static pixel pic2_exchange_rg(p, colbits) -+pixel p; -+int colbits; -+{ -+ pixel rmask, gmask, bmask; -+ -+ rmask = (0xff >> (8 - colbits)) << (colbits * 2); -+ gmask = (0xff >> (8 - colbits)) << colbits; -+ bmask = (0xff >> (8 - colbits)); -+ -+ p = ((p << colbits) & rmask) -+ | ((p >> colbits) & gmask) -+ | ( p & bmask); -+ return (p); -+} -+ -+/* -+ * This function handles work memory buffer. -+ */ -+static void pic2_handle_para(pi, mode) -+struct pic2_info *pi; -+int mode; -+{ -+ static pixel *vram_prev, *vram_now, *vram_next; -+ static short *flag_now, *flag_next; -+ static short *flag2_now, *flag2_next, *flag2_next2; -+ -+ switch (mode) { -+ case 0: -+ vram_prev = pi->vram_prev; -+ vram_now = pi->vram_now; -+ vram_next = pi->vram_next; -+ flag_now = pi->flag_now; -+ flag_next = pi->flag_next; -+ flag2_now = pi->flag2_now; -+ flag2_next = pi->flag2_next; -+ flag2_next2 = pi->flag2_next2; -+ pi->vram_prev += 4; -+ pi->vram_now += 4; -+ pi->vram_next += 4; -+ pi->flag_now += 4; -+ pi->flag_next += 4; -+ pi->flag2_now += 4; -+ pi->flag2_next += 4; -+ pi->flag2_next2 += 4; -+ break; -+ case 1: -+ pi->vram_prev = vram_now; -+ pi->vram_now = vram_next; -+ pi->vram_next = vram_prev; -+ pi->flag_now = flag_next; -+ pi->flag_next = flag_now; -+ pi->flag2_now = flag2_next; -+ pi->flag2_next = flag2_next2; -+ pi->flag2_next2 = flag2_now; -+ break; -+ } -+} -+ -+/* -+ * These functions alloc/free work memory. -+ * pic2_alloc_buffer: -+ * alloc work memory buffer. -+ * pic2_free_buffer: -+ * free work memory buffer. -+ */ -+static int pic2_alloc_buffer(pi) -+struct pic2_info *pi; -+{ -+ int wid; -+ byte *p; -+ -+ if (pi->buf != NULL) -+ return (-1); -+ -+ wid = pi->block->x_wid; -+ -+ p = pi->buf = (byte *) pic2_new((wid + 8) * sizeof(pixel) * 3 // GRR POSSIBLE OVERFLOW / FIXME -+ + sizeof(pi->cache[0]) * 8 * 8 * 8 -+ + sizeof(pi->cache_pos[0]) * 8 * 8 * 8 -+ + sizeof(pi->mulu_tab[0]) * 16384 -+ + sizeof(pi->flag_now[0]) * ((wid+8) * 5), -+ "pic2_alloc_buffer"); -+ -+ pi->vram_prev = (pixel *) p; -+ p += (wid + 8) * sizeof(pixel); -+ pi->vram_now = (pixel *) p; -+ p += (wid + 8) * sizeof(pixel); -+ pi->vram_next = (pixel *) p; -+ p += (wid + 8) * sizeof(pixel); -+ pi->cache = (pixel (*)[PIC2_ARITH_CACHE]) p; -+ p += sizeof(pi->cache[0]) * 8 * 8 * 8; -+ pi->cache_pos = (unsigned short *) p; -+ p += sizeof(pi->cache_pos[0]) * 8 * 8 * 8; -+ pi->mulu_tab = (unsigned short *) p; -+ p += sizeof(pi->mulu_tab[0]) * 16384; -+ pi->flag_now = (short *) p; -+ p += sizeof(pi->flag_now[0]) * (wid + 8); -+ pi->flag_next = (short *) p; -+ p += sizeof(pi->flag_next[0]) * (wid + 8); -+ pi->flag2_now = (short *) p; -+ p += sizeof(pi->flag2_now[0]) * (wid + 8); -+ pi->flag2_next = (short *) p; -+ p += sizeof(pi->flag2_next[0]) * (wid + 8); -+ pi->flag2_next2 = (short *) p; -+ p += sizeof(pi->flag2_next2[0]) * (wid + 8); -+ return (0); -+} -+ -+static void pic2_free_buffer(pi) -+struct pic2_info *pi; -+{ -+ free(pi->buf); -+ pi->buf = NULL; -+} -+ -+/* -+ * These functions handle the file pointer. -+ * pic2_seek_file: -+ * moves the file pointer. -+ * pic2_tell_file: -+ * tells the location of the file pointer. -+ */ -+static long pic2_seek_file(pi, offset, whence) -+struct pic2_info *pi; -+long offset; -+int whence; -+{ -+ long n; -+ -+ n = fseek(pi->fp, offset, whence); -+ if (n < 0) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ -+ return (n); -+} -+ -+static long pic2_tell_file(pi) -+struct pic2_info *pi; -+{ -+ return (ftell(pi->fp)); -+} -+ -+/* -+ * These functions handle file. -+ * pic2_read_file: -+ * reads data from the file. -+ * pic2_read_long: -+ * reads long word data from the file and converts to internal expression. -+ * pic2_read_short: -+ * reads word data from the file and converts to internal expression. -+ * pic2_read_char: -+ * reads byte data from the file. -+ * pic2_write_file: -+ * writes data to the file. -+ * pic2_write_long: -+ * converts long word data to common expression and writes to the file. -+ * pic2_write_short: -+ * converts word data to common expression and writes to the file. -+ * pic2_write_char: -+ * writes byte data to the file. -+ */ -+static int pic2_read_file(pi, buf, size) -+struct pic2_info *pi; -+void *buf; -+size_t size; -+{ -+ if (fread(buf, (size_t) 1, size, pi->fp) < size) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ return (0); -+} -+ -+static long pic2_read_long(pi) -+struct pic2_info *pi; -+{ -+ byte buf[4]; -+ -+ if (fread(buf, (size_t) 4, (size_t) 1, pi->fp) < 1) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ return (pic2_cextolong(buf)); -+} -+ -+static short pic2_read_short(pi) -+struct pic2_info *pi; -+{ -+ byte buf[2]; -+ -+ if (fread(buf, (size_t) 2, (size_t) 1, pi->fp) < 1) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ return (pic2_cextoshort(buf)); -+} -+ -+static char pic2_read_char(pi) -+struct pic2_info *pi; -+{ -+ int c; -+ -+ if ((c = fgetc(pi->fp)) == EOF) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ return ((char) c); -+} -+ -+static int pic2_write_file(pi, buf, size) -+struct pic2_info *pi; -+void *buf; -+size_t size; -+{ -+ if (fwrite(buf, (size_t) 1, size, pi->fp) < size) -+ pic2_error(pi, PIC2_WRITE); -+ return (0); -+} -+ -+static int pic2_write_long(pi, n) -+struct pic2_info *pi; -+long n; -+{ -+ byte buf[4]; -+ -+ pic2_longtocex(buf, n); -+ if (fwrite(buf, (size_t) 4, (size_t) 1, pi->fp) < 1) -+ pic2_error(pi, PIC2_WRITE); -+ return (0); -+} -+ -+static int pic2_write_short(pi, n) -+struct pic2_info *pi; -+int n; -+{ -+ byte buf[2]; -+ -+ pic2_shorttocex(buf, n); -+ if (fwrite(buf, (size_t) 2, (size_t) 1, pi->fp) < 1) -+ pic2_error(pi, PIC2_WRITE); -+ return (0); -+} -+ -+static int pic2_write_char(pi, c) -+struct pic2_info *pi; -+int c; -+{ -+ if (fputc(c, pi->fp) == EOF) -+ pic2_error(pi, PIC2_WRITE); -+ return (0); -+} -+ -+/* -+ * These functions access the bit stream. -+ * pic2_read_bits: -+ * reads the specified bits from the file. -+ * pic2_write_bits: -+ * writes the specified bits to the file. -+ * pic2_flush_bits: -+ * flushes bit buffer to the file. -+ */ -+static unsigned long pic2_read_bits(pi, bits) -+struct pic2_info *pi; -+int bits; -+{ -+ unsigned long r = 0; -+ -+ while (bits > 0) { -+ while (pi->bs.rest > 0 && bits > 0) { -+ r = (r << 1) | (pi->bs.cur & 0x80 ? 1 : 0); -+ pi->bs.cur <<= 1; -+ pi->bs.rest--; -+ bits--; -+ } -+ if (bits > 0) { -+ int c; -+ if ((c = fgetc(pi->fp)) == EOF) -+ pic2_file_error(pi, PIC2_CORRUPT); -+ pi->bs.cur = (byte) c; -+ pi->bs.rest = 8; -+ } -+ } -+ return r; -+} -+ -+static void pic2_write_bits(pi, dat, bits) -+struct pic2_info *pi; -+unsigned long dat; -+int bits; -+{ -+ unsigned long dat_mask = 1 << (bits - 1); -+ -+ while (bits > 0) { -+ while (pi->bs.rest < 8 && bits > 0) { -+ pi->bs.cur <<= 1; -+ if (dat & dat_mask) -+ pi->bs.cur |= 1; -+ pi->bs.rest++; -+ bits--; -+ dat_mask >>= 1; -+ } -+ if (pi->bs.rest >= 8) { -+ if ((fputc((int) pi->bs.cur, pi->fp)) == EOF) -+ pic2_error(pi, PIC2_WRITE); -+ pi->bs.cur = 0; -+ pi->bs.rest = 0; -+ } -+ } -+} -+ -+static void pic2_flush_bits(pi) -+struct pic2_info *pi; -+{ -+ if (pi->bs.rest < 8) { -+ pi->bs.cur <<= 8 - pi->bs.rest; -+ if (fputc((int) pi->bs.cur, pi->fp) == EOF) -+ pic2_error(pi, PIC2_WRITE); -+ pi->bs.cur = 0; -+ pi->bs.rest = 0; -+ } -+} -+ -+/* -+ * These functions initialize or clean up structures. -+ * pic2_init_info: -+ * initializes a pic2_info structure. -+ * pic2_cleanup_pic2_info: -+ * cleans up a pic_info structure. -+ * pic2_cleanup_pinfo: -+ * cleans up a PICINFO structure. -+ */ -+static void pic2_init_info(pi) -+struct pic2_info *pi; -+{ -+ xvbzero((char *) pi, sizeof(struct pic2_info)); -+ pi->header = pic2_new(sizeof(struct pic2_header), "pic2_init_info#1"); -+ pi->block = pic2_new(sizeof(struct pic2_block), "pic2_init_info#2"); -+} -+ -+static void pic2_cleanup_pic2_info(pi, writing) -+struct pic2_info *pi; -+int writing; -+{ -+ if (!writing && pi->fp) -+ fclose(pi->fp); -+ if (pi->header) -+ free(pi->header); -+ if (pi->block) -+ free(pi->block); -+ pi->fp = NULL; -+ pi->header = NULL; -+ pi->block = NULL; -+ pi->comment = NULL; -+} -+ -+static void pic2_cleanup_pinfo(pinfo) -+PICINFO *pinfo; -+{ -+ if (pinfo->pic){ -+ free(pinfo->pic); -+ pinfo->pic = NULL; -+ } -+ if (pinfo->comment){ -+ free(pinfo->comment); -+ pinfo->comment = NULL; -+ } -+} -+ -+/* -+ * Error Handlers. -+ * pic2_memory_error: -+ * shows an error message and terminates. -+ * pic2_error: -+ * shows a non-file error message and jumps to the entry for errors. -+ * pic2_file_error: -+ * shows a file error message and jumps to the entry for errors. -+ */ -+static void pic2_memory_error(scm, fn) -+char *scm, *fn; -+{ -+ char buf[128]; -+ sprintf(buf, "%s: can't allocate memory. (%s)", scm, fn); -+ FatalError(buf); -+} -+ -+static void pic2_error(pi, mn) -+struct pic2_info *pi; -+int mn; -+{ -+ SetISTR(ISTR_WARNING, "%s", pic2_msgs[mn]); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pic2_file_error(pi, mn) -+ struct pic2_info *pi; -+ int mn; -+{ -+ if (feof(pi->fp)) -+ SetISTR(ISTR_WARNING, "%s (end of file)", pic2_msgs[mn]); -+ else -+ SetISTR(ISTR_WARNING, "%s (%s)", pic2_msgs[mn], ERRSTR(errno)); -+ longjmp(pi->jmp, 1); -+} -+ -+static void pic2_show_pic2_info(pi) -+ struct pic2_info *pi; -+{ -+ fprintf(stderr, "file size: %ld.\n", pi->fsize); -+ fprintf(stderr, "full image size: %dx%d\n", pi->x_max, pi->y_max); -+ fprintf(stderr, "number of palettes: %d\n", pi->n_pal); -+ fprintf(stderr, "depth of palettes: %d\n", pi->pal_bits); -+ fprintf(stderr, "current block position: %ld\n", pi->block_pos); -+ fprintf(stderr, "next block position: %ld\n\n", pi->next_pos); -+ -+ fprintf(stderr, "header flag: %x\n", pi->header->flag); -+ fprintf(stderr, "header size: %ld\n", pi->header->size); -+ fprintf(stderr, "x_aspect: %d, y_aspect: %d\n", -+ pi->header->x_aspect, pi->header->y_aspect); -+ fprintf(stderr, "number of color bits: %d\n\n", pi->header->depth); -+ -+ fprintf(stderr, "image block id: %s\n", pi->block->id); -+ fprintf(stderr, "image block size: %ld\n", pi->block->size); -+ fprintf(stderr, "block flag: %x\n", pi->block->flag); -+ -+ fprintf(stderr, "block image size: %dx%d\n", -+ pi->block->x_wid, pi->block->y_wid); -+ fprintf(stderr, "x_offset: %d\n", pi->block->x_offset); -+ fprintf(stderr, "y_offset: %d\n", pi->block->y_offset); -+ fprintf(stderr, "opaque color: %lx\n\n", pi->block->opaque); -+} -+ -+/* -+ * This function is similar to strncpy. -+ * But this pads with whitespace after the null character. -+ */ -+static char *pic2_strncpy(dest, src, n) -+char *dest, *src; -+size_t n; -+{ -+ char *r; -+ -+ r = dest; -+ while (n--) -+ if ((src != NULL) && (*src != '\r') && (*src != '\n') && *src) -+ *dest++ = *src++; -+ else -+ *dest++ = ' '; -+ return (r); -+} -+ -+/* -+ * These functions create a memory block. -+ */ -+static void *pic2_malloc(size, fn) -+size_t size; -+char *fn; -+{ -+ void *p; -+ -+ p = (void *) malloc(size); -+ if (p == NULL) -+ pic2_memory_error("malloc", fn); -+ return (p); -+} -+ -+static void *pic2_new(size, fn) -+size_t size; -+char *fn; -+{ -+ void *p; -+ -+ p = (void *) pic2_malloc(size, fn); -+ xvbzero((char *) p, size); -+ return (p); -+} -+ -+ -+ -+ -+/**** Stuff for PIC2Dialog box ****/ -+ -+#define TWIDE 320 -+#define THIGH 178 -+#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 writePIC2 PARM((void)); -+ -+/* local variables */ -+static FILE *fp; -+static char *filename; -+static int colorType; -+static int append; -+static int x_offset; -+static int y_offset; -+static BUTT tbut[T_NBUTTS]; -+static RBUTT *typeRB; -+static RBUTT *depthRB; -+ -+ -+ -+/***************************************************/ -+void CreatePIC2W() -+{ -+ int y; -+ -+ pic2W = CreateWindow("xv pic2", "XVpic2", NULL, -+ TWIDE, THIGH, infofg, infobg, 0); -+ if (!pic2W) -+ FatalError("can't create pic2 window!"); -+ -+ XSelectInput(theDisp, pic2W, -+ ExposureMask | ButtonPressMask | KeyPressMask); -+ -+ BTCreate(&tbut[T_BOK], pic2W, TWIDE-140-1, THIGH-10-BUTTH-1, 60, BUTTH, -+ "Ok", infofg, infobg, hicol, locol); -+ -+ BTCreate(&tbut[T_BCANC], pic2W, TWIDE-70-1, THIGH-10-BUTTH-1, 60, BUTTH, -+ "Cancel", infofg, infobg, hicol, locol); -+ -+ y = 55; -+ typeRB = RBCreate(NULL, pic2W, 36, y, "P2SS", -+ infofg, infobg,hicol,locol); -+ RBCreate(typeRB, pic2W, 36, y+18, "P2SF", -+ infofg, infobg,hicol,locol); -+ RBCreate(typeRB, pic2W, 36, y+36, "P2BM", -+ infofg, infobg, hicol, locol); -+ RBCreate(typeRB, pic2W, 36, y+54, "P2BI", -+ infofg, infobg, hicol, locol); -+ -+ depthRB = RBCreate(NULL, pic2W, TWIDE/2-16, y, " 3bit", -+ infofg, infobg,hicol,locol); -+ RBCreate(depthRB, pic2W, TWIDE/2-16, y+18, " 6bit", -+ infofg, infobg,hicol,locol); -+ RBCreate(depthRB, pic2W, TWIDE/2-16, y+36, " 9bit", -+ infofg, infobg, hicol, locol); -+ RBCreate(depthRB, pic2W, TWIDE/2-16, y+54, "12bit", -+ infofg, infobg, hicol, locol); -+ RBCreate(depthRB, pic2W, TWIDE/4*3-16, y, "15bit", -+ infofg, infobg, hicol, locol); -+ RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+18, "18bit", -+ infofg, infobg, hicol, locol); -+ RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+36, "21bit", -+ infofg, infobg, hicol, locol); -+ RBCreate(depthRB, pic2W, TWIDE/4*3-16, y+54, "24bit", -+ infofg, infobg, hicol, locol); -+ -+ XMapSubwindows(theDisp, pic2W); -+} -+ -+ -+/***************************************************/ -+void PIC2Dialog(vis) -+int vis; -+{ -+ if (vis) { -+ CenterMapWindow(pic2W, tbut[T_BOK].x + tbut[T_BOK].w/2, -+ tbut[T_BOK].y + tbut[T_BOK].h/2, TWIDE, THIGH); -+ } -+ else XUnmapWindow(theDisp, pic2W); -+ pic2Up = vis; -+} -+ -+ -+/***************************************************/ -+int PIC2CheckEvent(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 (!pic2Up) -+ 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 == pic2W) 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 == pic2W) 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'; -+ -+ if (e->window == pic2W) { -+ 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); -+} -+ -+ -+/***************************************************/ -+int PIC2SaveParams(fname, col) -+char *fname; -+int col; -+{ -+ filename = fname; -+ colorType = col; -+ -+ /* see if we can open the output file before proceeding */ -+ fp = pic2_OpenOutFile(filename, &append); -+ if (!fp) -+ return (-1); -+ -+ RBSetActive(typeRB,0,1); -+ RBSetActive(typeRB,1,1); -+ RBSetActive(typeRB,2,1); -+ RBSetActive(typeRB,3,1); -+ RBSelect(typeRB,0); -+ -+ -+ if (append) { -+ struct pic2_info pic2; -+ -+ pic2_init_info(&pic2); -+ pic2.fp = fp; -+ pic2_read_header(&pic2); -+ -+ RBSetActive(depthRB,0,0); -+ RBSetActive(depthRB,1,0); -+ RBSetActive(depthRB,2,0); -+ RBSetActive(depthRB,3,0); -+ RBSetActive(depthRB,4,0); -+ RBSetActive(depthRB,5,0); -+ RBSetActive(depthRB,6,0); -+ RBSetActive(depthRB,7,0); -+ -+ switch (pic2.header->depth) { -+ case 3: -+ RBSetActive(depthRB,0,1); -+ RBSelect(depthRB,0); -+ RBSetActive(typeRB,3,0); -+ break; -+ case 6: -+ RBSetActive(depthRB,1,1); -+ RBSelect(depthRB,1); -+ RBSetActive(typeRB,3,0); -+ break; -+ case 9: -+ RBSetActive(depthRB,2,1); -+ RBSelect(depthRB,2); -+ break; -+ case 12: -+ RBSetActive(depthRB,3,1); -+ RBSelect(depthRB,3); -+ break; -+ case 15: -+ RBSetActive(depthRB,4,1); -+ RBSelect(depthRB,4); -+ break; -+ case 18: -+ RBSetActive(depthRB,5,1); -+ RBSelect(depthRB,5); -+ RBSetActive(typeRB,3,0); -+ break; -+ case 21: -+ RBSetActive(depthRB,6,1); -+ RBSelect(depthRB,6); -+ RBSetActive(typeRB,3,0); -+ break; -+ case 24: -+ RBSetActive(depthRB,7,1); -+ RBSelect(depthRB,7); -+ RBSetActive(typeRB,3,0); -+ break; -+ default: { -+ char str[512]; -+ sprintf(str, "unsupported PIC2 file '%s'.", filename); -+ ErrPopUp(str, "\nBummer"); -+ CloseOutFile(fp, filename, 0); -+ fp = OpenOutFile(fname); -+ if (!fp) -+ return (-1); -+ break; -+ } -+ } -+ pic2_seek_file(&pic2, 0, SEEK_SET); -+ pic2_cleanup_pic2_info(&pic2, 1); -+ } else { -+ RBSetActive(depthRB,0,1); -+ RBSetActive(depthRB,1,1); -+ RBSetActive(depthRB,2,1); -+ RBSetActive(depthRB,3,1); -+ RBSetActive(depthRB,4,1); -+ RBSetActive(depthRB,5,1); -+ RBSetActive(depthRB,6,1); -+ RBSetActive(depthRB,7,1); -+ RBSelect(depthRB,7); -+ RBSetActive(typeRB,3,0); -+ } -+ return (0); -+} -+ -+ -+/***************************************************/ -+static void drawTD(x,y,w,h) -+int x,y,w,h; -+{ -+ char *title = "Save PIC2 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(pic2W, typeRB->x-16, typeRB->y-3-DESCENT, "FormatType"); -+ ULineString(pic2W, depthRB->x-16, depthRB->y-3-DESCENT, "ColorDepth"); -+ RBRedraw(typeRB, -1); -+ RBRedraw(depthRB, -1); -+ -+ DrawString(pic2W, 20, 29, 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(typeRB, x,y)) >= 0) { -+ (void) RBTrack(typeRB, i); -+ return; -+ } else if ((i = RBClick(depthRB, x,y)) >= 0) { -+ (void) RBTrack(depthRB, i); -+ if ((2 <= i) && (i <= 4)) -+ RBSetActive(typeRB,3,1); -+ else { -+ RBSetActive(typeRB,3,0); -+ if (RBWhich(typeRB) == 3) -+ RBSelect(typeRB,0); -+ 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; -+{ -+ switch (cmd) { -+ case T_BOK: { -+ char *fullname; -+ char buf[64], *x_offsetp, *y_offsetp; -+ static char *labels[] = { "\nOk", "\033Cancel" }; -+ XEvent event; -+ int i; -+ -+ strcpy(buf, "0,0"); -+ i = GetStrPopUp("Enter offset (x,y):", labels, 2, buf, 64, -+ "01234567890,", 1); -+ -+ if (i) -+ return; -+ if (strlen(buf)==0) -+ return; -+ -+ x_offsetp = buf; -+ y_offsetp = index(buf, ','); -+ if (!y_offsetp) -+ return; -+ *(y_offsetp++) = '\0'; -+ if ((*x_offsetp == '\0') || (*y_offsetp == '\0')) -+ return; -+ x_offset = atoi(x_offsetp); -+ y_offset = atoi(y_offsetp); -+ -+ XNextEvent(theDisp, &event); -+ HandleEvent(&event, &i); -+ -+ writePIC2(); -+ PIC2Dialog(0); -+ -+ fullname = GetDirFullName(); -+ if (!ISPIPE(fullname[0])) { -+ XVCreatedFile(fullname); -+ StickInCtrlList(0); -+ } -+ } -+ break; -+ case T_BCANC: -+ pic2_KillNullFile(fp); -+ PIC2Dialog(0); -+ break; -+ default: -+ break; -+ } -+} -+ -+ -+/*******************************************/ -+static void writePIC2() -+{ -+ int w, h, nc, rv, type, depth, ptype, pfree; -+ byte *inpix, *rmap, *gmap, *bmap; -+ -+ -+ WaitCursor(); -+ inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap); -+ -+ if (colorType == F_REDUCED) -+ colorType = F_FULLCOLOR; -+ -+ switch (RBWhich(typeRB)) { -+ case 0: type = P2SS; break; -+ case 1: type = P2SF; break; -+ case 2: type = P2BM; break; -+ case 3: type = P2BI; break; -+ default: type = P2SS; break; -+ } -+ switch (RBWhich(depthRB)) { -+ case 0: depth = 3; break; -+ case 1: depth = 6; break; -+ case 2: depth = 9; break; -+ case 3: depth = 12; break; -+ case 4: depth = 15; break; -+ case 5: depth = 18; break; -+ case 6: depth = 21; break; -+ case 7: depth = 24; break; -+ default: depth = 24; break; -+ } -+ rv = WritePIC2(fp, inpix, ptype, w, h, -+ rmap, gmap, bmap, nc, colorType, filename, -+ type, depth, x_offset, y_offset, append, picComments); -+ -+ if (CloseOutFile(fp, filename, rv) == 0) -+ DirBox(0); -+ -+ if (pfree) -+ free(inpix); -+} -+#endif /* HAVE_PIC2 */ -diff -ruN xv-3.10a-bugfixes/xvpng.c xv-3.10a-enhancements/xvpng.c ---- xv-3.10a-bugfixes/xvpng.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvpng.c 2005-04-17 15:00:08.000000000 -0700 -@@ -0,0 +1,1081 @@ -+/* -+ * xvpng.c - load and write routines for 'PNG' format pictures -+ * -+ * callable functions -+ * -+ * CreatePNGW() -+ * PNGDialog(vis) -+ * PNGCheckEvent(xev) -+ * PNGSaveParams(fname, col) -+ * LoadPNG(fname, pinfo) -+ * VersionInfoPNG() -+ */ -+ -+/*#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. -+ * Modified by Greg Roelofs, TenThumbs and others to fix bugs and add -+ * features. -+ * 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 */ -+#define COMPRESSION 6 /* default zlib compression level, not max -+ (Z_BEST_COMPRESSION) */ -+ -+#define HAVE_tRNS (info_ptr->valid & PNG_INFO_tRNS) -+ -+#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, pass; -+ byte *p, *png_line; -+ char software[256]; -+ char *savecmnt; -+ -+ if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, -+ png_xv_error, png_xv_warning)) == NULL) { -+ sprintf(software, "png_create_write_struct() failure in WritePNG (ver. %s)", -+ PNG_LIBPNG_VER_STRING); -+ FatalError(software); -+ } -+ -+ if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) -+ { -+ png_destroy_write_struct(&png_ptr, &info_ptr); -+ sprintf(software, "png_create_info_struct() failure in WritePNG"); -+ FatalError(software); -+ } -+ -+ 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; -+ if (w <= 0 || h <= 0) { -+ SetISTR(ISTR_WARNING, "%s: image dimensions out of range (%dx%d)", -+ fbasename, w, h); -+ png_destroy_write_struct(&png_ptr, &info_ptr); -+ return -1; -+ } -+ -+ info_ptr->interlace_type = interCB.val ? 1 : 0; -+ -+ linesize = 0; /* quiet a compiler warning */ -+ -+ if (colorType == F_FULLCOLOR || colorType == F_REDUCED) { -+ if(ptype == PIC24) { -+ linesize = 3*w; -+ if (linesize/3 < w) { -+ SetISTR(ISTR_WARNING, "%s: image dimensions too large (%dx%d)", -+ fbasename, w, h); -+ png_destroy_write_struct(&png_ptr, &info_ptr); -+ return -1; -+ } -+ 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 = 3*w; -+ if (linesize/3 < w) { -+ SetISTR(ISTR_WARNING, "%s: image dimensions too large (%dx%d)", -+ fbasename, w, h); -+ png_destroy_write_struct(&png_ptr, &info_ptr); -+ return -1; -+ } -+ info_ptr->bit_depth = 8; -+ } -+ else { -+ int low_precision; -+ -+ 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 precision grayscale */ -+ -+ low_precision=1; -+ -+ for(i = 0; i < numcols; i++) { -+ if((remap[i] & 0x0f) * 0x11 != remap[i]) { -+ low_precision = 0; -+ break; -+ } -+ } -+ -+ if(low_precision) { -+ for(i = 0; i < numcols; i++) { -+ remap[i] &= 0xf; -+ } -+ info_ptr->bit_depth = 4; -+ -+ /* try to adjust to 2-bit precision grayscale */ -+ -+ for(i = 0; i < numcols; i++) { -+ if((remap[i] & 0x03) * 0x05 != remap[i]) { -+ low_precision = 0; -+ break; -+ } -+ } -+ } -+ -+ if(low_precision) { -+ for(i = 0; i < numcols; i++) { -+ remap[i] &= 3; -+ } -+ info_ptr->bit_depth = 2; -+ -+ /* try to adjust to 1-bit precision grayscale */ -+ -+ for(i = 0; i < numcols; i++) { -+ if((remap[i] & 0x01) * 0x03 != remap[i]) { -+ low_precision = 0; -+ break; -+ } -+ } -+ } -+ -+ if(low_precision) { -+ 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); -+ -+ savecmnt = NULL; /* quiet a compiler warning */ -+ -+ 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, bufsize; -+ int filesize; -+ int pass; -+ int gray_to_rgb; -+ 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; -+ if (pinfo->w <= 0 || pinfo->h <= 0) { -+ SetISTR(ISTR_WARNING, "%s: image dimensions out of range (%dx%d)", -+ fbasename, pinfo->w, pinfo->h); -+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); -+ return read_anything; -+ } -+ -+ 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, "%lux%lu 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); -+ -+ gray_to_rgb = 0; /* quiet a compiler warning */ -+ -+ if (have_imagebg) { -+ if (info_ptr->bit_depth == 16) { -+ my_background.red = imagebgR; -+ my_background.green = imagebgG; -+ my_background.blue = imagebgB; -+ my_background.gray = imagebgG; /* only used if all three equal... */ -+ } else { -+ my_background.red = (imagebgR >> 8); -+ my_background.green = (imagebgG >> 8); -+ my_background.blue = (imagebgB >> 8); -+ my_background.gray = my_background.green; -+ } -+ png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, -+ 0, Display_Gamma); -+ if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA || -+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY && HAVE_tRNS)) && -+ (imagebgR != imagebgG || imagebgR != imagebgB)) /* i.e., colored bg */ -+ { -+ png_set_gray_to_rgb(png_ptr); -+ png_set_expand(png_ptr); -+ gray_to_rgb = 1; -+ } -+ } else { -+ 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 || gray_to_rgb) -+ { -+ linesize = 3 * pinfo->w; -+ if (linesize/3 < pinfo->w) { /* know pinfo->w > 0 (see above) */ -+ SetISTR(ISTR_WARNING, "%s: image dimensions too large (%dx%d)", -+ fbasename, pinfo->w, pinfo->h); -+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); -+ return read_anything; -+ } -+ 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; -+ } -+ } -+ } -+ -+ bufsize = linesize * pinfo->h; -+ if (bufsize/linesize < pinfo->h) { /* know linesize, pinfo->h > 0 (above) */ -+ SetISTR(ISTR_WARNING, "%s: image dimensions too large (%dx%d)", -+ fbasename, pinfo->w, pinfo->h); -+ png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); -+ return read_anything; -+ } -+ pinfo->pic = calloc((size_t)bufsize, (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); -+} -+ -+ -+/*******************************************/ -+void -+VersionInfoPNG() /* GRR 19980605 */ -+{ -+ fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", -+ PNG_LIBPNG_VER_STRING, png_libpng_ver); -+ fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", -+ ZLIB_VERSION, zlib_version); -+} -+ -+#endif /* HAVE_PNG */ -diff -ruN xv-3.10a-bugfixes/xvpopup.c xv-3.10a-enhancements/xvpopup.c ---- xv-3.10a-bugfixes/xvpopup.c 2004-05-16 18:04:13.000000000 -0700 -+++ xv-3.10a-enhancements/xvpopup.c 2005-04-25 08:21:34.000000000 -0700 -@@ -23,7 +23,7 @@ - #define OMIT_ICON_BITS - #include "bits/icon" /* icon_bits[] not used, but icon_width/height are */ - --#define PUWIDE 400 -+#define PUWIDE 480 - #define PUHIGH 170 - - #define PAD_PUWIDE 480 -@@ -201,14 +201,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, -@@ -259,9 +259,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)); -@@ -287,15 +287,19 @@ - /* center first button in window around mouse position, with constraint that - window be fully on the screen */ - -- CenterMapWindow(popW, 40 + bts[0].x, BUTTH/2 + bts[0].y, puwide, puhigh); - popUp = poptyp; -+ if (startGrab == 2) -+ startGrab = 4; -+ else { -+ CenterMapWindow(popW, 40 + bts[0].x, BUTTH/2 + bts[0].y, puwide, puhigh); - -- /* MUST wait for VisibilityNotify event to come in, else we run the risk -- of UnMapping the window *before* the Map request completed. This -- appears to be bad, (It leaves an empty window frame up.) though it -- generally only happens on slow servers. Better safe than screwed... */ -+ /* MUST wait for VisibilityNotify event to come in, else we run the risk -+ of UnMapping the window *before* the Map request completed. This -+ appears to be bad, (It leaves an empty window frame up.) though it -+ generally only happens on slow servers. Better safe than screwed... */ - -- XWindowEvent(theDisp, popW, VisibilityChangeMask, &event); -+ XWindowEvent(theDisp, popW, VisibilityChangeMask, &event); -+ } - - /* block until this window gets closed */ - while (popUp) { -@@ -466,9 +470,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; } - -@@ -487,9 +491,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); -@@ -499,9 +503,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; -@@ -956,14 +960,14 @@ - int x,y; - { - int i; -- BUTT *bp; -+ BUTT *bp = NULL; - - for (i=0; i<nbts; i++) { - bp = &bts[i]; - if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break; - } - -- if (i<nbts && BTTrack(bp)) { -+ if (i<nbts && bp && BTTrack(bp)) { - popUp = 0; selected = i; return; - } - -@@ -972,8 +976,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); - } - } - -@@ -1105,7 +1109,7 @@ - } - - -- else if (c=='\010' || c=='\177') { /* BS or DEL */ -+ else if (c=='\010') { /* BS */ - if (gsCurPos==0) return 1; /* at beginning of str */ - xvbcopy(&gsBuf[gsCurPos], &gsBuf[gsCurPos-1], (size_t) len-gsCurPos+1); - gsCurPos--; -@@ -1128,7 +1132,7 @@ - gsCurPos = len; - } - -- else if (c=='\004') { /* ^D: delete character at gsCurPos */ -+ else if (c=='\004' || c=='\177') { /* ^D or DEL: delete character at gsCurPos */ - if (gsCurPos==len) return 1; - xvbcopy(&gsBuf[gsCurPos+1], &gsBuf[gsCurPos], (size_t) len-gsCurPos); - } -diff -ruN xv-3.10a-bugfixes/xvps.c xv-3.10a-enhancements/xvps.c ---- xv-3.10a-bugfixes/xvps.c 2005-03-30 08:18:17.000000000 -0800 -+++ xv-3.10a-enhancements/xvps.c 2005-04-17 14:45:28.000000000 -0700 -@@ -142,9 +142,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; -@@ -239,10 +239,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); - } - } - -@@ -839,7 +839,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); -@@ -1561,9 +1561,9 @@ - the first one is loaded (but not deleted) */ - - #ifdef GS_PATH -- char tmp[512], gscmd[512], cmdstr[512], tmpname[64]; -+ #define CMDSIZE 1024 -+ char tmp[512], gscmd[512], cmdstr[CMDSIZE], tmpname[64]; - int gsresult, nump, i, filetype, doalert, epsf; -- char *rld; - #endif - - pinfo->pic = (byte *) NULL; -@@ -1596,7 +1596,7 @@ - /* build 'gscmd' string */ - - #ifndef VMS /* VMS needs quotes around mixed case command lines */ -- sprintf(gscmd, "%s -sDEVICE=%s -r%d -q -dNOPAUSE -sOutputFile=%s%%d ", -+ sprintf(gscmd, "%s -sDEVICE=%s -r%d -q -dSAFER -dNOPAUSE -sOutputFile=%s%%d ", - GS_PATH, gsDev, gsRes, tmpname); - #else - sprintf(gscmd, -@@ -1734,32 +1734,48 @@ - - /******************************************************************/ - #ifdef GS_PATH --void buildCmdStr(str, gscmd, fname, quick, epsf) -- char *str, *gscmd, *fname; -+void buildCmdStr(str, gscmd, xname, quick, epsf) -+ char *str, *gscmd, *xname; - int quick, epsf; - { - /* note 'epsf' set only on files that don't have a showpage cmd */ -+ char *x, *y, *fname; -+ -+ x = (char *) malloc((5 * strlen(xname))+3); -+ if (!x) -+ FatalError("malloc failure in xvps.c buildCmdStr"); -+ fname = x; -+ *x++ = 0x27; -+ -+ for (y = xname; *y; ++y) { -+ if (0x27 == *y) { -+ strcpy(x, "'\"'\"'"); -+ x += strlen(x); -+ } else *x++ = *y; -+ } -+ strcpy (x, "'"); - - #ifndef VMS - -- if (epsf) sprintf(str, "echo '\n showpage ' | cat '%s' - | %s -", -+ if (epsf) snprintf(str, CMDSIZE, "echo '\n showpage ' | cat %s - | %s -", - fname, gscmd); - -- else if (quick) sprintf(str, "echo '%s' | cat - '%s' | %s -", -+ else if (quick) snprintf(str, CMDSIZE, "echo %s | cat - %s | %s -", - "/showpage { showpage quit } bind def", - fname, gscmd); - -- else sprintf(str, "%s -- %s", gscmd, fname); -+ else snprintf(str, CMDSIZE, "%s -- %s", gscmd, fname); - - #else /* VMS */ - /* VMS doesn't have pipes or an 'echo' command and GS doesn't like -- Unix-style file names as input files in the VMS version */ -+ Unix-style filenames as input files in the VMS version */ - strcat(tmp, " -- "); - rld = strrchr(fname, '/'); /* Pointer to last '/' */ - if (rld) rld++; /* Pointer to filename */ - else rld = fname; /* No path - use original string */ - strcat(tmp, rld); - #endif /* VMS */ -+ free(fname); - } - #endif /* GS_PATH */ - -diff -ruN xv-3.10a-bugfixes/xvrle.c xv-3.10a-enhancements/xvrle.c ---- xv-3.10a-bugfixes/xvrle.c 2005-03-29 23:29:14.000000000 -0800 -+++ xv-3.10a-enhancements/xvrle.c 2004-05-16 18:07:46.000000000 -0700 -@@ -43,7 +43,7 @@ - byte bgcol[256]; - byte maps[3][256]; - int xpos, ypos, w, h, flags, ncolors, pixelbits, ncmap, cmaplen; -- int cmtlen, npixels, bufsize=0; -+ int cmtlen; - byte *img; - long filesize; - char *bname, *errstr; -@@ -176,44 +176,32 @@ - - errstr = NULL; - if (ncolors == 0 || ncolors == 2) -- errstr = "Unsupported number of channels in RLE file"; -+ errstr = "Unsupt. # of channels in RLE file.\n"; - - if (pixelbits != 8) -- errstr = "Only 8-bit pixels supported in RLE files"; -+ errstr = "Only 8-bit pixels supported in RLE files.\n"; - - if (ncmap==0 || ncmap==1 || ncmap == 3 || ncmap == ncolors) { /* ok */ } -- else errstr = "Invalid number of colormap channels in RLE file"; -+ else errstr = "Invalid # of colormap channels in RLE file.\n"; - -- npixels = w * h; -- if (w <= 0 || h <= 0 || npixels/w != h) -- errstr = "RLE image dimensions out of range"; -+ if (w<1 || h<1) -+ errstr = "Bogus size in RLE header.\n"; - - - if (errstr) { - fclose(fp); -- if (pinfo->comment) -- free(pinfo->comment); -- pinfo->comment = (char *) NULL; -+ if (pinfo->comment) free(pinfo->comment); pinfo->comment = (char *) NULL; - return rleError(bname, errstr); - } - - - /* allocate image memory */ -- if (ncolors == 1) -- img = (byte *) calloc((size_t) npixels, (size_t) 1); -- else { -- bufsize = 3*npixels; -- if (bufsize/3 != npixels) -- return rleError(bname, "RLE image dimensions out of range"); -- img = (byte *) calloc((size_t) bufsize, (size_t) 1); -- } -- -+ if (ncolors == 1) img = (byte *) calloc((size_t) w * h, (size_t) 1); -+ else img = (byte *) calloc((size_t) w * h * 3, (size_t) 1); - if (!img) { - fclose(fp); -- if (pinfo->comment) -- free(pinfo->comment); -- pinfo->comment = (char *) NULL; -- return rleError(bname, "Unable to allocate RLE image data"); -+ if (pinfo->comment) free(pinfo->comment); pinfo->comment = (char *) NULL; -+ return rleError(bname, "unable to allocate image data.\n"); - } - - -@@ -221,10 +209,10 @@ - if ((flags & H_CLEARFIRST) && !(flags & H_NO_BACKGROUND)) { - byte *ip; - if (ncolors == 1) { -- for (i=0, ip=img; i<npixels; i++, ip++) *ip = bgcol[0]; -+ for (i=0, ip=img; i<w*h; i++, ip++) *ip = bgcol[0]; - } - else { -- for (i=0, ip=img; i<npixels; i++) -+ for (i=0, ip=img; i<w*h; i++) - for (j=0; j<3; j++, ip++) *ip = bgcol[j]; - } - } -@@ -242,7 +230,7 @@ - if (ncmap) { - byte *ip; - int imagelen, cmask; -- imagelen = (ncolors==1) ? npixels : bufsize; -+ imagelen = (ncolors==1) ? w*h : w*h*3; - cmask = (cmaplen-1); - - if (ncmap == 1) { /* single gamma curve */ -@@ -250,7 +238,7 @@ - } - - else if (ncmap >= 3 && ncolors >=3) { /* one curve per band */ -- for (i=0, ip=img; i<npixels; i++) { -+ for (i=0, ip=img; i<w*h; i++) { - *ip = maps[0][*ip & cmask]; ip++; - *ip = maps[1][*ip & cmask]; ip++; - *ip = maps[2][*ip & cmask]; ip++; -diff -ruN xv-3.10a-bugfixes/xvroot.c xv-3.10a-enhancements/xvroot.c ---- xv-3.10a-bugfixes/xvroot.c 2004-05-16 18:04:21.000000000 -0700 -+++ xv-3.10a-enhancements/xvroot.c 2004-05-16 18:07:52.000000000 -0700 -@@ -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 -ruN xv-3.10a-bugfixes/xvsmooth.c xv-3.10a-enhancements/xvsmooth.c ---- xv-3.10a-bugfixes/xvsmooth.c 2004-05-16 18:04:28.000000000 -0700 -+++ xv-3.10a-enhancements/xvsmooth.c 2004-05-16 18:07:59.000000000 -0700 -@@ -105,7 +105,7 @@ - /* we can save a lot of time by precomputing cxtab[] and pxtab[], both - dwide arrays of ints that contain values for the equations: - cx = (ex * swide) / dwide; -- px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */ -+ px = ((ex * swide * 128) / dwide) - (cx * 128) - 64; */ - - cxtab = (int *) malloc(dwide * sizeof(int)); - if (!cxtab) { free(pic24); return NULL; } -@@ -115,8 +115,8 @@ - - for (ex=0; ex<dwide; ex++) { - cxtab[ex] = (ex * swide) / dwide; -- pxtab[ex] = (((ex * swide)* 100) / dwide) -- - (cxtab[ex] * 100) - 50; -+ pxtab[ex] = (((ex * swide)* 128) / dwide) -+ - (cxtab[ex] * 128) - 64; - } - - for (ey=0; ey<dhigh; ey++) { -@@ -125,7 +125,7 @@ - ProgressMeter(0, (dhigh)-1, ey, "Smooth"); - - cy = (ey * shigh) / dhigh; -- py = (((ey * shigh) * 100) / dhigh) - (cy * 100) - 50; -+ py = (((ey * shigh) * 128) / dhigh) - (cy * 128) - 64; - if (py<0) { y1 = cy-1; if (y1<0) y1=0; } - else { y1 = cy+1; if (y1>shigh-1) y1=shigh-1; } - -@@ -172,30 +172,30 @@ - else { - /* compute weighting factors */ - apx = abs(px); apy = abs(py); -- pA = (apx * apy) / 100; -- pB = (apy * (100 - apx)) / 100; -- pC = (apx * (100 - apy)) / 100; -- pD = 100 - (pA + pB + pC); -+ pA = (apx * apy) >> 7; /* div 128 */ -+ pB = (apy * (128 - apx)) >> 7; /* div 128 */ -+ pC = (apx * (128 - apy)) >> 7; /* div 128 */ -+ pD = 128 - (pA + pB + pC); - - if (is24) { -- *pp++ = ((int) (pA * rA))/100 + ((int) (pB * rB))/100 + -- ((int) (pC * rC))/100 + ((int) (pD * rD))/100; -+ *pp++ = (((int) (pA * rA))>>7) + (((int) (pB * rB))>>7) + -+ (((int) (pC * rC))>>7) + (((int) (pD * rD))>>7); - -- *pp++ = ((int) (pA * gA))/100 + ((int) (pB * gB))/100 + -- ((int) (pC * gC))/100 + ((int) (pD * gD))/100; -+ *pp++ = (((int) (pA * gA))>>7) + (((int) (pB * gB))>>7) + -+ (((int) (pC * gC))>>7) + (((int) (pD * gD))>>7); - -- *pp++ = ((int) (pA * bA))/100 + ((int) (pB * bB))/100 + -- ((int) (pC * bC))/100 + ((int) (pD * bD))/100; -+ *pp++ = (((int) (pA * bA))>>7) + (((int) (pB * bB))>>7) + -+ (((int) (pC * bC))>>7) + (((int) (pD * bD))>>7); - } - else { /* 8-bit pic */ -- *pp++ = ((int) (pA * rmap[cA]))/100 + ((int)(pB * rmap[cB]))/100 + -- ((int) (pC * rmap[cC]))/100 + ((int)(pD * rmap[cD]))/100; -+ *pp++ = (((int)(pA * rmap[cA]))>>7) + (((int)(pB * rmap[cB]))>>7) + -+ (((int)(pC * rmap[cC]))>>7) + (((int)(pD * rmap[cD]))>>7); - -- *pp++ = ((int) (pA * gmap[cA]))/100 + ((int)(pB * gmap[cB]))/100 + -- ((int) (pC * gmap[cC]))/100 + ((int)(pD * gmap[cD]))/100; -+ *pp++ = (((int)(pA * gmap[cA]))>>7) + (((int)(pB * gmap[cB]))>>7) + -+ (((int)(pC * gmap[cC]))>>7) + (((int)(pD * gmap[cD]))>>7); - -- *pp++ = ((int)(pA * bmap[cA]))/100 + ((int)(pB * bmap[cB]))/100 + -- ((int)(pC * bmap[cC]))/100 + ((int)(pD * bmap[cD]))/100; -+ *pp++ = (((int)(pA * bmap[cA]))>>7) + (((int)(pB * bmap[cB]))>>7) + -+ (((int)(pC * bmap[cC]))>>7) + (((int)(pD * bmap[cD]))>>7); - } - } - } -diff -ruN xv-3.10a-bugfixes/xvtext.c xv-3.10a-enhancements/xvtext.c ---- xv-3.10a-bugfixes/xvtext.c 2004-05-16 18:04:38.000000000 -0700 -+++ xv-3.10a-enhancements/xvtext.c 2005-05-01 13:04:23.000000000 -0700 -@@ -19,9 +19,13 @@ - #include "copyright.h" - - #include "xv.h" -+#ifdef TV_MULTILINGUAL -+#include "xvml.h" -+#endif - -- --#define BUTTW 80 -+#define BUTTW1 80 -+#define BUTTW2 60 -+#define BUTTW3 110 - #define BUTTH 24 - - #define TOPMARGIN 30 /* from top of window to top of text window */ -@@ -36,11 +40,28 @@ - #define TV_ASCII 0 - #define TV_HEX 1 - #define TV_CLOSE 2 --#define TV_NBUTTS 3 - -+#define TV_E_NBUTTS 3 -+ -+#ifdef TV_L10N -+# define TV_RESCAN 3 -+# define TV_USASCII 4 -+# define TV_JIS 5 -+# define TV_EUCJ 6 -+# define TV_MSCODE 7 -+ -+# define TV_J_NBUTTS 8 -+#endif - - #define TITLELEN 128 - -+#ifdef TV_MULTILINGUAL -+struct coding_spec { -+ struct coding_system coding_system; -+ char *(*converter)PARM((char *, int, int *)); -+}; -+#endif -+ - /* data needed per text window */ - typedef struct { Window win, textW; - int vis, wasvis; -@@ -57,16 +78,89 @@ - int chwide, chhigh; /* size of textW, in chars */ - int hexmode; /* true if disp Hex, else Ascii */ - SCRL vscrl, hscrl; -- BUTT but[TV_NBUTTS], nopBut; -+#ifdef TV_L10N -+ int code; /* current character code */ -+ BUTT but[TV_J_NBUTTS], nopBut; -+#else -+ BUTT but[TV_E_NBUTTS], nopBut; -+#endif -+#ifdef TV_MULTILINGUAL -+/* int codeset; */ -+ struct coding_spec ccs; /* current coding_spec */ -+ BUTT csbut; -+ char *cv_text; -+ int cv_len; -+ struct context *ctx; -+ struct ml_text *txt; -+ struct csinfo_t *cs; -+#endif - } TVINFO; - - - static TVINFO tinfo[MAXTVWIN]; - static int hasBeenSized = 0; - static int haveWindows = 0; -+static int nbutts; /* # of buttons */ - static int mfwide, mfhigh, mfascent; /* size of chars in mono font */ - static int *event_retP, *event_doneP; /* used in tvChkEvent() */ -- -+#ifdef TV_MULTILINGUAL -+# define TV_PLAIN 0 -+# define TV_ISO_8859_1 1 -+# define TV_ISO_2022_JP 2 -+# define TV_EUC_JAPAN 3 -+# define TV_ISO_2022_INT_1 4 -+# define TV_ISO_2022_KR 5 -+# define TV_EUC_KOREA 6 -+# define TV_ISO_2022_SS2_8 7 -+# define TV_ISO_2022_SS2_7 8 -+# define TV_SHIFT_JIS 9 -+# define TV_NCSS 10 -+static char *codeSetNames[TV_NCSS] = { -+ "plain", -+ "iso-8859-1", -+ "iso-2022-jp", -+ "euc-japan", -+ "iso-2022-int-1", -+ "iso-2022-kr", -+ "euc-korea", -+ "iso-2022-ss2-8", -+ "iso-2022-ss2-7", -+ "Shift JIS", -+}; -+static struct coding_spec coding_spec[TV_NCSS] = { -+ /* --- G0 --- --- G1 --- --- G2 --- --- G3 --- GL GR EOL SF LS */ -+ /* plain */ -+ {{{{ 1,94,'B'}, { 1,94,'B'}, { 1,94,'B'}, { 1,94,'B'}}, 0, 0, 0, 1, 1}, -+ NULL}, -+ /* iso-8859-1 */ -+ {{{{ 1,94,'B'}, { 1,96,'A'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 0, 0}, -+ NULL}, -+ /* iso-2022-jp */ -+ {{{{ 1,94,'B'}, {-1,94,'B'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 0, 0, 1, 0}, -+ NULL}, -+ /* euc-japan */ -+ {{{{ 1,94,'B'}, { 2,94,'B'}, { 1,94,'J'}, { 2,94,'D'}}, 0, 1, 0, 1, 0}, -+ NULL}, -+ /* iso-2022-int-1 */ -+ {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 1, 1}, -+ NULL}, -+ /* iso-2022-kr */ -+ {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 0, 1}, -+ NULL}, -+ /* euc-korea */ -+ {{{{ 1,94,'B'}, { 2,94,'C'}, {-1,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 0, 0}, -+ NULL}, -+ /* iso-2022-ss2-8 */ -+ {{{{ 1,94,'B'}, {-1,94,'C'}, { 0,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 0, 0}, -+ NULL}, -+ /* iso-2022-ss2-7 */ -+ {{{{ 1,94,'B'}, {-1,94,'C'}, { 0,94,'B'}, {-1,94,'B'}}, 0, 1, 0, 1, 0}, -+ NULL}, -+ /* shift jis */ -+ {{{{ 1,94,'B'}, { 2,94,'B'}, { 1,94,'J'}, { 2,94,'D'}}, 0, 1, 1, 1, 0}, -+ sjis_to_jis}, -+}; -+#endif - - static void closeText PARM((TVINFO *)); - static int tvChkEvent PARM((TVINFO *, XEvent *)); -@@ -82,7 +176,15 @@ - static void textKey PARM((TVINFO *, int)); - static void doHexAsciiCmd PARM((TVINFO *, int)); - static void computeText PARM((TVINFO *)); -- -+#ifdef TV_L10N -+static int selectCodeset PARM((TVINFO *)); -+#endif -+#ifdef TV_MULTILINGUAL -+static void setCodingSpec PARM((TVINFO *, struct coding_spec *)); -+static void createCsWins PARM((char *)); -+static void openCsWin PARM((TVINFO *)); -+static void closeCsWin PARM((TVINFO *)); -+#endif - - /* HEXMODE output looks like this: - 0x00000000: 00 11 22 33 44 55 66 77 - 88 99 aa bb cc dd ee ff 0123456789abcdef -@@ -98,12 +200,51 @@ - XSizeHints hints; - XSetWindowAttributes xswa; - TVINFO *tv; -+#ifdef TV_MULTILINGUAL -+ int default_codeset; -+#endif - -+#ifdef TV_L10N -+ if (!xlocale) { -+#endif -+ mfwide = monofinfo->max_bounds.width; -+ mfhigh = monofinfo->ascent + monofinfo->descent; -+ mfascent = monofinfo->ascent; - -- mfwide = monofinfo->max_bounds.width; -- mfhigh = monofinfo->ascent + monofinfo->descent; -- mfascent = monofinfo->ascent; -+ nbutts = TV_E_NBUTTS; /* # of buttons */ -+#ifdef TV_L10N -+ } -+ else { -+ mfwide = monofsetinfo->max_logical_extent.width / 2; /* shit! */ -+ mfhigh = monofsetinfo->max_logical_extent.height + 1; -+ mfascent = mfhigh; -+ -+ nbutts = TV_J_NBUTTS; /* # of buttons */ -+ } -+#endif - -+#ifdef TV_MULTILINGUAL -+ { -+ char *dc = XGetDefault(theDisp, "xv", "codeSet"); -+ if (dc == NULL) -+ default_codeset = TV_DEFAULT_CODESET; -+ else { -+ for (i = 0; i < TV_NCSS; i++) { -+ if (strcmp(dc, codeSetNames[i]) == 0) -+ break; -+ } -+ if (i >= TV_NCSS) { -+ if (strcmp(dc, "iso-2022") == 0) -+ default_codeset = TV_PLAIN; -+ else { -+ SetISTR(ISTR_WARNING, "%s: unknown codeset.", dc); -+ default_codeset = TV_PLAIN; -+ } -+ } else -+ default_codeset = i; -+ } -+ } -+#endif - /* compute default size of textview windows. should be big enough to - hold an 80x24 text window */ - -@@ -118,6 +259,14 @@ - for (i=0; i<MAXTVWIN; i++) { - tv = &tinfo[i]; - -+#ifdef TV_MULTILINGUAL -+ tv->ctx = ml_create_context(ScreenOfDisplay(theDisp, theScreen)); -+ tv->txt = NULL; -+ tv->cv_text = NULL; -+ tv->cv_len = 0; -+ ml_set_charsets(tv->ctx, &coding_spec[TV_PLAIN].coding_system); -+#endif -+ - tv->win = CreateWindow((i<CMTWIN) ? "xv text viewer" : "xv image comments", - "XVtextview", - (i<CMTWIN) ? geom : cmtgeom, -@@ -162,24 +311,56 @@ - XSelectInput(theDisp, tv->textW, ExposureMask | ButtonPressMask); - - -- BTCreate(&(tv->but[TV_ASCII]), tv->win, 0,0,BUTTW,BUTTH, -+ BTCreate(&(tv->but[TV_ASCII]), tv->win, 0,0,BUTTW1,BUTTH, - "Ascii",infofg,infobg,hicol,locol); -- BTCreate(&(tv->but[TV_HEX]), tv->win, 0,0,BUTTW,BUTTH, -+ BTCreate(&(tv->but[TV_HEX]), tv->win, 0,0,BUTTW1,BUTTH, - "Hex",infofg,infobg,hicol,locol); -- BTCreate(&(tv->but[TV_CLOSE]), tv->win, 0,0,BUTTW,BUTTH, -+ BTCreate(&(tv->but[TV_CLOSE]), tv->win, 0,0,BUTTW1,BUTTH, - "Close",infofg,infobg,hicol,locol); - -+#ifdef TV_L10N -+ if (xlocale) { -+ BTCreate(&(tv->but[TV_RESCAN]), tv->win, 0,0,BUTTW2,BUTTH, -+ "RESCAN",infofg,infobg,hicol,locol); -+ BTCreate(&(tv->but[TV_USASCII]), tv->win, 0,0,BUTTW2,BUTTH, -+ "ASCII",infofg,infobg,hicol,locol); -+ BTCreate(&(tv->but[TV_JIS]), tv->win, 0,0,BUTTW2,BUTTH, -+ "JIS",infofg,infobg,hicol,locol); -+ BTCreate(&(tv->but[TV_EUCJ]), tv->win, 0,0,BUTTW2,BUTTH, -+ "EUC-j",infofg,infobg,hicol,locol); -+ BTCreate(&(tv->but[TV_MSCODE]), tv->win, 0,0,BUTTW2,BUTTH, -+ "MS Kanji",infofg,infobg,hicol,locol); -+ } -+#endif -+ - BTCreate(&(tv->nopBut), tv->win, 0,0, (u_int) tv->vscrl.tsize+1, - (u_int) tv->vscrl.tsize+1, "", infofg, infobg, hicol, locol); - tv->nopBut.active = 0; - - XMapSubwindows(theDisp, tv->win); - -+#ifdef TV_MULTILINGUAL -+ BTCreate(&tv->csbut, tv->win, 0, 0, BUTTW1, BUTTH, "Code Sets", -+ infofg, infobg, hicol, locol); -+#endif -+ - tv->text = (char *) NULL; - tv->textlen = 0; - tv->title[0] = '\0'; -+#ifdef TV_L10N -+ tv->code = (xlocale ? LOCALE_DEFAULT : 0); -+#endif -+#ifdef TV_MULTILINGUAL -+ tv->ccs = coding_spec[default_codeset]; -+#endif - } -- -+#ifdef TV_MULTILINGUAL -+ get_monofont_size(&mfwide, &mfhigh); -+ /* recalculate sizes. */ -+ defwide = 80 * mfwide + 2*LRMARGINS + 8 + 20; /* -ish */ -+ defhigh = 24 * mfhigh + TOPMARGIN + BOTMARGIN + 8 + 20; /* ish */ -+ cmthigh = 6 * mfhigh + TOPMARGIN + BOTMARGIN + 8 + 20; /* ish */ -+#endif - - for (i=0; i<MAXTVWIN; i++) { - resizeText(&tinfo[i], defwide, (i<CMTWIN) ? defhigh : cmthigh); -@@ -190,44 +371,54 @@ - - hasBeenSized = 1; /* we can now start looking at textview events */ - -+#ifdef TV_MULTILINGUAL -+ createCsWins("+100+100"); -+#endif - } - - - /***************************************************************/ --void TextView(fname) -+int TextView(fname) - char *fname; - { - /* given a filename, attempts to read in the file and open a textview win */ - -+ int filetype; - long textlen; - char *text, buf[512], title[128], rfname[MAXPATHLEN+1]; - char *basefname[128]; /* just current fname, no path */ - FILE *fp; -+ char filename[MAXPATHLEN+1]; -+ -+ strncpy(filename, fname, sizeof(filename) - 1); -+#ifdef AUTO_EXPAND -+ Mkvdir(filename); -+ Dirtovd(filename); -+#endif - - basefname[0] = '\0'; -- strcpy(rfname, fname); -+ strncpy(rfname, filename, sizeof(rfname) - 1); - - /* see if this file is compressed. if it is, uncompress it, and view - the uncompressed version */ - -- if (ReadFileType(fname) == RFT_COMPRESS) { -+ filetype = ReadFileType(filename); -+ if ((filetype == RFT_COMPRESS) || (filetype == RFT_BZIP2)) { - #ifndef VMS -- if (!UncompressFile(fname, rfname)) return; /* failed to uncompress */ -+ if (!UncompressFile(filename, rfname, filetype)) return FALSE; - #else - /* chop off trailing '.Z' from friendly displayed basefname, if any */ -- strcpy (basefname, fname); -+ strncpy (basefname, filename, 128 - 1); - *rindex (basefname, '.') = '\0'; -- if (!UncompressFile(basefname, rfname)) return;/* failed to uncompress */ -+ if (!UncompressFile(basefname, rfname, filetype)) return FALSE; - #endif - } - -- -- - fp = fopen(rfname, "r"); - if (!fp) { - sprintf(buf,"Couldn't open '%s': %s", rfname, ERRSTR(errno)); - ErrPopUp(buf,"\nOh well"); -- return; -+ return FALSE; - } - - -@@ -239,16 +430,16 @@ - sprintf(buf, "File '%s' contains no data. (Zero length file.)", rfname); - ErrPopUp(buf, "\nOk"); - fclose(fp); -- return; -+ return FALSE; - } - -- text = (char *) malloc((size_t) textlen); -+ text = (char *) malloc((size_t) textlen + 1); - if (!text) { - sprintf(buf, "Couldn't malloc %ld bytes to read file '%s'", - textlen, rfname); - ErrPopUp(buf, "\nSo what!"); - fclose(fp); -- return; -+ return FALSE; - } - - if (fread(text, (size_t) 1, (size_t) textlen, fp) != textlen) { -@@ -256,6 +447,9 @@ - rfname); - ErrPopUp(buf, "\nHmm..."); - } -+#ifdef TV_MULTILINGUAL -+ text[textlen] = '\0'; -+#endif - - fclose(fp); - -@@ -263,6 +457,7 @@ - OpenTextView(text, (int) textlen, title, 1); - - /* note: text gets freed when window gets closed */ -+ return TRUE; - } - - -@@ -504,6 +699,10 @@ - tv->text = (char *) NULL; - tv->lines = (char **) NULL; - tv->numlines = tv->textlen = tv->hexmode = 0; -+ -+#ifdef TV_MULTILINGUAL -+ closeCsWin(tv); -+#endif - } - - -@@ -591,6 +790,40 @@ - else if (e->window == tv->textW) { } - else rv = 0; - } -+ else if (e->button == Button4) { /* note min vs. max, + vs. - */ -+ /* scroll regardless of where we are in the text window */ -+ if (e->window == tv->win || -+ e->window == tv->vscrl.win || -+ e->window == tv->hscrl.win || -+ e->window == tv->textW) -+ { -+ SCRL *sp=&(tv->vscrl); -+ int halfpage=sp->page/2; -+ -+ if (sp->val > sp->min+halfpage) -+ SCSetVal(sp,sp->val-halfpage); -+ else -+ SCSetVal(sp,sp->min); -+ } -+ else rv = 0; -+ } -+ else if (e->button == Button5) { /* note max vs. min, - vs. + */ -+ /* scroll regardless of where we are in the text window */ -+ if (e->window == tv->win || -+ e->window == tv->vscrl.win || -+ e->window == tv->hscrl.win || -+ e->window == tv->textW) -+ { -+ SCRL *sp=&(tv->vscrl); -+ int halfpage=sp->page/2; -+ -+ if (sp->val < sp->max-halfpage) -+ SCSetVal(sp,sp->val+halfpage); -+ else -+ SCSetVal(sp,sp->max); -+ } -+ else rv = 0; -+ } - else rv = 0; - } - -@@ -633,7 +866,9 @@ - int i, maxw, maxh; - XSizeHints hints; - -+#ifndef TV_MULTILINGUAL - if (tv->wide == w && tv->high == h) return; /* no change in size */ -+#endif - - if (XGetNormalHints(theDisp, tv->win, &hints)) { - hints.width = w; -@@ -657,10 +892,23 @@ - XMoveResizeWindow(theDisp, tv->textW, LRMARGINS, TOPMARGIN, - (u_int) tv->twWide, (u_int) tv->twHigh); - -- for (i=0; i<TV_NBUTTS; i++) { -- tv->but[i].x = tv->wide - (TV_NBUTTS-i) * (BUTTW+5); -+ for (i=0; i<TV_E_NBUTTS; i++) { -+ tv->but[i].x = tv->wide - (TV_E_NBUTTS-i) * (BUTTW1+5); - tv->but[i].y = tv->high - BUTTH - 5; - } -+#ifdef TV_MULTILINGUAL -+ tv->csbut.x = 5; -+ tv->csbut.y = tv->high - BUTTH - 5; -+#endif -+ -+#ifdef TV_L10N -+ if (xlocale) { -+ for (; i<TV_J_NBUTTS; i++) { -+ tv->but[i].x = 5 + (i-TV_E_NBUTTS) * (BUTTW2+5); -+ tv->but[i].y = tv->high - BUTTH - 5; -+ } -+ } -+#endif - - computeScrlVals(tv); - -@@ -711,6 +959,29 @@ - case TV_CLOSE: if (tv == &tinfo[CMTWIN]) CloseCommentText(); - else closeText(tv); - break; -+ -+#ifdef TV_L10N -+ case TV_RESCAN: -+ tv->code = selectCodeset(tv); -+ drawTextW(0, &tv->vscrl); -+ break; -+ case TV_USASCII: -+ tv->code = LOCALE_USASCII; -+ drawTextW(0, &tv->vscrl); -+ break; -+ case TV_JIS: -+ tv->code = LOCALE_JIS; -+ drawTextW(0, &tv->vscrl); -+ break; -+ case TV_EUCJ: -+ tv->code = LOCALE_EUCJ; -+ drawTextW(0, &tv->vscrl); -+ break; -+ case TV_MSCODE: -+ tv->code = LOCALE_MSCODE; -+ drawTextW(0, &tv->vscrl); -+ break; -+#endif /* TV_L10N */ - } - } - -@@ -745,8 +1016,10 @@ - drawNumLines(tv); - - /* draw the buttons */ -- for (i=0; i<TV_NBUTTS; i++) BTRedraw(&(tv->but[i])); -- -+ for (i=0; i<nbutts; i++) BTRedraw(&(tv->but[i])); -+#ifdef TV_MULTILINGUAL -+ BTRedraw(&tv->csbut); -+#endif - BTRedraw(&tv->nopBut); - } - -@@ -816,7 +1089,14 @@ - int delta; - SCRL *sptr; - { -- int i, j, lnum, hpos, cpos, extrach, lwide; -+ int i, j, lnum, hpos, vpos, cpos, lwide; -+#ifndef TV_MULTILINGUAL -+ int extrach; -+#endif -+#ifdef TV_L10N -+ int desig_stat; /* for ISO 2022-JP */ -+ /* 0: ASCII, 1: JIS X 0208, 2: GL is JIS X 0201 kana */ -+#endif - TVINFO *tv; - char linestr[512]; - u_char *sp, *ep, *lp; -@@ -839,12 +1119,38 @@ - XSetFont(theDisp, theGC, monofont); - - hpos = tv->hscrl.val; -+ vpos = tv->vscrl.val; - lwide = (tv->chwide < 500) ? tv->chwide : 500; - - /* draw text */ - if (!tv->hexmode) { /* ASCII mode */ -+#ifdef TV_MULTILINGUAL -+ XClearArea(theDisp, tv->textW, 0, 0, -+ (u_int) tv->twWide, (u_int) tv->twHigh, False); -+ if(tv->txt == NULL) -+ return; -+ else { -+ int i; -+ int y; -+ struct ml_text *tp = tv->txt; -+ struct ml_line *lp; -+ -+ XSetFunction(theDisp, theGC, GXcopy); -+ XSetClipMask(theDisp, theGC, None); -+ y = 3; -+ for (lp = &tp->lines[vpos], i = tp->nlines - vpos; -+ i > 0; lp++, i--) { -+ XDrawText16(theDisp, tv->textW, theGC, -+ -mfwide * hpos + 3, y + lp->ascent, -+ lp->items, lp->nitems); -+ y += lp->ascent + lp->descent; -+ if (y > tv->twHigh) -+ break; -+ } -+ } -+#else - for (i=0; i<tv->chhigh; i++) { /* draw each line */ -- lnum = i + tv->vscrl.val; -+ lnum = i + vpos; - if (lnum < tv->numlines-1) { - - /* find start of displayed portion of line. This is *wildly* -@@ -865,7 +1171,13 @@ - cpos--; sp++; - } - else if (*sp < 32) extrach = 1; -+ -+#ifdef TV_L10N -+ else if (!tv->code && *sp > 127) extrach = 3; -+#else - else if (*sp > 127) extrach = 3; -+#endif -+ - else sp++; - } - else { -@@ -881,6 +1193,10 @@ - - /* build up the linestr buffer, which is the current line, padded - with blanks to a width of exactly tv->chwide chars */ -+#ifdef TV_L10N -+ desig_stat = 0; /* for ISO 2022-JP */ -+ /* 0: ASCII, 1: JIS X 0208, 2: GL is JIS X 0201 kana */ -+#endif - for (cpos=0, lp=(byte *) linestr; cpos<lwide; cpos++, lp++) { - if (sp>=ep) *lp = ' '; - else { -@@ -894,13 +1210,117 @@ - cpos--; lp--; sp++; - } - -+#ifdef TV_L10N -+ else if (*sp < 32 && !(tv->code == LOCALE_JIS && *sp == 0x1b)) { -+#else - else if (*sp < 32) { -+#endif - if (!extrach) extrach = 2; - if (extrach == 2) *lp = '^'; - else if (extrach == 1) *lp = *sp + 64; - } - -+#ifdef TV_L10N -+ /* convert to EUC-Japan */ -+ else if (tv->code == LOCALE_JIS) { -+ if (*sp == 0x1b) { /* ESC */ -+ if (*(sp+1) == '$') { -+ if (*(sp+2) == 'B' || *(sp+2) == 'A' || *(sp+2) == '@') { -+ /* ESC $ B, ESC $ A, ESC $ @ */ -+ desig_stat = 1; -+ sp += 3; cpos--; lp--; -+ } -+ else if (*(sp+2) == '(' && *(sp+3) == 'B') { -+ /* ESC $ ( B */ -+ desig_stat = 1; -+ sp += 4; cpos--; lp--; -+ } -+ } -+ else if (*(sp+1) == '(') { -+ if (*(sp+2) == 'B' || *(sp+2) == 'J' || *(sp+2) == 'H') { -+ /* ESC ( B, ESC ( J, ESC ( H */ -+ desig_stat = 0; -+ sp += 3; cpos--; lp--; -+ } -+ else if (*(sp+2) == 'I') { -+ /* ESC ( I */ -+ desig_stat = 2; -+ sp += 3; cpos--; lp--; -+ } -+ } -+ else if (*(sp+1) == ')' && *(sp+2) == 'I') { -+ /* ESC ) I */ -+ desig_stat = 2; -+ sp += 3; cpos--; lp--; -+ } -+ else { /* error */ -+ *lp = ' '; sp++; -+ } -+ } -+ -+ else { -+ switch (desig_stat) { -+ case 0: /* ASCII */ -+ *lp = *sp++; -+ break; -+ case 1: /* JIS X 0208 */ -+ *lp++ = *sp++ | 0x80; -+ *lp = *sp++ | 0x80; -+ cpos++; -+ break; -+ case 2: /* JIS X 0201 kana */ -+#if defined(__osf__) && !defined(X_LOCALE) -+ *lp = '='; sp++; -+#else -+ *lp++ = 0x8e; /* ^N | 0x80 */ -+ *lp = *sp++ | 0x80; -+#endif -+ break; -+ default: /* error */ -+ *lp = *sp++; -+ break; -+ } -+ } -+ } -+ -+ else if (tv->code == LOCALE_MSCODE) { -+ if ((*sp >= 0x81 && *sp <= 0x9f) -+ || (*sp >= 0xe0 && *sp <= 0xef)) { -+ static u_char c1, c2; -+ -+/*fprintf(stderr, "(%x,%x)->", *sp, *(sp+1));*/ -+ c1 = ((*sp - ((*sp>=0xe0) ? 0xb0 : 0x70)) << 1) -+ - ((*(sp+1)<=0x9e) ? 1 : 0); -+ c2 = *(sp+1); -+ if (c2 >= 0x9f) c2 -= 0x7e; /* 0x9F - 0xFC */ -+ else if (c2 >= 0x80) c2 -= 0x20; /* 0x80 - 0x9E */ -+ else c2 -= 0x1f; /* 0x40 - 0x7E */ -+ -+ *lp++ = c1 | 0x80; -+ *lp = c2 | 0x80; -+ sp += 2; -+/*fprintf(stderr, "(%x %x) ", c1 | 0x80, c2 | 0x80);*/ -+ cpos++; -+ } -+ -+ else if (*sp >= 0xa1 && *sp <= 0xdf) { /* JIS X 0201 kana */ -+#if defined(__osf__) && !defined(X_LOCALE) -+ *lp = '='; sp++; -+#else -+ *lp++ = 0x8e; /* ^N | 0x80 */ -+ *lp = *sp++; -+#endif -+ } -+ -+ else *lp = *sp++; -+ } -+#endif /* TV_L10N */ -+ -+#ifdef TV_L10N -+ else if (!tv->code && *sp > 127) { -+#else - else if (*sp > 127) { -+#endif - if (!extrach) extrach = 4; - if (extrach == 4) *lp = '\\'; - else if (extrach == 3) *lp = ((u_char)(*sp & 0700) >> 6) + '0'; -@@ -916,6 +1336,9 @@ - } - } - } -+#ifdef TV_L10N -+ *lp = '\0'; /* terminate linestr */ -+#endif - } - - else { /* below bottom of file. Just build a blank str */ -@@ -923,15 +1346,22 @@ - } - - /* draw the line */ -- XDrawImageString(theDisp, tv->textW, theGC, -- 3, i*mfhigh + 3 + mfascent, linestr, lwide); -+#ifdef TV_L10N -+ if (xlocale) -+ XmbDrawImageString(theDisp, tv->textW, monofset, theGC, -+ 3, i*mfhigh + 1 + mfascent, linestr, strlen(linestr)); -+ else -+#endif -+ XDrawImageString(theDisp, tv->textW, theGC, -+ 3, i*mfhigh + 3 + mfascent, linestr, lwide); - } /* for i ... */ -+#endif /* TV_MULTILINGUAL */ - } /* if hexmode */ - - - else { /* HEX MODE */ - for (i=0; i<tv->chhigh; i++) { /* draw each line */ -- lnum = i + tv->vscrl.val; -+ lnum = i + vpos; - if (lnum < tv->hexlines) { - - char hexstr[80], tmpstr[16]; -@@ -957,7 +1387,11 @@ - - for (j=0; j<16; j++) { - if (sp+j < ep) { -+#ifdef TV_L10N -+ if (sp[j] >= 32 && (sp[j] <= 127 || tv->code)) *lp++ = sp[j]; -+#else - if (sp[j] >= 32 && sp[j] <= 127) *lp++ = sp[j]; -+#endif - else *lp++ = '.'; - } - else *lp++ = ' '; -@@ -1005,14 +1439,21 @@ - int i; - BUTT *bp; - -- for (i=0, bp=tv->but; i<TV_NBUTTS; i++, bp++) { -+ for (i=0, bp=tv->but; i<nbutts; i++, bp++) { - if (PTINRECT(x,y,bp->x,bp->y,bp->w,bp->h)) break; - } - -- if (i<TV_NBUTTS) { -+ if (i<nbutts) { - if (BTTrack(bp)) doCmd(tv, i); - return; - } -+ -+#ifdef TV_MULTILINGUAL -+ if (PTINRECT(x, y, tv->csbut.x, tv->csbut.y, tv->csbut.w, tv->csbut.h)) { -+ if (BTTrack(&tv->csbut)) -+ openCsWin(tv); -+ } -+#endif - } - - -@@ -1042,13 +1483,38 @@ - - /* keyboard equivalents */ - switch (buf[0]) { -- case '\001': doCmd(tv, TV_ASCII); break; /* ^A = Ascii */ -- case '\010': doCmd(tv, TV_HEX); break; /* ^H = Hex */ -- -- case '\033': doCmd(tv, TV_CLOSE); break; /* ESC = Close window */ -+ case '\001': case 'a': case 'A': -+ doCmd(tv, TV_ASCII); break; /* ^A = Ascii */ -+ case '\010': case 'h': case 'H': -+ doCmd(tv, TV_HEX); break; /* ^H = Hex */ -+ -+ case '\021': case 'q': case 'Q': -+ case '\003': case 'c': case 'C': -+ case '\033': -+ doCmd(tv, TV_CLOSE); break; /* ESC = Close window */ - - default: break; - } -+ -+#ifdef TV_L10N -+ if (xlocale) { -+ switch (buf[0]) { -+ case '\022': case 'r': case 'R': -+ doCmd(tv, TV_RESCAN); break; -+ case '\012': case 'j': case 'J': -+ doCmd(tv, TV_JIS); break; -+ case '\005': case 'e': case 'E': -+ case '\025': case 'u': case 'U': -+ doCmd(tv, TV_EUCJ); break; -+ case '\015': case 'm': case 'M': -+ case '\023': case 's': case 'S': -+ doCmd(tv, TV_MSCODE); break; -+ -+ default: break; -+ } -+ } -+#endif /* TV_L10N */ -+ - } - - -@@ -1109,7 +1575,20 @@ - if (i<tv->numlines-1) SCSetVal(&tv->vscrl, i); - } - -+#ifdef TV_L10N -+ /* redraw text */ -+ if (xlocale) { -+ XClearArea(theDisp, tv->textW, 0, 0, -+ (u_int) tv->twWide, (u_int) tv->twHigh, False); -+ -+ drawTextW(0, &tv->vscrl); -+ } -+#endif -+#ifdef TV_MULTILINGUAL -+ XClearArea(theDisp, tv->textW, 0, 0, -+ (u_int) tv->twWide, (u_int) tv->twHigh, False); - drawTextW(0, &tv->vscrl); -+#endif - } - - -@@ -1122,9 +1601,22 @@ - int i,j,wide,maxwide,space; - byte *sp; - -+#ifdef TV_L10N -+ /* select code-set */ -+ if (xlocale) -+ tv->code = selectCodeset(tv); -+#endif /* TV_L10N */ -+ - if (!tv->text) { - tv->numlines = tv->hexlines = 0; - tv->lines = (char **) NULL; -+#ifdef TV_MULTILINGUAL -+ if (tv->cv_text != NULL) { -+ free(tv->cv_text); -+ tv->cv_text = NULL; -+ } -+ tv->txt = NULL; -+#endif - return; - } - -@@ -1172,17 +1664,129 @@ - wide += space; - } - else if (*sp < 32) wide += 2; -+#ifdef TV_L10N -+ else if (*sp > 127 && !tv->code) wide += 4; -+#else - else if (*sp > 127) wide += 4; -+#endif - else wide++; - } - if (wide > maxwide) maxwide = wide; - } - tv->maxwide = maxwide; - -+#ifdef TV_MULTILINGUAL -+ ml_set_charsets(tv->ctx, &tv->ccs.coding_system); -+ if (tv->cv_text != NULL) { -+ free(tv->cv_text); -+ tv->cv_text = NULL; -+ } -+ if (tv->ccs.converter == NULL) { -+ tv->txt = ml_draw_text(tv->ctx, tv->text, tv->textlen); -+ } else { -+ tv->cv_text = (*tv->ccs.converter)(tv->text, tv->textlen, &tv->cv_len); -+ tv->txt = ml_draw_text(tv->ctx, tv->cv_text, tv->cv_len); -+ } -+ tv->maxwide = tv->txt->width / mfwide; -+ tv->numlines = tv->txt->height / mfhigh + 1; -+#endif -+ - tv->hexlines = (tv->textlen + 15) / 16; - } - - -+/***************************************************/ -+#ifdef TV_L10N -+static int selectCodeset(tv) -+ TVINFO *tv; -+{ -+ u_char *sp; -+ int i, len; -+ int code = LOCALE_USASCII; /* == 0 */ -+ -+ -+ len = tv->textlen; -+ -+ /* select code-set */ -+ if (xlocale) { -+ sp = (u_char *) tv->text; i = 0; -+ while (i < len - 1) { -+ if (*sp == 0x1b && -+ (*(sp+1) == '$' || *(sp+1) == '(' || *(sp+1) == ')')) { -+ code = LOCALE_JIS; -+ break; -+ } -+ -+ else if (*sp >= 0xa1 && *sp <= 0xdf) { -+ if (*(sp+1) >= 0xf0 && *(sp+1) <= 0xfe) { -+ code = LOCALE_EUCJ; -+ break; -+ } -+# if (LOCALE_DEFAULT == LOCALE_EUCJ) -+ else { -+ sp++; i++; -+ } -+# endif -+ } -+ -+ else if ((*sp >= 0x81 && *sp <= 0x9f) || (*sp >= 0xe0 && *sp <= 0xef)) { -+ if ((*(sp+1) >= 0x40 && *(sp+1) <= 0x7e) || *(sp+1) == 0x80) { -+ code = LOCALE_MSCODE; -+ break; -+ } -+ else if (*(sp+1) == 0xfd || *(sp+1) == 0xfe) { -+ code = LOCALE_EUCJ; -+ break; -+ } -+ else { -+ sp++; i++; -+ } -+ } -+ -+ else if (*sp >= 0xf0 && *sp <= 0xfe) { -+ code = LOCALE_EUCJ; -+ break; -+ } -+ -+ sp++; i++; -+ } -+ if (!code) code = LOCALE_DEFAULT; -+ } -+ -+ return code; -+} -+#endif /* TV_L10N */ -+ -+#ifdef TV_MULTILINGUAL -+static void setCodingSpec(tv, cs) -+ TVINFO *tv; -+ struct coding_spec *cs; -+{ -+ if (xvbcmp((char *) &tv->ccs, (char *) cs, sizeof *cs) == 0) -+ return; -+ -+ tv->ccs = *cs; -+#if 0 -+ ml_set_charsets(tv->ctx, &tv->ccs.coding_system); -+ if (tv->cv_text != NULL) { -+ free(tv->cv_text); -+ tv->cv_text = NULL; -+ } -+ if (tv->ccs.converter == NULL) { -+ tv->txt = ml_draw_text(tv->ctx, tv->text, tv->textlen); -+ } else { -+ tv->cv_text = (*tv->ccs.converter)(tv->text, tv->textlen, &tv->cv_len); -+ tv->txt = ml_draw_text(tv->ctx, tv->cv_text, tv->cv_len); -+ } -+#else -+ computeText(tv); -+ computeScrlVals(tv); -+#endif -+ /* drawTextW(0, &tv->vscrl); */ -+} -+#endif -+ -+ - /**********************************************************************/ - /* BUILT-IN TEXT FILES ************************************************/ - /**********************************************************************/ -@@ -1555,8 +2159,509 @@ - OpenTextView(keyhelp, (int) strlen(keyhelp), "XV Help", 0); - } - -+#ifdef TV_MULTILINGUAL -+ -+#define TV_ML_ACCEPT TV_NCSS -+#define TV_ML_CLOSE (TV_ML_ACCEPT + 1) -+#define TV_ML_NBUTTS (TV_ML_CLOSE + 1) -+ -+#define TV_ML_RETCODE 0 -+# define TV_ML_RET_LF 0 -+# define TV_ML_RET_CRLF 1 -+# define TV_ML_RET_CR 2 -+# define TV_ML_RET_ANY 3 -+#define TV_ML_GL 1 -+#define TV_ML_GR 2 -+#define TV_ML_CVTR 3 -+#define TV_ML_NRBUTTS 4 -+ -+#define TV_ML_SHORT 0 -+#define TV_ML_LOCK 1 -+#define TV_ML_NCBUTTS 2 -+ -+#define TV_ML_NLISTS 4 -+ -+#define CSWIDE (BUTTW3 * 5 + 5 * 6) -+#define CSHIGH 450 -+ -+typedef struct csinfo_t { -+ TVINFO *tv; -+ RBUTT *rbt[TV_ML_NRBUTTS]; -+ CBUTT cbt[TV_ML_NCBUTTS]; -+ LIST ls[TV_ML_NLISTS]; -+ BUTT bt[TV_ML_NBUTTS]; -+ int up; -+ Window win; -+ struct coding_spec tcs; /* temporary coding_spec */ -+} CSINFO; -+CSINFO csinfo[MAXTVWIN]; -+static char **regs; -+static int nregs; -+ -+static int csCheckEvent PARM((CSINFO *, XEvent *)); -+static void csReflect PARM((CSINFO *)); -+static void csRedraw PARM((CSINFO *)); -+static void csListRedraw PARM((LIST *)); -+static void csLsRedraw PARM((int, SCRL *)); -+static void create_registry_list PARM((void)); -+ -+static char *(*cvtrtab[])PARM((char *, int, int *)) = { -+ NULL, -+ sjis_to_jis, -+}; -+ -+static void createCsWins(geom) -+ char *geom; -+{ -+ XSetWindowAttributes xswa; -+ int i, j; -+ -+ create_registry_list(); -+ -+ xswa.backing_store = WhenMapped; -+ for (i = 0; i < MAXTVWIN; i++) { -+ char nam[8]; -+ TVINFO *tv = &tinfo[i]; -+ CSINFO *cs = &csinfo[i]; -+ tv->cs = cs; -+ cs->tv = tv; -+ sprintf(nam, "XVcs%d", i); -+ cs->win = CreateWindow("xv codeset", nam, geom, -+ CSWIDE, CSHIGH, infofg, infobg, 0); -+ if (!cs->win) FatalError("couldn't create 'charset' window!"); -+#ifdef BACKING_STORE -+ XChangeWindowAttributes(theDisp, cs->win, CWBackingStore, &xswa); -+#endif -+ XSelectInput(theDisp, cs->win, ExposureMask | ButtonPressMask); -+ -+ DrawString(cs->win, 5, 5 + ASCENT, "Initial States"); -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ int x, y; -+ char buf[80]; -+ -+ if (i / 2 == 0) -+ x = 15; -+ else -+ x = 280; -+ if (i % 2 == 0) -+ y = 5 + LINEHIGH * 1; -+ else -+ y = 5 + LINEHIGH * 7 + SPACING * 3; -+ -+ sprintf(buf, "Designation for G%d:", i + 1); -+ DrawString(cs->win, x, y + ASCENT, buf); -+ -+ LSCreate(&cs->ls[i], cs->win, x + 15, y + LINEHIGH, -+ 200, LINEHIGH * 5, 5, -+ regs, nregs + 2, -+ infofg, infobg, hicol, locol, csLsRedraw, 0, 0); -+ cs->ls[i].selected = 0; -+ } -+ -+ for (i = 0; i < 2; i++) { -+ char *p; -+ int n; -+ int x, y; -+ -+ if ((p = (char *) malloc(3 * 4)) == NULL) -+ FatalError("out of memory in createCsWins()."); -+ strcpy(p, "G1 G2 G3 G4"); -+ p[2] = p[5] = p[8] = '\0'; -+ n = (i == 0 ? TV_ML_GL : TV_ML_GR); -+ x = (i == 0 ? 15 : 280); -+ y = 235; -+ DrawString(cs->win, x, y + ASCENT, "Assignment for GL:"); -+ x += 15; -+ y += LINEHIGH; -+ cs->rbt[n] = RBCreate(NULL, cs->win, -+ x, y, p, infofg, infobg, hicol, locol); -+ for (j = 1; j < 4; j++) { -+ p += 3; -+ x += 50; -+ RBCreate(cs->rbt[n], cs->win, -+ x, y, p, infofg, infobg, hicol, locol); -+ } -+ } -+ -+ DrawString(cs->win, 5, 280 + ASCENT, "Ret Code:"); -+ cs->rbt[TV_ML_RETCODE] = -+ RBCreate(NULL, cs->win, 20, 300, "LF", infofg,infobg, hicol,locol); -+ RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 20, 300 + 20, "CR+LF", -+ infofg, infobg, hicol, locol); -+ RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 90, 300, "CR", -+ infofg, infobg, hicol, locol); -+ RBCreate(cs->rbt[TV_ML_RETCODE], cs->win, 90, 300 + 20, "Any", -+ infofg, infobg, hicol, locol); -+ -+ DrawString(cs->win, 350, 280 + ASCENT, "Converter:"); -+ cs->rbt[TV_ML_CVTR] = -+ RBCreate(NULL, cs->win, 365, 300, "Nothing", -+ infofg, infobg, hicol, locol); -+ RBCreate(cs->rbt[TV_ML_CVTR], cs->win, 365, 300 + 20, "Shift JIS", -+ infofg, infobg, hicol, locol); -+ -+ CBCreate(&cs->cbt[TV_ML_SHORT], cs->win, 200, 300, "Short Form", -+ infofg, infobg, hicol, locol); -+ CBCreate(&cs->cbt[TV_ML_LOCK], cs->win, 200, 320, "Locking Shift", -+ infofg, infobg, hicol, locol); -+ -+ for (j = 0; j < TV_NCSS; j++) { -+ BTCreate(&cs->bt[j], cs->win, -+ 5 + (BUTTW3 + 5) * (j % 5), -+ 350 + 5 + (BUTTH + 5) * (j / 5), -+ BUTTW3, BUTTH, codeSetNames[j], -+ infofg, infobg, hicol, locol); -+ } -+ BTCreate(&cs->bt[TV_ML_ACCEPT], cs->win, -+ CSWIDE - 10 - BUTTW3 * 2, CSHIGH - 5 - BUTTH, BUTTW3, BUTTH, -+ "Accept", infofg, infobg, hicol, locol); -+ BTCreate(&cs->bt[TV_ML_CLOSE], cs->win, -+ CSWIDE - 5 - BUTTW3, CSHIGH - 5 - BUTTH, BUTTW3, BUTTH, -+ "Close", infofg, infobg, hicol, locol); - -+ XMapSubwindows(theDisp, cs->win); -+ cs->up = 0; -+ } -+} - -+static void openCsWin(tv) -+ TVINFO *tv; -+{ -+ CSINFO *cs = tv->cs; -+ if (cs->up) -+ return; - -+ XMapRaised(theDisp, cs->win); -+ cs->up = 1; -+ cs->tcs = cs->tv->ccs; -+ csReflect(cs); -+} - -+static void closeCsWin(tv) -+ TVINFO *tv; -+{ -+ CSINFO *cs = tv->cs; -+ if (!cs->up) -+ return; -+ cs->up = 0; -+ XUnmapWindow(theDisp, cs->win); -+} -+ -+int CharsetCheckEvent(xev) -+ XEvent *xev; -+{ -+ int i; -+ CSINFO *cs; -+ -+ for (cs = csinfo, i = 0; i < MAXTVWIN; cs++, i++) { -+ if (!cs->up) -+ continue; -+ if (csCheckEvent(cs, xev)) -+ break; -+ } -+ if (i < MAXTVWIN) -+ return 1; -+ return 0; -+} -+ -+static int csCheckEvent(cs, xev) -+ CSINFO *cs; -+ XEvent *xev; -+{ -+ RBUTT **rbp; -+ CBUTT *cbp; -+ LIST *ls; -+ BUTT *bp; -+ int i, n; -+ -+ 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 (cs->win == e->window){ -+ csRedraw(cs); -+ return 1; -+ } else { -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ if (cs->ls[i].win == e->window) { -+ LSRedraw(&cs->ls[i], 0); -+ return 1; -+ } -+ } -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ if (cs->ls[i].scrl.win == e->window) { -+ SCRedraw(&cs->ls[i].scrl); -+ return 1; -+ } -+ } -+ } -+ } else if (xev->type == ButtonPress) { -+ int x, y; -+ XButtonEvent *e = (XButtonEvent *) xev; -+ x = e->x; y = e->y; -+ if (cs->win == e->window) { -+ for (bp = cs->bt, i = 0; i < TV_ML_NBUTTS; bp++, i++) { -+ if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) -+ break; -+ } -+ if (i < TV_ML_NBUTTS) { -+ if (BTTrack(bp)) { -+ if (i < TV_NCSS) { -+ cs->tcs = coding_spec[i]; -+ csReflect(cs); -+ } else { -+ switch (i) { -+ case TV_ML_ACCEPT: -+ setCodingSpec(cs->tv, &cs->tcs); -+ break; -+ case TV_ML_CLOSE: -+ closeCsWin(cs->tv); -+ break; -+ } -+ } -+ } -+ return 1; -+ } -+ for (cbp = cs->cbt, i = 0; i < TV_ML_NCBUTTS; cbp++, i++) { -+ if (CBClick(cbp, x, y) && CBTrack(cbp)) -+ break; -+ } -+ if (i < TV_ML_NCBUTTS) { -+ switch (i) { -+ case TV_ML_SHORT: -+ cs->tcs.coding_system.short_form = cbp->val; -+ break; -+ case TV_ML_LOCK: -+ cs->tcs.coding_system.lock_shift = cbp->val; -+ break; -+ } -+ return 1; -+ } -+ for (rbp = cs->rbt, i = 0; i < TV_ML_NRBUTTS; rbp++, i++) { -+ if ((n = RBClick(*rbp, x, y)) >= 0 && RBTrack(*rbp, n)) { -+ break; -+ } -+ } -+ if (i < TV_ML_NRBUTTS) { -+ switch (i) { -+ case TV_ML_RETCODE: -+ cs->tcs.coding_system.eol = n; -+ break; -+ case TV_ML_GL: -+ cs->tcs.coding_system.gl = n; -+ break; -+ case TV_ML_GR: -+ cs->tcs.coding_system.gr = n; -+ break; -+ case TV_ML_CVTR: -+ cs->tcs.converter = cvtrtab[n]; -+ break; -+ } -+ return 1; -+ } -+ } else { -+ for (ls = cs->ls, i = 0; i < TV_ML_NLISTS; ls++, i++) { -+ if (ls->win == e->window) { -+ LSClick(ls, e); -+ n = ls->selected; -+ if (n < nregs) { -+ char r[32], *p = r; -+ int b7; -+ strcpy(r, regs[n]); -+ if ((p = strrchr(r, '/')) != NULL) { -+ *p = '\0'; -+ b7 = (*(p + 1) == 'R' ? 1 : 0); -+ } else -+ b7 = 0; /* shouldn't occur */ -+ cs->tcs.coding_system.design[i] = lookup_design(r, b7); -+ } else if (n == nregs) /* initially none is designed. */ -+ cs->tcs.coding_system.design[i].bpc = 0; -+ else -+ cs->tcs.coding_system.design[i].bpc = -1; -+ return 1; -+ } -+ } -+ for (ls = cs->ls, i = 0; i < TV_ML_NLISTS; ls++, i++) { -+ if (ls->scrl.win == e->window) { -+ SCTrack(&ls->scrl, x, y); -+ return 1; -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+static void csReflect(cs) -+ CSINFO *cs; -+{ -+ int i; -+ -+ RBSelect(cs->rbt[TV_ML_RETCODE], cs->tcs.coding_system.eol); -+ RBSelect(cs->rbt[TV_ML_GL], cs->tcs.coding_system.gl); -+ RBSelect(cs->rbt[TV_ML_GR], cs->tcs.coding_system.gr); -+ for (i = 0; i < sizeof cvtrtab / sizeof cvtrtab[0]; i++) { -+ if (cs->tcs.converter == cvtrtab[i]) -+ break; -+ } -+ if (i >= sizeof cvtrtab / sizeof cvtrtab[0]) -+ FatalError("program error in csReflect()."); -+ RBSelect(cs->rbt[TV_ML_CVTR], i); -+ -+ cs->cbt[TV_ML_SHORT].val = cs->tcs.coding_system.short_form; -+ cs->cbt[TV_ML_LOCK].val = cs->tcs.coding_system.lock_shift; -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ struct design design = cs->tcs.coding_system.design[i]; -+ char *reg, r[32]; -+ int b7; -+ int n = 0; -+ switch (design.bpc) { -+ case -1: -+ n = nregs + 1; -+ break; -+ case 0: -+ n = nregs; -+ break; -+ case 1: -+ case 2: -+ if ((reg = lookup_registry(design, &b7)) == NULL) -+ FatalError("internal error in csReflect."); -+ sprintf(r, "%s/%s", reg, b7 ? "Right" : "Left"); -+ for (n = 0; n < nregs; n++) { -+ if (strcmp(regs[n], r) == 0) -+ break; -+ } -+ } -+ cs->ls[i].selected = n; -+ ScrollToCurrent(&cs->ls[i]); -+ } -+ csRedraw(cs); -+ for (i = 0; i < TV_ML_NLISTS; i++) -+ csListRedraw(&cs->ls[i]); -+} -+ -+static void csRedraw(cs) -+ CSINFO *cs; -+{ -+ int i; -+ -+ XSetForeground(theDisp, theGC, infofg); -+ DrawString(cs->win, 5,5 + ASCENT, "Initial States"); -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ int x, y; -+ char buf[80]; -+ -+ if (i / 2 == 0) -+ x = 15; -+ else -+ x = 280; -+ if (i % 2 == 0) -+ y = 5 + LINEHIGH * 1; -+ else -+ y = 5 + LINEHIGH * 7 + SPACING * 3; -+ -+ sprintf(buf, "Designation for G%d:", i); -+ DrawString(cs->win, x, y + ASCENT, buf); -+ } -+ -+ DrawString(cs->win, 15, 235 + ASCENT, "Invocation for GL:"); -+ DrawString(cs->win, 280, 235 + ASCENT, "Invocation for GR:"); -+ DrawString(cs->win, 5, 280 + ASCENT, "Ret Code:"); -+ DrawString(cs->win, 350, 280 + ASCENT, "Converter:"); -+ -+ for (i = 0; i < TV_ML_NBUTTS; i++) -+ BTRedraw(&cs->bt[i]); -+ for (i = 0; i < TV_ML_NCBUTTS; i++) -+ CBRedraw(&cs->cbt[i]); -+ for (i = 0; i < TV_ML_NRBUTTS; i++) -+ RBRedraw(cs->rbt[i], -1); -+} -+ -+static void csListRedraw(ls) -+ LIST *ls; -+{ -+ int i; -+ for (i = 0; i < TV_ML_NLISTS; i++) { -+ LSRedraw(ls, 0); -+ SCRedraw(&ls->scrl); -+ } -+} -+ -+static void csLsRedraw(delta, sptr) -+ int delta; -+ SCRL *sptr; -+{ -+ int i, j; -+ for (i = 0; i < MAXTVWIN; i++) { -+ for (j = 0; j < TV_ML_NLISTS; j++) { -+ if (sptr == &csinfo[i].ls[j].scrl) { -+ LSRedraw(&csinfo[i].ls[j], delta); -+ return; -+ } -+ } -+ } -+} -+ -+int CharsetDelWin(win) -+ Window win; -+{ -+ CSINFO *cs; -+ int i; -+ -+ for (cs = csinfo, i = 0; i < TV_NCSS; cs++, i++) { -+ if (cs->win == win) { -+ if (cs->up) { -+ XUnmapWindow(theDisp, cs->win); -+ cs->up = 0; -+ } -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static int reg_comp PARM((const void *, const void *)); -+static void create_registry_list() -+{ -+ struct design d; -+ char *names, *p; -+ int i; -+ -+ if ((p = names = (char *) malloc(32 * 0x80 * 2 * 2)) == NULL) -+ FatalError("out of memory in create_name_list#1."); -+ nregs = 0; -+ for (d.bpc = 1; d.bpc <=2; d.bpc++) { -+ for (d.noc = 94; d.noc <= 96; d.noc += 2) { -+ for (d.des = ' '; (unsigned char) d.des < 0x80; d.des++) { -+ int b7; -+ char *r; -+ if ((r = lookup_registry(d, &b7)) != NULL) { -+ sprintf(p, "%s/%s", r, b7 ? "Right" : "Left"); -+ p += strlen(p) + 1; -+ nregs++; -+ } -+ } -+ } -+ } -+ if ((names = (char *) realloc(names, (size_t) (p - names))) == NULL) -+ FatalError("out of memory in create_name_list#2."); -+ if ((regs = (char **) malloc(sizeof(char *) * (nregs + 3))) == NULL) -+ FatalError("out of memory in create_name_list#3."); -+ p = names; -+ for (i = 0; i < nregs; i++) { -+ regs[i] = p; -+ p += strlen(p) + 1; -+ } -+ qsort(regs, (size_t) nregs, sizeof(char *), reg_comp); -+ regs[i++] = "nothing"; -+ regs[i++] = "unused"; -+ regs[i++] = NULL; -+} -+static int reg_comp(dst, src) -+ const void *dst, *src; -+{ -+ return strcmp(*(char **) dst, *(char **) src); -+} - -+#endif /* TV_MULTILINGUAL */ -diff -ruN xv-3.10a-bugfixes/xvtiff.c xv-3.10a-enhancements/xvtiff.c ---- xv-3.10a-bugfixes/xvtiff.c 2005-03-27 17:25:31.000000000 -0800 -+++ xv-3.10a-enhancements/xvtiff.c 2005-04-17 14:11:55.000000000 -0700 -@@ -512,7 +512,7 @@ - vsprintf(cp, fmt, ap); - strcat(cp, "."); - -- SetISTR(ISTR_WARNING,buf); -+ SetISTR(ISTR_WARNING, "%s", buf); - - error_occurred = 1; - } -@@ -536,7 +536,7 @@ - vsprintf(cp, fmt, ap); - strcat(cp, "."); - -- SetISTR(ISTR_WARNING,buf); -+ SetISTR(ISTR_WARNING, "%s", buf); - } - - -@@ -564,6 +564,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)); - -@@ -603,7 +607,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 *, -@@ -653,7 +657,7 @@ - - default: - TIFFError(TIFFFileName(tif), -- "Sorry, can not handle %d-bit pictures", bitspersample); -+ "Sorry, cannot handle %d-bit pictures", bitspersample); - return (0); - } - -@@ -666,7 +670,7 @@ - - default: - TIFFError(TIFFFileName(tif), -- "Sorry, can not handle %d-channel images", samplesperpixel); -+ "Sorry, cannot handle %d-channel images", samplesperpixel); - return (0); - } - -@@ -1157,7 +1161,7 @@ - b = g + stripsize; - put = pickTileSeparateCase(Map); - if (put == 0) { -- TIFFError(filename, "Can not handle format"); -+ TIFFError(filename, "Cannot handle format"); - return (0); - } - y = setorientation(tif, h); -@@ -1197,7 +1201,7 @@ - /* - * Greyscale images with less than 8 bits/sample are handled - * with a table to avoid lots of shifts and masks. The table -- * is setup so that put*bwtile (below) can retrieve 8/bitspersample -+ * is set up so that put*bwtile (below) can retrieve 8/bitspersample - * pixel values simply by indexing into the table with one - * number. - */ -@@ -1249,11 +1253,11 @@ - - - /* -- * Palette images with <= 8 bits/sample are handled -- * with a table to avoid lots of shifts and masks. The table -- * is setup so that put*cmaptile (below) can retrieve 8/bitspersample -- * pixel values simply by indexing into the table with one -- * number. -+ * Palette images with <= 8 bits/sample are handled with -+ * a table to avoid lots of shifts and masks. The table -+ * is set up so that put*cmaptile (below) can retrieve -+ * (8/bitspersample) pixel-values simply by indexing into -+ * the table with one number. - */ - static int makecmap() - { -@@ -1305,7 +1309,7 @@ - /* - * The following routines move decoded data returned - * from the TIFF library into rasters filled with packed -- * ABGR pixels (i.e. suitable for passing to lrecwrite.) -+ * ABGR pixels (i.e., suitable for passing to lrecwrite.) - * - * The routines have been created according to the most - * important cases and optimized. pickTileContigCase and -@@ -1376,7 +1380,7 @@ - int fromskew, toskew; - { - while (h-- > 0) { -- UNROLL8(w, , *cp++ = PALmap[*pp++][0]) -+ UNROLL8(w, , *cp++ = PALmap[*pp++][0]); - cp += toskew; - pp += fromskew; - } -@@ -1529,7 +1533,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; -@@ -1538,8 +1542,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; -@@ -1577,7 +1580,7 @@ - *cp++ = pp[0]; - *cp++ = pp[1]; - *cp++ = pp[2]; -- pp += samplesperpixel) -+ pp += samplesperpixel); - cp += toskew; - pp += fromskew; - } -@@ -1650,7 +1653,7 @@ - *cp++ = *r++; - *cp++ = *g++; - *cp++ = *b++; -- ) -+ ); - SKEW(r, g, b, fromskew); - cp += toskew; - } -@@ -1857,7 +1860,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; -@@ -1872,7 +1875,7 @@ - break; - } - -- if (put==0) TIFFError(filename, "Can not handle format"); -+ if (put==0) TIFFError(filename, "Cannot handle format"); - return (put); - } - -@@ -1880,8 +1883,8 @@ - /* - * Select the appropriate conversion routine for unpacked data. - * -- * NB: we assume that unpacked single channel data is directed -- * to the "packed routines. -+ * NB: we assume that unpacked single-channel data is directed -+ * to the "packed" routines. - */ - static tileSeparateRoutine pickTileSeparateCase(Map) - RGBvalue* Map; -@@ -1897,10 +1900,32 @@ - break; - } - -- if (put==0) TIFFError(filename, "Can not handle format"); -+ if (put==0) TIFFError(filename, "Cannot handle format"); - return (put); - } - - - -+/*******************************************/ -+void -+VersionInfoTIFF() /* GRR 19980605 */ -+{ -+ char temp[1024], *p, *q; -+ -+ strcpy(temp, TIFFGetVersion()); -+ p = temp; -+ while (!isdigit(*p)) -+ ++p; -+ if ((q = strchr(p, '\n')) != NULL) -+ *q = '\0'; -+ -+ fprintf(stderr, " Compiled with libtiff %s", p); -+#ifdef TIFFLIB_VERSION -+ fprintf(stderr, " of %d", TIFFLIB_VERSION); /* e.g., 19960307 */ -+#endif -+ fprintf(stderr, ".\n"); -+} -+ -+ -+ - #endif /* HAVE_TIFF */ -diff -ruN xv-3.10a-bugfixes/xvtiffwr.c xv-3.10a-enhancements/xvtiffwr.c ---- xv-3.10a-bugfixes/xvtiffwr.c 2005-03-28 08:39:52.000000000 -0800 -+++ xv-3.10a-enhancements/xvtiffwr.c 2005-04-17 14:45:28.000000000 -0700 -@@ -86,6 +86,9 @@ - TIFFSetField(tif, TIFFTAG_GROUP3OPTIONS, - GROUP3OPT_2DENCODING+GROUP3OPT_FILLBITS); - -+ if (comp == COMPRESSION_LZW) -+ TIFFSetField(tif, TIFFTAG_PREDICTOR, 2); -+ - TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1); - TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); -diff -ruN xv-3.10a-bugfixes/xvvd.c xv-3.10a-enhancements/xvvd.c ---- xv-3.10a-bugfixes/xvvd.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvvd.c 2005-04-17 22:56:02.000000000 -0700 -@@ -0,0 +1,1101 @@ -+ -+/* -+ * xvvd.c - extract archived file automatically and regard it as a -+ * (virtual) directory. -+ */ -+ -+#define NEEDSDIR -+ -+#include "xv.h" -+ -+#ifdef AUTO_EXPAND -+ -+static void vd_Dirtovd PARM((char *)); -+static void vd_Vdtodir PARM((char *)); -+static int vd_Mkvdir PARM((char *)); -+static int vd_Rmvdir PARM((char *)); -+static int vd_Movevdir PARM((char *, char *)); -+static void vd_addvdtable PARM((char *)); -+static void vd_packvdtable PARM((void)); -+static int vd_recursive_mkdir PARM((char *)); -+static int vd_recursive_rmdir PARM((char *)); -+static void vd_optimize_path PARM((char *)); -+static int vd_ftype PARM((char *)); -+static int vd_compp PARM((char *, char *)); -+static int vd_UncompressFile PARM((char *, char *)); -+static int vd_tarc PARM((char *)); -+static u_int vd_tar_sumchk PARM((char *)); -+ -+#define VD_VDTABLESIZE 100 -+ -+#define VD_ERR -2 -+#define VD_UKN -1 -+ -+static char *ext_command[] = { -+/* KEEP 0 */ -+ NULL, -+#define VD_ARC 1 -+ "arc xo %s", -+#define VD_ARJ 2 -+ "unarj x %s", -+#define VD_LZH 3 -+ "lha -xf %s", -+#define VD_TAR 4 -+ "tar xvf %s", -+#define VD_ZIP 5 -+ "unzip -xo %s", -+#define VD_ZOO 6 -+ "zoo xOS %s", -+}; -+ -+int vdcount = 0; -+ -+static char vdroot[MAXPATHLEN+1]; -+static char *vdtable[VD_VDTABLESIZE]; -+ -+/* -+ * These functions initialize and settle virtual directory system. -+ * Vdinit: -+ * creates root of virtual directory. -+ * Vdsettle: -+ * sweeps virtual directories. -+ */ -+void Vdinit() -+{ -+#ifndef VMS -+ char tmp[MAXPATHLEN+1]; -+ -+ xv_getwd(tmp, MAXPATHLEN+1); -+ if (chdir(tmpdir)) { -+ fprintf(stderr, "Warning: cannot chdir to tmpdir = '%s'.\n", tmpdir); -+ fprintf(stderr, -+ " I will use current directory '%s' instead of tmpdir.\n", -+ tmp); -+ } -+ xv_getwd(vdroot, MAXPATHLEN+1); -+ strcat(vdroot, "/.xvvdXXXXXX"); -+ chdir(tmp); -+#else -+ sprintf(vdroot, "Sys$Scratch:xvvdXXXXXX"); -+#endif /* VMS */ -+#ifdef USE_MKSTEMP -+ close(mkstemp(vdroot)); -+#else -+ mktemp(vdroot); -+#endif -+ -+ if (!vd_recursive_mkdir(vdroot)) -+ tmpdir = vdroot; -+} -+ -+void Vdsettle() -+{ -+ int i; -+ -+ for (i = 0; i < vdcount; i++) -+ free(vdtable[i]); -+ -+ vdcount = 0; -+ -+ vd_recursive_rmdir(vdroot); -+} -+ -+/* -+ * This function chdir to virtual directory, if specified path is in -+ * virtual directlry. -+ */ -+int Chvdir(dir) -+char *dir; -+{ -+ char buf[MAXPATHLEN+1]; -+ -+ if (Mkvdir(dir) == VD_ERR) -+ return -1; -+ -+ strcpy(buf, dir); -+ Dirtovd(buf); -+ -+ return (chdir(buf)); -+} -+ -+/* -+ * These functions convert directory <-> virtual directory. -+ * Dirtovd: -+ * front interface of vd_Dirtovd. -+ * vd_Dirtovd: -+ * converts directory to virtual directory. -+ * Vdtodir: -+ * front interface of vd_Vdtodir. -+ * vd_Vdtodir: -+ * converts virtual directory to normal directory. -+ * Dirtosubst: -+ * converts directory to substance of archive. -+ */ -+void Dirtovd(dir) -+char *dir; -+{ -+ vd_optimize_path(dir); -+ -+ vd_Dirtovd(dir); -+} -+ -+static void vd_Dirtovd(dir) -+char *dir; -+{ -+ int i; -+ -+ for (i = 0; i < vdcount; i++) -+ if (!strncmp(dir, vdtable[i], strlen(vdtable[i]))) { -+ char tmp[MAXPATHLEN+1]; -+ -+ sprintf(tmp, "%s%s", vdroot, dir); -+ strcpy(dir, tmp); -+ Dirtovd(dir); -+ } -+} -+ -+void Vdtodir(dir) -+char *dir; -+{ -+ vd_optimize_path(dir); -+ -+ vd_Vdtodir(dir); -+} -+ -+static void vd_Vdtodir(vd) -+char *vd; -+{ -+ int i; -+ char tmp[MAXPATHLEN+1]; -+ -+ for (i = vdcount-1; i >= 0; i--) { -+ sprintf(tmp, "%s%s", vdroot, vdtable[i]); -+ if(!strncmp(vd, tmp, strlen(tmp))) { -+ strcpy(tmp, vd+strlen(vdroot)); -+ strcpy(vd, tmp); -+ Vdtodir(vd); -+ } -+ } -+} -+ -+void Dirtosubst(dir) -+char *dir; -+{ -+ char tmp[MAXPATHLEN+1]; -+ -+ Dirtovd(dir); -+ -+ strcpy(tmp, dir+strlen(vdroot)); -+ -+ if (Isarchive(tmp)) -+ strcpy(dir, tmp); -+} -+ -+/* -+ * These functions make virtual directory and extracts archive, if -+ * specified path is archive. -+ * Mkvdir: -+ * front interface of vd_Mkvdir. -+ * vd_Mkvdir: -+ * does real work. -+ * Mkvdir_force: (used by makeThumbDir(in xvbrowse.c) only) -+ * make virtual directory by force. -+ */ -+int Mkvdir(dir) -+char *dir; -+{ -+ char dir1[MAXPATHLEN+1], dir2[MAXPATHLEN+1]; -+ char *d1, *d2; -+ int rv; -+ -+#if defined(SYSV) || defined(SVR4) || defined(__USE_XOPEN_EXTENDED) -+ sighold(SIGHUP); -+ sighold(SIGCHLD); -+#else -+ int mask; -+ mask = sigblock(sigmask(SIGHUP)|sigmask(SIGCHLD)); -+#endif -+ -+ strcpy(dir1, dir); -+ vd_optimize_path(dir1); -+ -+ if ((rv = vd_Mkvdir(dir1)) != VD_ERR) -+ goto MKVDIR_END; -+ -+ strcpy(dir2, dir1); -+ d2 = dir2 + strlen(dir2); -+ while (rv == VD_ERR) { -+ d2--; -+ while (*d2 != '/') -+ d2--; -+ *d2 = '\0'; -+ rv = vd_Mkvdir(dir2); -+ } -+ d1 = dir1 + strlen(dir2); -+ while ((rv != VD_ERR) && (*d1 != '\0')) { -+ *d2++ = *d1++; -+ while ((*d1 != '/') && (*d1 != '\0')) -+ *d2++ = *d1++; -+ *d2 = '\0'; -+ rv = vd_Mkvdir(dir2); -+ } -+ -+MKVDIR_END: -+#if defined(SYSV) || defined(SVR4) || defined(__USE_XOPEN_EXTENDED) -+ sigrelse(SIGHUP); -+ sigrelse(SIGCHLD); -+#else -+ sigsetmask(mask); -+#endif -+ -+ return rv; -+} -+ -+static int vd_Mkvdir(dir) -+char *dir; -+{ -+ char dir1[MAXPATHLEN+1], dir2[MAXPATHLEN+1], tmp[MAXPATHLEN+1]; -+ int ftype, i; -+ struct stat st; -+ FILE *pfp; -+ -+ strcpy(dir1, dir); -+ Dirtovd(dir1); -+ strcpy(dir2, dir1); -+ -+ WaitCursor(); -+ -+ if ((ftype = vd_ftype(dir1)) < 0) { -+ SetCursors(-1); -+ return ftype; -+ } -+ if (ftype == RFT_COMPRESS) { -+ if (!(ftype = vd_compp(dir1, tmp))) { -+ SetCursors(-1); -+ return ftype; -+ } -+ strcpy(dir1, tmp); -+ } -+ -+ if (!stat(dir1, &st)) { -+ for(i = 0; i < vdcount; i++) -+ if (!strcmp(vdtable[i], dir2)) { -+ SetCursors(-1); -+ return 0; -+ } -+ -+ if (!S_ISDIR(st.st_mode)) { -+ char origdir[MAXPATHLEN+1], buf[MAXPATHLEN+10], buf1[100]; -+ -+ if (vdcount >= VD_VDTABLESIZE) { -+ ErrPopUp("Sorry, you can't make virtual directory any more.", -+ "\nBummer!"); -+ goto VD_MKVDIR_ERR; -+ } -+ -+ WaitCursor(); -+ -+ xv_getwd(origdir, MAXPATHLEN+1); -+ -+ sprintf(tmp, "%s%s", vdroot, dir2); -+ if (vd_recursive_mkdir(tmp) || chdir(tmp)) { -+ SetISTR(ISTR_INFO, "fail to make virtual directory."); -+ Warning(); -+ goto VD_MKVDIR_ERR; -+ } -+ sprintf(buf, ext_command[ftype], dir1); -+ -+ WaitCursor(); -+ -+ if((pfp = popen(buf, "r")) == NULL) { -+ SetISTR(ISTR_INFO, "fail to extract archive '%s'.", -+ BaseName(dir2)); -+ Warning(); -+ goto VD_MKVDIR_ERR; -+ } -+ while (1) { -+ if (fread(buf1, 1, sizeof(buf1), pfp) < sizeof(buf1)) -+ break; -+ WaitCursor(); -+ } -+ if (!feof(pfp)) { -+ SetISTR(ISTR_INFO, "Pipe was broken."); -+ Warning(); -+ pclose(pfp); -+ goto VD_MKVDIR_ERR; -+ } -+ pclose(pfp); -+ -+ if (strcmp(dir1, dir2)) -+ unlink(dir1); -+ -+ vd_addvdtable(dir2); -+ Dirtovd(origdir); -+ chdir(origdir); -+ SetCursors(-1); -+ return 0; -+ -+VD_MKVDIR_ERR: -+ if (strcmp(dir1, dir2)) -+ unlink(dir1); -+ SetCursors(-1); -+ return VD_ERR; -+ } -+ } -+ SetCursors(-1); -+ return VD_ERR; -+} -+ -+#ifdef VIRTUAL_TD -+void Mkvdir_force(dir) -+char *dir; -+{ -+ char tmp[MAXPATHLEN+1]; -+ -+ if (vdcount >= VD_VDTABLESIZE) { -+ ErrPopUp("Sorry, you can't make virtual directory any more.", -+ "\nBummer!"); -+ return; -+ } -+ -+ sprintf(tmp, "%s%s", vdroot, dir); -+ if (vd_recursive_mkdir(tmp)) { -+ SetISTR(ISTR_INFO, "Failed to make virtual directory."); -+ Warning(); -+ return; -+ } -+ -+ vd_addvdtable(dir); -+} -+#endif /* VIRTUAL_TD */ -+ -+/* -+ * These functions remove virtual directory, if exists. -+ * Rmvdir: -+ * front interface of vd_Rmvdir. -+ * vd_Rmvdir: -+ * remove virtual directory function. -+ */ -+int Rmvdir(dir) -+char *dir; -+{ -+ int rv; -+ char buf[MAXPATHLEN+1]; -+ -+ strcpy(buf, dir); -+ vd_optimize_path(buf); -+ -+ rv = vd_Rmvdir(buf); -+ vd_packvdtable(); -+ return rv; -+} -+ -+static int vd_Rmvdir(dir) -+char *dir; -+{ -+ int i; -+ char tmp[MAXPATHLEN+1]; -+ -+ for(i = 0; i < vdcount; i++) -+ if (!strncmp(dir, vdtable[i], strlen(dir))) { -+ sprintf(tmp, "%s%s", vdroot, vdtable[i]); -+ if (vd_Rmvdir(tmp)) -+ return 1; -+ if (vd_recursive_rmdir(tmp)) -+ return 1; -+ vdtable[i][0] = '\0'; -+ } -+ return 0; -+} -+ -+/* -+ * These functions move virtual directory, if exists. -+ * Movevdir: -+ * front interface of move virtual directory function. -+ * vd_Movevdir: -+ * does real work. -+ */ -+int Movevdir(src, dst) -+char *src, *dst; -+{ -+/* -+ char sbuf[MAXPATHLEN+1], dbuf[MAXPATHLEN+1]; -+ -+ strcpy(sbuf, src); -+ vd_optimize_path(sbuf); -+ -+ strcpy(dbuf, dst); -+ vd_optimize_path(dbuf); -+ -+ return (vd_Movevdir(sbuf, dbuf)); -+*/ -+ return (vd_Movevdir(src, dst)); -+} -+ -+static int vd_Movevdir(src, dst) -+char *src, *dst; -+{ -+ int i; -+ char *p, *pp; -+ char tmp[MAXPATHLEN+1], tmps[MAXPATHLEN+1], tmpd[MAXPATHLEN+1]; -+ -+ for (i = 0; i < vdcount; i++) -+ if (!strncmp(src, vdtable[i], strlen(src))) { -+ sprintf(tmps, "%s%s", vdroot, vdtable[i]); -+ sprintf(tmp, "%s%s", dst, vdtable[i]+strlen(src)); -+ sprintf(tmpd, "%s%s", vdroot, tmp); -+ -+ if (vd_Movevdir(tmps, tmpd)) -+ return 1; -+ -+ pp = vdtable[i]; -+ p = (char *) malloc(strlen(tmp)+1); -+ strcpy(p, tmp); -+ vdtable[i] = p; -+ -+ strcpy(tmp, tmpd); -+ for (p = tmp+strlen(tmp); *p != '/'; p--) -+ ; -+ *p = '\0'; -+ -+ if (vd_recursive_mkdir(tmp)) -+ goto VD_MOVEVDIR_ERR; -+ -+ if (rename(tmps, tmpd) < 0) -+ goto VD_MOVEVDIR_ERR; -+ -+ free(pp); -+ } -+ return 0; -+ -+VD_MOVEVDIR_ERR: -+ free(vdtable[i]); -+ vdtable[i] = pp; -+ return 1; -+} -+ -+/* -+ * These functions handle table of virtual directories. -+ * vd_addvdtable: -+ * adds virtual directory to table. -+ * vd_packvdtable: -+ * removes disused virtual directories from table. -+ */ -+static void vd_addvdtable(vd) -+char *vd; -+{ -+ char *p; -+ p = (char *) malloc(strlen(vd)+1); -+ strcpy(p, vd); -+ vdtable[vdcount] = p; -+ vdcount++; -+} -+ -+static void vd_packvdtable() -+{ -+ int i, j; -+ -+ for (i = j = 0; i < vdcount; i++) -+ if (vdtable[i][0] != '\0') -+ vdtable[j++] = vdtable[i]; -+ else -+ free(vdtable[i]); -+ -+ vdcount = j; -+} -+ -+/* -+ * These are utility functions. -+ * vd_recursive_mkdir: -+ * makes directories recursively. -+ * vd_recursive_rmdir -+ * removes directories recursively. -+ */ -+static int vd_recursive_mkdir(dir) -+char *dir; -+{ -+ char buf[MAXPATHLEN+1], *p; -+ struct stat st; -+ -+ strcpy(buf, dir); -+ -+ if (buf[strlen(buf) - 1] == '/') -+ buf[strlen(buf) - 1] = '\0'; -+ -+ p = rindex(buf, '/'); -+ *p = '\0'; -+ -+ if (stat(buf, &st) < 0) -+ if (vd_recursive_mkdir(buf) < 0) -+ return (-1); -+ -+ *p = '/'; -+ if (mkdir(buf, 0700) < 0) -+ return (-1); -+ -+ return (0); -+} -+ -+static int vd_recursive_rmdir(dir) -+char *dir; -+{ -+ char buf[MAXPATHLEN+1], buf2[MAXPATHLEN+1]; -+ DIR *dp; -+ struct dirent *di; -+ -+ strcpy(buf, dir); -+ -+ if (buf[strlen(buf) - 1] == '/') -+ buf[strlen(buf) - 1] = '\0'; -+ -+ if ((dp = opendir(buf)) == NULL) -+ return (-1); -+ -+ while ((di = readdir(dp)) != NULL) { -+ struct stat st; -+ -+ if (!strcmp(di->d_name, ".") || !strcmp(di->d_name, "..")) -+ continue; -+ -+ sprintf(buf2, "%s/%s", dir, di->d_name); -+ -+ stat(buf2, &st); -+ if (S_ISDIR(st.st_mode)) { -+ if (vd_recursive_rmdir(buf2) < 0) -+ goto VD_RECURSIVE_RMDIR_ERR; -+ } else -+ unlink(buf2); -+ } -+ if (rmdir(buf) < 0) -+ goto VD_RECURSIVE_RMDIR_ERR; -+ -+ closedir(dp); -+ return (0); -+ -+VD_RECURSIVE_RMDIR_ERR: -+ closedir(dp); -+ return (-1); -+} -+ -+/* -+ * These functions test specified path. -+ * Isarchive: -+ * tests whether it's an archive? -+ * Isvdir: -+ * tests whether it's in the virtual directory? -+ */ -+int Isarchive(path) -+char *path; -+{ -+ int ftype; -+ -+ if ((ftype = vd_ftype(path)) < 0) -+ return 0; -+ -+ if (ftype == RFT_COMPRESS) -+ if (!(ftype = vd_compp(path, NULL))) -+ return 0; -+ -+ return ftype; -+} -+ -+int Isvdir(path) -+char *path; -+{ -+ int rv = 0; -+ char tmp1[MAXPATHLEN+1], tmp2[MAXPATHLEN+1]; -+ int archive1, archive2; -+ -+ strcpy(tmp1, path); -+ strcpy(tmp2, path); -+ -+ vd_optimize_path(tmp1); -+ Dirtovd(tmp2); -+ -+ archive1 = Isarchive(tmp1); -+ archive2 = Isarchive(tmp2); -+ -+ if (strcmp(tmp1, tmp2)) { -+ char tmp3[MAXPATHLEN+1], tmp4[MAXPATHLEN+1]; -+ int archive3, archive4; -+ -+ sprintf(tmp3, "%s%s", vdroot, tmp1); -+ strcpy(tmp4, tmp2+strlen(vdroot)); -+ -+ archive3 = Isarchive(tmp3); -+ archive4 = Isarchive(tmp4); -+ -+ if (archive4 && !strcmp(tmp1, tmp4)) { -+ rv |= 06; -+ return rv; -+ } -+ rv |= 01; -+ if (archive2) -+ rv |= 02; -+ else if (archive4) -+ rv |= 06; -+ return rv; -+ } -+ if (archive1) -+ rv |= 02; -+ -+ return rv; -+} -+ -+/* -+ * This function optimizes given path. -+ * Expand '~' to home directory and removes '.', and treat '..'. -+ */ -+static void vd_optimize_path(path) -+char *path; -+{ -+ char *tmp, *reserve; -+ -+ if (!strcmp(path, STDINSTR)) -+ return; -+ -+ if (*path == '\0') { -+ xv_getwd(path, MAXPATHLEN+1); -+ return; -+ } -+ if (*path == '~') -+ Globify(path); -+ if (*path != '/') { -+ char tmp[MAXPATHLEN+1]; -+ -+ strcpy(tmp, path); -+ xv_getwd(path, MAXPATHLEN+1); -+ strcat(path, "/"); -+ strcat(path, tmp); -+ } -+ -+ reserve = tmp = path; -+ while(*path != '\0') { -+ if (*path == '/') { -+ *tmp++ = *path; -+ while (*++path == '/') -+ ; -+ continue; -+ } -+ if ((*path == '.') && (*(path-1) == '/')) { -+ if (*(path+1) == '/') { -+ tmp--; -+ path++; -+ continue; -+ } else if (*(path+1) == '\0') { -+ tmp--; -+ break; -+ } else if (*(path+1) == '.') { -+ if (*(path+2) == '/') { -+ if ((tmp - reserve) > 1) -+ for (tmp-=2; (*tmp != '/'); tmp--) -+ ; -+ else -+ tmp = reserve; -+ path+=2; -+ continue; -+ } else if (*(path+2) == '\0') { -+ if ((tmp - reserve) > 1) -+ for (tmp-=2; (*tmp != '/'); tmp--) -+ ; -+ else -+ tmp = reserve+1; -+ break; -+ } -+ } -+ } -+ *tmp++ = *path++; -+ } -+ if (((tmp - reserve) > 1) && *(tmp-1) == '/') -+ tmp--; -+ if (tmp == reserve) -+ *tmp++ = '/'; -+ -+ *tmp = '\0'; -+} -+ -+/* -+ * These functions detect file type. -+ */ -+static int vd_ftype(fname) -+char *fname; -+{ -+ /* check archive type */ -+ -+ FILE *fp; -+ byte magicno[30]; /* first 30 bytes of file */ -+ int rv, n; -+ struct stat st; -+ -+ if (!fname) return VD_ERR; /* shouldn't happen */ -+ -+ if ((!stat(fname, &st)) && (st.st_mode & S_IFMT) == S_IFDIR) -+ return VD_UKN; -+ fp = xv_fopen(fname, "r"); -+ if (!fp) return VD_ERR; -+ -+ n = fread(magicno, (size_t) 1, (size_t) 30, fp); -+ fclose(fp); -+ -+ if (n<30) return VD_UKN; /* files less than 30 bytes long... */ -+ -+ rv = VD_UKN; -+ -+ if (magicno[0] == 0x60 && magicno[1]==0xea) rv = VD_ARJ; -+ -+ else if (magicno[2] == '-' && magicno[3] == 'l' && -+ magicno[4] == 'h') rv = VD_LZH; -+ -+ else if (strncmp((char *) magicno,"PK", (size_t) 2)==0) rv = VD_ZIP; -+ -+ else if (magicno[20]==0xdc && magicno[21]==0xa7 && -+ magicno[22]==0xc4 && magicno[23]==0xfd) rv = VD_ZOO; -+ -+ else if (vd_tarc(fname)) rv = VD_TAR; -+ -+ else if (magicno[0]==0x1f && magicno[1]==0x9d) rv = RFT_COMPRESS; -+ -+ else if (!strncmp((char *) &magicno[11], "MAJYO", (size_t) 5)) -+ rv = VD_UKN; /* XXX */ -+ -+ else if (magicno[0] == 26) rv = VD_ARC; -+ -+#ifdef GUNZIP -+ else if (magicno[0]==0x1f && magicno[1]==0x8b) rv = RFT_COMPRESS;/* gzip */ -+ else if (magicno[0]==0x1f && magicno[1]==0x9e) rv = RFT_COMPRESS;/* old */ -+ else if (magicno[0]==0x1f && magicno[1]==0x1e) rv = RFT_COMPRESS;/* pack */ -+#endif -+ -+ return rv; -+} -+ -+static int vd_compp(path, newpath) -+char *path, *newpath; -+{ -+ /* -+ * uncompress and check archive type. -+ * -+ * If newpath is NULL, uncompress only 512 byte of 'path' and -+ * check archive type, so it is for SPEED-UP strategy. -+ * In this case, caller this function does not have to unlink -+ * tempoary file. -+ * Unfortunately it does not work in VMS system. -+ */ -+ -+ int file_type, r; -+ char uncompname[128], basename[128]; -+ int comptype; -+ -+ if (newpath) *newpath = '\0'; -+ strncpy(basename, path, 127); -+ comptype = ReadFileType(path); -+#if (defined(VMS) && !defined(GUNZIP)) -+ /* VMS decompress doesn't like the file to have a trailing .Z in fname -+ however, GUnZip is OK with it, which we are calling UnCompress */ -+ *rindex (basename, '.') = '\0'; -+#endif -+#ifdef VMS -+ if (UncompressFile(basename, uncompname)) { -+#else -+ if (newpath == NULL) -+ r = vd_UncompressFile(basename, uncompname); -+ else -+ r = UncompressFile(basename, uncompname, comptype); -+ if (r) { -+#endif -+ if ((file_type = vd_ftype(uncompname)) < 0) { -+ unlink(uncompname); -+ return 0; -+ } -+ if (newpath) strcpy(newpath, uncompname); -+ else unlink(uncompname); -+ } else { -+ return 0; -+ } -+ return file_type; -+} -+ -+#define HEADERSIZE 512 -+ -+static void vd_Dirtovd PARM((char *)); -+static int stderr_on PARM((void)); -+static int stderr_off PARM((void)); -+static FILE *popen_nul PARM((char *, char *)); -+ -+static int vd_UncompressFile(name, uncompname) -+char *name, *uncompname; -+{ -+ /* Yap, I`m nearly same as original `UncompnameFile' function, but, -+ 1) I extract `name' file ONLY first 512 byte. -+ 2) I'm called only from UNIX and UNIX like OS, *NOT* VMS */ -+ /* returns '1' on success, with name of uncompressed file in uncompname -+ returns '0' on failure */ -+ -+ char namez[128], *fname, buf[512], tmp[HEADERSIZE]; -+ int n, tmpfd; -+ FILE *pfp, *tfp; -+ -+ fname = name; -+ namez[0] = '\0'; -+ -+ -+#ifndef GUNZIP -+ /* see if compressed file name ends with '.Z'. If it *doesn't*, we need -+ to temporarily rename it so it *does*, uncompress it, and rename it -+ *back* to what it was. necessary because uncompress doesn't handle -+ files that don't end with '.Z' */ -+ -+ if (strlen(name) >= (size_t) 2 && -+ strcmp(name + strlen(name)-2,".Z")!=0 && -+ strcmp(name + strlen(name)-2,".z")!=0) { -+ strcpy(namez, name); -+ strcat(namez,".Z"); -+ -+ if (rename(name, namez) < 0) { -+ sprintf(buf, "Error renaming '%s' to '%s': %s", -+ name, namez, ERRSTR(errno)); -+ ErrPopUp(buf, "\nBummer!"); -+ return 0; -+ } -+ -+ fname = namez; -+ } -+#endif /* not GUNZIP */ -+ -+ sprintf(uncompname, "%s/xvuXXXXXX", tmpdir); -+#ifdef USE_MKSTEMP -+ tmpfd = mkstemp(uncompname); -+#else -+ mktemp(uncompname); -+#endif -+ -+ sprintf(buf,"%s -c %s", UNCOMPRESS, fname); -+ SetISTR(ISTR_INFO, "Uncompressing Header '%s'...", BaseName(fname)); -+ if ((pfp = popen_nul(buf, "r")) == NULL) { -+ SetISTR(ISTR_INFO, "Cannot extract for archive '%s'.", -+ BaseName(fname)); -+ Warning(); -+#ifdef USE_MKSTEMP -+ if (tmpfd >= 0) -+ close(tmpfd); -+#endif -+ return 0; -+ } -+#ifdef USE_MKSTEMP -+ if (tmpfd < 0) -+#else -+ if ((tmpfd = open(uncompname,O_WRONLY|O_CREAT|O_EXCL,S_IRWUSR)) < 0) -+#endif -+ { -+ SetISTR(ISTR_INFO, "Unable to create temporary file.", -+ BaseName(uncompname)); -+ Warning(); -+ pclose(pfp); -+ } -+ if ((tfp = fdopen(tmpfd, "w")) == NULL) { -+ SetISTR(ISTR_INFO, "Unable to create temporary file.", -+ BaseName(uncompname)); -+ Warning(); -+ close(tmpfd); -+ pclose(pfp); -+ return 0; -+ } -+ if ((n = fread(tmp, 1, sizeof(tmp), pfp)) != HEADERSIZE) { -+ SetISTR(ISTR_INFO, "Unable to read '%s'.", -+ BaseName(fname)); -+ Warning(); -+ pclose(pfp); -+ fflush(tfp); -+ fclose(tfp); -+ close(tmpfd); -+ return 0; -+ } -+ fwrite(tmp, 1, n, tfp); -+ fflush(tfp); -+ fclose(tfp); -+ close(tmpfd); -+ pclose(pfp); -+ -+ /* if we renamed the file to end with a .Z for the sake of 'uncompress', -+ rename it back to what it once was... */ -+ -+ if (strlen(namez)) { -+ if (rename(namez, name) < 0) { -+ sprintf(buf, "Error renaming '%s' to '%s': %s", -+ namez, name, ERRSTR(errno)); -+ ErrPopUp(buf, "\nBummer!"); -+ } -+ } -+ -+ return 1; -+} -+ -+#define TARBLOCK 512 -+#define CKSTART 148 /* XXX */ -+#define CKSIZE 8 -+ -+/* -+ * Tar file: 1, other: 0 -+ */ -+static int vd_tarc(fname) -+char *fname; -+{ -+ FILE *fp; -+ unsigned int sum; -+ char *ckp, buf[TARBLOCK]; -+ -+ if ((fp = fopen(fname, "r")) == NULL) -+ return 0; -+ -+ fread(buf, TARBLOCK, 1, fp); -+ fclose(fp); -+ -+ for (sum = 0, ckp = buf + CKSTART; -+ (ckp < buf + CKSTART + CKSIZE) && *ckp != '\0'; -+ ckp++) { -+ sum *= 8; -+ if (*ckp == ' ') -+ continue; -+ if (*ckp < '0' || '7' < *ckp) -+ return 0; -+ sum += *ckp - '0'; -+ } -+ if (sum != vd_tar_sumchk(buf)) -+ return 0; -+ -+ return 1; -+} -+ -+static unsigned int vd_tar_sumchk(buf) -+char *buf; -+{ -+ int i; -+ unsigned int sum = 0; -+ -+ for (i = 0; i < CKSTART; i++) { -+ sum += *(buf + i); -+ } -+ sum += ' ' * 8; -+ for (i += 8; i < TARBLOCK; i++) { -+ sum += *(buf + i); -+ } -+ return sum; -+} -+ -+ -+static int stde = -1; /* fd of stderr */ -+static int nul = -1; /* fd of /dev/null */ -+ -+/* -+ * switch off the output to stderr(bypass to /dev/null). -+ */ -+static int stderr_off() -+{ -+ if (nul < 0) -+ nul = open("/dev/null", O_RDONLY); -+ if (nul < 0) { -+ fprintf(stderr, "/dev/null open failure\n"); -+ return -1; -+ } -+ if (stde < 0) -+ stde = dup(2); -+ if (stde < 0) { -+ fprintf(stderr, "duplicate stderr failure\n"); -+ return -1; -+ } -+ close(2); -+ dup(nul); -+ return 0; -+} -+ -+/* -+ * turn on stderr output. -+ */ -+static int stderr_on() -+{ -+ if ((stde < 0) || (nul < 0)) { -+ fprintf(stderr, "stderr_on should call after stderr_off\n"); -+ return -1; -+ } -+ close(2); -+ dup(stde); -+ return 0; -+} -+ -+/* -+ * popen with no output to stderr. -+ */ -+static FILE *popen_nul(prog, mode) -+char *prog, *mode; -+{ -+ FILE *fp; -+ -+ stderr_off(); -+ fp = popen(prog, mode); -+ stderr_on(); -+ return fp; -+} -+ -+/* -+ * These functions are for SIGNAL. -+ * If XV end by C-c, there are dust of directory which name is .xvvd???, -+ * made by xvvd. Then, I handle SIGINT, and add good finish. -+ */ -+void vd_HUPhandler() -+{ -+#if defined(SYSV) || defined(SVR4) || defined(__USE_XOPEN_EXTENDED) -+ sighold(SIGHUP); -+#else -+ int mask; -+ mask = sigblock(sigmask(SIGHUP)); -+#endif -+ -+ Vdsettle(); -+ -+#if defined(SYSV) || defined(SVR4) || defined(__USE_XOPEN_EXTENDED) -+ sigrelse(SIGHUP); -+ signal(SIGHUP, (void (*)PARM((int))) vd_HUPhandler); -+#else -+ sigsetmask(mask); -+#endif -+} -+ -+void vd_handler(sig) -+int sig; -+{ -+#if defined(SYSV) || defined(SVR4) || defined(__USE_XOPEN_EXTENDED) -+ sighold(sig); -+#else -+ sigblock(sigmask(sig)); -+#endif -+ -+ Quit(1); /*exit(1);*/ -+} -+ -+int vd_Xhandler(disp,event) -+Display *disp; -+XErrorEvent *event; -+{ -+ Quit(1); /*exit(1);*/ -+ return (1); /* Not reached */ -+} -+ -+int vd_XIOhandler(disp) -+Display *disp; -+{ -+ fprintf(stderr, "XIO fatal IO error ? (?) on X server\n"); -+ fprintf(stderr, "You must exit normally in xv usage.\n"); -+ Quit(1); /*exit(1);*/ -+ return (1); /* Not reached */ -+} -+ -+void vd_handler_setup() -+{ -+ signal(SIGHUP, (void (*)PARM((int))) vd_HUPhandler); -+ signal(SIGINT, (void (*)PARM((int))) vd_handler); -+ signal(SIGTERM,(void (*)PARM((int))) vd_handler); -+ -+ (void)XSetErrorHandler(vd_Xhandler); -+ (void)XSetIOErrorHandler(vd_XIOhandler); -+} -+#endif /* AUTO_EXPAND */ -diff -ruN xv-3.10a-bugfixes/xvwbmp.c xv-3.10a-enhancements/xvwbmp.c ---- xv-3.10a-bugfixes/xvwbmp.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvwbmp.c 2005-04-03 14:02:18.000000000 -0700 -@@ -0,0 +1,323 @@ -+/* -+ * xvwbmp.c - i/o routings for WBMP files -+ * defined by OMA (http://www.openmobilealliance.com) -+ * as a standard for images for micro devices. -+ * -+ * exports : -+ * -+ * LoadWBMP(fname, numcols); -+ * WriteWBMP(fp, pic, ptype, w, h, r, g, b, numcols, style); -+ * -+ * author: Pawel S. Veselov <vps@manticore.2y.net> -+ * http://manticore.2y.net/ -+ * -+ */ -+ -+#include "xv.h" -+ -+typedef short int16; -+typedef unsigned char uint8; -+typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ -+#if defined(__alpha) || _MIPS_SZLONG == 64 -+typedef int int32; -+typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ -+#else -+typedef long int32; -+typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ -+#endif -+ -+#define MUST(a) if (!(a)) {\ -+ return fail(st_fname, st_err);\ -+ close(fd); \ -+ } -+#define READU8(fd,u) if ((read(fd, &u, 1)<1)) {\ -+ myfree(); \ -+ close(fd); \ -+ return fail(st_fname, err_ueof); } -+#define SREADU8(fd, u) if ((read(fd, &u, 1,)<1)) {\ -+ { st_err = err_ueof; return 0; } -+ -+#define SREADC(fd, str, l) { \ -+ str = (char*)mymalloc(l); \ -+ if (!str) { \ -+ myfree(); \ -+ FatalError("LoadWBMP: can't malloc extension buffer"); \ -+ } \ -+ if (read(fd, str, l)<l) { \ -+ st_err = err_ueof; \ -+ return 0; \ -+ } -+ -+static char * err_ueof = "Unexpected EOF"; -+static char * err_unst = "Unsupported image type"; -+static char * err_extf = "Extensions are forbidden"; -+static char * err_inmb = "Invalid multibyte integer"; -+ -+static char * st_fname; -+static char * st_err; -+ -+static int fail PARM((char *, char *)); -+static int read_mb PARM((int *, int)); -+static void write_mb PARM((uint32, FILE *)); -+static int read_ext PARM((int, uint8)); -+static void * mymalloc PARM((int)); -+static void myfree PARM((void)); -+static uint8 * render1 PARM((uint8 *, int, int)); -+ -+void ** mymem = NULL; -+int mymems = 0; -+ -+int LoadWBMP(char * fname, PICINFO * pinfo) -+{ -+ int fd; -+ int im_type; /* image type (only type 0 supported) */ -+ uint8 fix_header; /* fixed header field */ -+ int width, height; -+ int npixels, raw_size, aux; -+ uint8 * raw; -+ -+ st_fname = fname; -+ -+ fd = open(fname, O_RDONLY); -+ if (fd < 0) { -+ return fail(fname, "Couldn't open the file"); -+ } -+ -+ MUST(read_mb(&im_type, fd)); -+ if (im_type) { -+ return fail(fname, err_unst); -+ } -+ -+ READU8(fd, fix_header); -+ -+ MUST(read_ext(fd, fix_header)); -+ -+ MUST(read_mb(&width, fd)); -+ MUST(read_mb(&height, fd)); -+ -+ npixels = width * height; -+ raw_size = (npixels+7) / 8; -+ if (width <= 0 || height <= 0 || npixels/width != height || -+ npixels+7 < npixels) -+ { -+ return fail(fname, "image dimensions out of range"); -+ } -+ -+ raw = mymalloc(raw_size); -+ if (!raw) { -+ myfree(); -+ FatalError("LoadWBMP: can't malloc image buffer"); -+ } -+ -+ aux = read(fd, raw, raw_size); -+ if (aux < raw_size) { -+ fail(fname, "Image size shrank"); -+ raw_size = aux; -+ } -+ -+ pinfo->r[0] = 0; -+ pinfo->g[0] = 0; -+ pinfo->b[0] = 0; -+ pinfo->r[1] = 255; -+ pinfo->g[1] = 255; -+ pinfo->b[1] = 255; -+ -+ pinfo->pic = render1(raw, raw_size, npixels); -+ pinfo->type = PIC8; -+ -+ pinfo->w = pinfo->normw = width; -+ pinfo->h = pinfo->normh = height; -+ pinfo->frmType = F_BWDITHER; -+ -+ sprintf(pinfo->fullInfo, "WBMP, 1 bit per pixel, %d bytes", raw_size); -+ sprintf(pinfo->shrtInfo, "%dx%d WBMP (WAP/OMA).", width, height); -+ pinfo->comment = (char*)NULL; -+ -+ close(fd); -+ -+ myfree(); -+ return 1; -+} -+ -+int WriteWBMP(FILE * fp, byte * pic, int ptype, int w, int h, -+ byte * rmap, byte *gmap, byte *bmap, -+ int numcols, int colorstyle) -+{ -+ int count = 0; -+ uint8 bit = 0; -+ int i; -+ -+ write_mb(0, fp); /* type : always 0 */ -+ putc(0, fp); /* fixed header : always 0 for type 0 */ -+ write_mb((uint32)w, fp); -+ write_mb((uint32)h, fp); -+ -+ /* ready to write data */ -+ -+ for (i=0; i<w*h; i++) { -+ bit |= (((pic[i]&1)<<(7-(count++)))); -+ if (count == 8) { -+ putc(bit, fp); -+ count = 0; -+ } -+ } -+ -+ if (!count) { -+ putc(bit, fp); -+ } -+ -+ return 0; -+} -+ -+int fail(char * name, char * msg) -+{ -+ SetISTR(ISTR_WARNING, "%s : %s", name, msg); -+ return 0; -+} -+ -+void write_mb(uint32 data, FILE * f) -+{ -+ int i = 32; -+ uint32 aux = data; -+ int no; -+ -+ if (!aux) { -+ i = 1; -+ } else { -+ while (!(aux & 0x80000000)) { -+ aux <<= 1; -+ i--; -+ } -+ } -+ -+ /* i tells us how many bits are left to encode */ -+ -+ no = (i / 7 + ((i % 7)?1:0))-1; -+ -+ /* -+ fprintf(stderr, "writing %x, bits to write=%d, passes=%d\n", -+ data, i, no); -+ */ -+ -+ do { -+ uint8 value = no?0x80:0x0; -+ value |= ((data >> (no*7)) & 0x7f); -+ putc(value, f); -+ } while ((no--)>0); -+ -+} -+ -+int read_mb(int * dst, int fd) -+{ -+ int ac = 0; -+ int ct = 0; -+ -+ while (1) { -+ uint8 bt; -+ if ((ct++)==6) { -+ st_err = err_inmb; -+ return 0; -+ } -+ -+ if ((read(fd, &bt, 1)) < 1) { -+ st_err = err_ueof; -+ return 0; -+ } -+ ac = (ac << 7) | (bt & 0x7f); /* accumulates up to 42 bits?? FIXME */ -+ if (!(bt & 0x80)) -+ break; -+ } -+ *dst = ac; -+ return 1; -+} -+ -+int read_ext(int fd, uint8 fixed) -+{ -+ if (!(fixed&0x7f)) { /* no extensions */ -+ return 1; -+ } -+ -+ /* -+ * The only described type is WBMP 0, that must not -+ * have extensions. -+ */ -+ -+ st_err = err_extf; -+ return 0; -+ -+ /* -+ -+ fixed = (fixed >> 5)&0x3; -+ -+ switch (fixed) { -+ case 0: -+ while (true) { -+ SREADU8(fd, fixed); -+ if (!(fixed & 0x7f)) { break; } -+ } -+ break; -+ case 0x3: -+ { -+ char * par; -+ char * val; -+ SREADU8(fd, fixed); -+ SREADC(fd, par, (fixed>>4)&0x6); -+ SREADC(fd, val, fixed&0xf); -+ } -+ break; -+ } -+ */ -+} -+ -+void * mymalloc(int l) -+{ -+ mymem = (void**)realloc(mymem, mymems+1); -+ if (!mymem) -+ FatalError("LoadWBMP: can't realloc buffer"); -+ return (mymem[mymems++] = malloc(l)); -+} -+ -+void myfree() -+{ -+ int i; -+ -+ if (mymem) { -+ for (i=0; i<mymems; i++) { -+ if (mymem[i]) -+ free(mymem[i]); -+ } -+ free(mymem); -+ } -+ mymem = (void**)NULL; -+ mymems = 0; -+} -+ -+uint8 * render1(uint8 * data, int size, int npixels) -+{ -+ byte * pic; -+ int i; -+ int cnt = 0; -+ uint8 cb = *data; -+ -+ pic = calloc(npixels,1); /* checked for overflow by caller */ -+ if (!pic) { -+ myfree(); -+ FatalError("LoadWBMP: can't allocate 'pic' buffer"); -+ } -+ -+ /* expand bits into bytes */ -+ /* memset(pic, 0, npixels); */ -+ -+ for (i=0; i<npixels; i++) { -+ -+ pic[i] = (cb>>7)&1; -+ -+ if ((++cnt)==8) { -+ cb = *(++data); -+ cnt = 0; -+ } else { -+ cb <<=1; -+ } -+ } -+ return pic; -+} -diff -ruN xv-3.10a-bugfixes/xvxpm.c xv-3.10a-enhancements/xvxpm.c ---- xv-3.10a-bugfixes/xvxpm.c 2005-03-28 22:22:50.000000000 -0800 -+++ xv-3.10a-enhancements/xvxpm.c 2005-04-17 14:45:28.000000000 -0700 -@@ -175,7 +175,15 @@ - - do { - char key[3]; -- char color[40]; /* Need to figure a good size for this... */ -+ char color[80]; /* Need to figure a good size for this... */ -+ -+/* -+ * Problem with spaces in color names -+ * -+ * X s Color Name m Other Name c Last Name -+ * -+ * ... this parser doesn't find `Any Name' -+ */ - - for (j=0; j<2 && (c != ' ') && (c != '\t') && (c != EOF); j++) { - key[j] = c; -@@ -187,7 +195,7 @@ - if (c == EOF) /* The failure condition of getc() */ - return (XpmLoadError(bname, "Error parsing colormap line")); - -- for (j=0; j<39 && (c!=' ') && (c!='\t') && (c!='"') && c!=EOF; j++) { -+ for (j=0; j<79 && (c!=' ') && (c!='\t') && (c!='"') && c!=EOF; j++) { - color[j] = c; - c = XpmGetc(fp); - } -@@ -248,7 +256,7 @@ - else { /* 'None' or unrecognized color spec */ - int rgb; - -- if (strcmp(color, "None") == 0) rgb = 0xb2c0dc; /* infobg */ -+ if (strcasecmp(color, "None") == 0) rgb = 0xb2c0dc; /* infobg */ - else { - SetISTR(ISTR_INFO, "%s: unknown color spec '%s'", bname, color); - Timer(1000); -@@ -321,7 +329,8 @@ - *i_sptr++ = mapentry->cv_rgb[2]; - } - } /* for ( j < w ) */ -- (void)XpmGetc(fp); /* Throw away the close " */ -+ while (((c = XpmGetc(fp))!=EOF) && /* Throw away the close " and */ -+ (c != '"')); /* erase all remaining pixels */ - - if (!(i%7)) WaitCursor(); - } /* for ( i < h ) */ -diff -ruN xv-3.10a-bugfixes/xvzx.c xv-3.10a-enhancements/xvzx.c ---- xv-3.10a-bugfixes/xvzx.c 1969-12-31 16:00:00.000000000 -0800 -+++ xv-3.10a-enhancements/xvzx.c 2004-05-16 18:08:33.000000000 -0700 -@@ -0,0 +1,349 @@ -+/* -+ * xvzx.c - load routine for Spectrum screen$ -+ * -+ * John Elliott, 7 August 1998 -+ * -+ * LoadZX(fname, pinfo) - load file -+ * WriteZX(fp,pic,ptype,w,h,r,g,b,numcols,style,cmt,comment) - convert to -+ * 256x192 SCREEN$ and save. -+ */ -+ -+#include "copyright.h" -+ -+#include "xv.h" -+ -+ -+ -+/* -+ * comments on error handling: -+ * a file with a bad header checksum is a warning error. -+ * -+ * not being able to malloc is a Fatal Error. The program is aborted. -+ */ -+ -+ -+#define TRUNCSTR "File appears to be truncated." -+ -+static int zxError PARM((char *, char *)); -+ -+static char *bname; -+ -+/*******************************************/ -+int LoadZX(fname, pinfo) -+ char *fname; -+ PICINFO *pinfo; -+/*******************************************/ -+{ -+ /* returns '1' on success */ -+ -+ FILE *fp; -+ unsigned int c, c1; -+ int x,y, trunc; -+ byte *zxfile; -+ -+ bname = BaseName(fname); -+ -+ pinfo->pic = (byte *) NULL; -+ pinfo->comment = (char *) NULL; -+ -+ /* Allocate memory for a 256x192x8bit image */ -+ -+ pinfo->pic = (byte *)malloc(256*192); -+ if (!pinfo->pic) FatalError("malloc failure in xvzx.c LoadZX"); -+ -+ /* Allocate 1B80h bytes and slurp the whole file into memory */ -+ -+ zxfile = (byte *)malloc(7040); -+ if (!zxfile) FatalError("malloc failure in xvzx.c LoadZX"); -+ -+ /* open the file */ -+ fp = xv_fopen(fname,"r"); -+ if (!fp) return (zxError(bname, "can't open file")); -+ -+ /* Load it in en bloc */ -+ memset(zxfile, 0, 7040); -+ if (fread(zxfile, 1, 7040, fp) < 7040) trunc = 1; -+ -+ /* Transform to 8-bit */ -+ -+ for (y = 0; y < 192; y++) for (x = 0; x < 256; x++) -+ { -+ /* Spectrum screen layout: three 2k segments at y=0, y=64, y=128 */ -+ /* In each segment: Scan lines 0,8,16,...,56,1,9,...,57 etc. Each -+ scanline is 32 bytes, so line 1 is 256 bytes after line 0 -+ -+ So address of line start is ((y>>6) * 2048) + ((y & 7) * 256) -+ + ((y & 0x38) * 4) -+ -+ The colour byte for a cell is at screen + 6k + (y >> 3)*32 + (x>>3) -+ -+ */ -+ -+ int offset; -+ byte *dst = pinfo->pic + 256*y + x; -+ byte attr, pt, mask; -+ -+ offset = (y >> 6) * 2048; -+ offset += (y & 7) * 256; -+ offset += (y & 0x38) * 4; -+ offset += (x >> 3); -+ -+ pt = zxfile[offset + 128]; /* Ink/paper map */ -+ -+ offset = 0x1880; -+ offset += (y >> 3) * 32; -+ offset += (x >> 3); -+ -+ attr = zxfile[offset]; /* Colours for cell */ -+ -+ mask = 0x80; -+ -+ if (x & 7) mask >>= (x & 7); -+ -+ if (pt & mask) *dst = attr & 7; /* Ink */ -+ else *dst = (attr >> 3) & 7; /* Paper */ -+ -+ if (attr & 0x40) *dst |= 8; /* High intensity */ -+ } -+ -+ /* Picture bytes converted; now build the colour maps */ -+ -+ pinfo->normw = pinfo->w = 256; -+ pinfo->normh = pinfo->h = 192; -+ pinfo->type = PIC8; -+ -+ for (c = 0; c < 16; c++) -+ { -+ if (c < 8) c1 = 192; else c1 = 255; /* low-intensity colours use 192 */ -+ /* high-intensity colours use 255 */ -+ pinfo->b[c] = (c & 1 ? c1 : 0); -+ pinfo->r[c] = (c & 2 ? c1 : 0); -+ pinfo->g[c] = (c & 4 ? c1 : 0); -+ } -+ -+ pinfo->colType = F_FULLCOLOR; -+ pinfo->frmType = F_ZX; /* Save as SCREEN$ */ -+ sprintf(pinfo->fullInfo, "Spectrum SCREEN$, load address %04x", -+ zxfile[16]+256*zxfile[17]); -+ strcpy(pinfo->shrtInfo, "Spectrum SCREEN$."); -+ -+ /* Almost as an afterthought, check that the +3DOS header is valid. -+ -+ If it isn't, then odds are that the file isn't a graphic. But it -+ had the right magic number, so it might be. Let them see it anyway. -+ -+ The check is: Byte 127 of the header should be the 8-bit sum of bytes -+ 0-126 of the header. The header should also have the -+ +3DOS magic number, but we know it does or we wouldn't -+ have got this far. -+ */ -+ -+ c1 = 0; -+ for (c1 = c = 0; c < 127; c++) c1 = ((c1 + zxfile[c]) & 0xFF); -+ if (c1 != zxfile[127]) zxError(bname, "Bad header checksum."); -+ -+ fclose(fp); -+ free(zxfile); -+ return 1; -+} -+ -+ -+ -+ -+ -+/*******************************************/ -+static int zxError(fname, st) -+ char *fname, *st; -+{ -+ SetISTR(ISTR_WARNING,"%s: %s", fname, st); -+ return 0; -+} -+ -+ -+/* Spectrum screen file header. The first 18 bytes are used in the magic -+ number test */ -+ -+byte ZXheader[128] = -+{ -+ 'P', 'L', 'U', 'S', '3', 'D', 'O', 'S', 26, /* Spectrum +3DOS file */ -+ 1, 0, /* Header type 1.0 */ -+ 128, 27, 0, 0, /* 7040 bytes */ -+ 3, /* Binary format */ -+ 0, 27, /* 6912 data bytes */ -+ 0, 64 /* load address 0x4000 */ -+}; -+ -+ -+ -+/* Get the Spectrum colour/bright byte (0-15) from a pixel */ -+ -+static int PointZX(pic, w, h, rmap, gmap, bmap, x, y) -+ byte *pic; -+ int w,h; -+ byte *rmap, *gmap, *bmap; -+ int x,y; -+{ -+ int index, r, g, b, zxc; -+ -+ /* If the picture is smaller than the screen, pad out the edges -+ with "bright black" - a colour not otherwise returned */ -+ -+ if (x >= w || y >= h) return 8; -+ -+ /* Get colour index */ -+ -+ index = pic[y*w + x]; -+ -+ /* Convert to rgb */ -+ -+ r = rmap[index]; -+ g = gmap[index]; -+ b = bmap[index]; -+ zxc = 0; -+ -+ /* Work out Spectrum colour by a simplistic "nearest colour" method */ -+ -+ if (b >= 160) zxc |= 1; /* Blue */ -+ if (r >= 160) zxc |= 2; /* Red */ -+ if (g >= 160) zxc |= 4; /* Green */ -+ if (r > 208 || g >= 208 || b >= 208) zxc |= 8; /* High intensity */ -+ -+ return zxc; -+} -+ -+ -+/* Work out what colours should be used in a cell */ -+ -+static void CellZX(pic, w, h, rmap, gmap, bmap, cx, cy, zxfile) -+ byte *pic; -+ int w,h; -+ byte *rmap, *gmap, *bmap; -+ int cx,cy; -+ byte *zxfile; -+{ -+ byte counts[16]; /* Count of no. of colours */ -+ int offset, ink, paper, n, m, x, y, x0, y0, di, dp; -+ -+ x0 = cx * 8; /* Convert from cell to pixel coords */ -+ y0 = cy * 8; -+ -+ for (n = 0; n < 16; n++) counts[n] = 0; /* Reset all counts */ -+ -+ /* Count no. of pixels of various colours */ -+ -+ for (y = y0; y < y0+8; y++) for (x = x0; x < x0+8; x++) -+ { -+ m = PointZX(pic, w, h, rmap, gmap, bmap, x, y); -+ -+ counts[m]++; -+ } -+ counts[8] = 0; /* Discard Bright Black (pixels not in the picture area) -+ */ -+ -+ /* Assign the most popular colour as ink */ -+ for (n = m = ink = 0; n < 16; n++) if (counts[n] > m) -+ { -+ ink = n; -+ m = counts[n]; -+ } -+ counts[ink] = 0; -+ -+ /* Assign the next most popular colour as paper */ -+ for (n = m = paper = 0; n < 16; n++) if (counts[n] > m) -+ { -+ paper = n; -+ m = counts[n]; -+ } -+ /* We have ink and paper. Set cell's attributes */ -+ -+ offset = cy*32 + cx + 0x1880; -+ -+ /* Set the high-intensity bit if ink is high-intensity */ -+ if (ink & 8) zxfile[offset] = 0x40; else zxfile[offset] = 0; -+ zxfile[offset] |= ((paper & 7) << 3); -+ zxfile[offset] |= (ink & 7); -+ -+ /* Plot the points */ -+ for (y = y0; y < y0+8; y++) -+ { -+ byte mask = 0x80; -+ -+ offset = (y >> 6) * 2048; -+ offset += (y & 7) * 256; -+ offset += (y & 0x38) * 4; -+ offset += (x0 >> 3); -+ -+ for (x = x0; x < x0+8; x++) -+ { -+ /* Work out whether the point should be plotted as ink or -+ paper */ -+ m = PointZX(pic, w, h, rmap, gmap, bmap, x, y); -+ -+ di = (ink & 7) - (m & 7); /* "Difference" from ink */ -+ dp = (paper & 7) - (m & 7); /* "Difference" from paper */ -+ -+ if (di < 0) di = -di; -+ if (dp < 0) dp = -dp; -+ -+ if (di < dp) /* Point is more like ink */ -+ zxfile[offset+128] |= mask; -+ -+ mask = (mask >> 1); -+ } -+ } -+ -+} -+ -+ -+ -+/*******************************************/ -+int WriteZX(fp,pic,ptype,w,h,rmap,gmap,bmap,numcols,colorstyle,comment) -+ FILE *fp; -+ byte *pic; -+ int ptype, w,h; -+ byte *rmap, *gmap, *bmap; -+ int numcols, colorstyle; -+ char *comment; -+{ -+ int rv, x, y; -+ byte *zxfile; -+ byte *pic8; -+ byte rtemp[256],gtemp[256],btemp[256]; -+ -+ /* To simplify matters, reduce 24-bit to 8-bit. Since the Spectrum -+ screen is 3.5-bit anyway, it doesn't make much difference */ -+ -+ if (ptype == PIC24) -+ { -+ pic8 = Conv24to8(pic, w, h, 256, rtemp,gtemp,btemp); -+ if (!pic8) FatalError("Unable to malloc in WriteZX()"); -+ rmap = rtemp; gmap = gtemp; bmap = btemp; numcols=256; -+ } -+ else pic8 = pic; -+ -+ ZXheader[127] = 0x71; /* The correct checksum. */ -+ -+ /* Create a memory image of the SCREEN$ */ -+ -+ zxfile = (byte *)malloc(7040); -+ if (!zxfile) FatalError("malloc failure in xvzx.c WriteZX"); -+ -+ memset(zxfile, 0, 7040); /* Reset all points to black */ -+ memcpy(zxfile, ZXheader, 128); /* Create +3DOS header */ -+ -+ /* Convert the image, character cell by character cell */ -+ for (y = 0; y < 24; y++) for (x = 0; x < 32; x++) -+ { -+ CellZX(pic8, w, h, rmap, gmap, bmap, x, y, zxfile); -+ } -+ rv = 0; -+ if (fwrite(zxfile, 1, 7040, fp) < 7040) rv = -1; -+ -+ if (ptype == PIC24) free(pic8); -+ free(zxfile); -+ -+ if (ferror(fp)) rv = -1; -+ -+ return rv; -+} -+ |