Imported from libpng-1.0.6.tar
diff --git a/contrib/gregbook/LICENSE b/contrib/gregbook/LICENSE
new file mode 100644
index 0000000..5714772
--- /dev/null
+++ b/contrib/gregbook/LICENSE
@@ -0,0 +1,26 @@
+  ---------------------------------------------------------------------------
+
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
+
+      This software is provided "as is," without warranty of any kind,
+      express or implied.  In no event shall the author or contributors
+      be held liable for any damages arising in any way from the use of
+      this software.
+
+      Permission is granted to anyone to use this software for any purpose,
+      including commercial applications, and to alter it and redistribute
+      it freely, subject to the following restrictions:
+
+      1. Redistributions of source code must retain the above copyright
+         notice, disclaimer, and this list of conditions.
+      2. Redistributions in binary form must reproduce the above copyright
+         notice, disclaimer, and this list of conditions in the documenta-
+         tion and/or other materials provided with the distribution.
+      3. All advertising materials mentioning features or use of this
+         software must display the following acknowledgment:
+
+            This product includes software developed by Greg Roelofs
+            and contributors for the book, "PNG: The Definitive Guide,"
+            published by O'Reilly and Associates.
+
+  ---------------------------------------------------------------------------
diff --git a/contrib/gregbook/makefile.unx b/contrib/gregbook/Makefile.unx
similarity index 64%
rename from contrib/gregbook/makefile.unx
rename to contrib/gregbook/Makefile.unx
index 93d46d1..ed2e4f4 100644
--- a/contrib/gregbook/makefile.unx
+++ b/contrib/gregbook/Makefile.unx
@@ -1,6 +1,6 @@
 # Sample makefile for rpng-x / rpng2-x / wpng using gcc and make.
 # Greg Roelofs
-# Last modified:  16 February 1999
+# Last modified:  28 February 2000
 #
 #	The programs built by this makefile are described in the book,
 #	"PNG:  The Definitive Guide," by Greg Roelofs (O'Reilly and
@@ -9,11 +9,12 @@
 #
 # Invoke this makefile from a shell prompt in the usual way; for example:
 #
-#	make -f makefile.unx
+#	make -f Makefile.unx
 #
 # This makefile assumes libpng and zlib have already been built or downloaded
 # and are both installed in /usr/local/{include,lib} (as indicated by the
-# PNGPATH and ZPATH macros below).  Edit as appropriate.
+# PNG* and Z* macros below).  Edit as appropriate--choose only ONE each of
+# the PNGINC, PNGLIB, ZINC and ZLIB lines.
 #
 # This makefile builds statically linked executables (against libpng and zlib,
 # that is), but that can be changed by uncommenting the appropriate PNGLIB and
@@ -22,30 +23,38 @@
 
 # macros --------------------------------------------------------------------
 
-PNGPATH = /usr/local
-PNGINC = -I$(PNGPATH)/include
-#PNGLIB = -L$(PNGPATH)/lib -lpng
-PNGLIB = $(PNGPATH)/lib/libpng.a
+PNGINC = -I/usr/local/include
+#PNGLIB = -L/usr/local/lib -lpng	# dynamically linked against libpng
+PNGLIB = /usr/local/lib/libpng.a	# statically linked against libpng
+# or:
+#PNGINC = -I../..
+#PNGLIB = -L../.. -lpng
+#PNGLIB = ../../libpng.a
 
-ZPATH = /usr/local
-ZINC = -I$(ZPATH)/include
-#ZLIB = -L$(ZPATH)/lib -lz
-ZLIB = $(ZPATH)/lib/libz.a
+ZINC = -I/usr/local/include
+#ZLIB = -L/usr/local/lib -lz		# dynamically linked against zlib
+ZLIB = /usr/local/lib/libz.a		# statically linked against zlib
+#ZINC = -I../zlib
+#ZLIB = -L../zlib -lz
+#ZLIB = ../../../zlib/libz.a
 
-#XPATH = /usr/X11
-XPATH = /usr/X11R6
-XINC = -I$(XPATH)/include
-XLIB = -L$(XPATH)/lib -lX11
+#XINC = -I/usr/include/X11		# old-style, stock X distributions
+#XLIB = -L/usr/lib/X11 -lX11
+#XINC = -I/usr/openwin/include/X11	# Sun workstations (OpenWindows)
+#XLIB = -L/usr/openwin/lib -lX11
+XINC = -I/usr/X11R6/include		# new X distributions (XFree86, etc.)
+XLIB = -L/usr/X11R6/lib -lX11
 
 INCS = $(PNGINC) $(ZINC) $(XINC)
 RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm
-WLIBS = $(PNGLIB) $(ZLIB) -lm
+WLIBS = $(PNGLIB) $(ZLIB)
 
 CC = gcc
 LD = gcc
 RM = rm -f
 CFLAGS = -O -Wall $(INCS)
-# [note that -Wall is a gcc-specific compilation flag ("all warnings on")]
+# [note that -Wall is a gcc-specific compilation flag ("most warnings on")]
+# [-ansi, -pedantic and -W can also be used]
 LDFLAGS =
 O = .o
 E =
diff --git a/contrib/gregbook/makefile.w32 b/contrib/gregbook/Makefile.w32
similarity index 97%
rename from contrib/gregbook/makefile.w32
rename to contrib/gregbook/Makefile.w32
index e520ae7..2a84022 100644
--- a/contrib/gregbook/makefile.w32
+++ b/contrib/gregbook/Makefile.w32
@@ -10,14 +10,14 @@
 # Invoke this makefile from a DOS prompt window via:
 #
 #	%devstudio%\vc\bin\vcvars32.bat
-#	nmake -nologo -f makefile.w32
+#	nmake -nologo -f Makefile.w32
 #
 # where %devstudio% is the installation directory for MSVC / DevStudio.  If
 # you get "environment out of space" errors, create a desktop shortcut with
 # "c:\windows\command.com /e:4096" as the program command line and set the
 # working directory to this directory.  Then double-click to open the new
 # DOS-prompt window with a bigger environment and retry the commands above.
-#
+# 
 # This makefile assumes libpng and zlib have already been built or downloaded
 # and are in subdirectories at the same level as the current subdirectory
 # (as indicated by the PNGPATH and ZPATH macros below).  Edit as appropriate.
@@ -32,12 +32,12 @@
 
 # macros --------------------------------------------------------------------
 
-PNGPATH = ../libpng
+PNGPATH = ../..
 PNGINC = -I$(PNGPATH)
 #PNGLIB = $(PNGPATH)/pngdll.lib
 PNGLIB = $(PNGPATH)/libpng.lib
 
-ZPATH = ../zlib
+ZPATH = ../../../zlib
 ZINC = -I$(ZPATH)
 #ZLIB = $(ZPATH)/zlibdll.lib
 ZLIB = $(ZPATH)/zlibstat.lib
diff --git a/contrib/gregbook/README b/contrib/gregbook/README
index fa3871a..a8bbc28 100644
--- a/contrib/gregbook/README
+++ b/contrib/gregbook/README
@@ -1,52 +1,183 @@
-PNG: The Definitive Guide: Source Code
+                     ===========================
+                      PNG: The Definitive Guide
+                     ===========================
 
-Chapters 13, 14 and 15 of PNG: The Definitive Guide discuss three
+                             Source Code
+
+Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free,
 cross-platform demo programs that show how to use the libpng reference
-library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is a
-very simple example that that shows how a standard file-viewer might use
-libpng, while the second is designed to process streaming data and shows how
-a web browser might be written. wpng is a simple command-line program that
-reads binary PPM files (the ``raw'' RGB subset of NetPBM) and converts them
-to PNG.
+library:  rpng, rpng2 and wpng.  rpng and rpng2 are viewers; the first is
+a very simple example that that shows how a standard file-viewer might use
+libpng, while the second is designed to process streaming data and shows
+how a web browser might be written.  wpng is a simple command-line program
+that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets
+of PBMPLUS/NetPBM) and converts them to PNG.
 
-The source code for all three demo programs currently compiles only under
-Unix and 32-bit Windows. It has been tested with gcc 2.7.2.3 under Linux and
-Solaris and with Microsoft Visual C++ 5.0 under Windows 95. Brief
-instructions for compiling the programs are included at the top of the
-makefiles; makefile.unx is the Unix version, and makefile.w32 is (you
-guessed it!) the version for 32-bit Windows. libpng and zlib are required.
+The source code for all three demo programs currently compiles under
+Unix, OpenVMS, and 32-bit Windows.  (Special thanks to Martin Zinser,
+zinser@decus.de, for making the necessary changes for OpenVMS and for
+providing an appropriate build script.)  Build instructions can be
+found below.
 
-----------------------------------------------------------------------------
+Files:
 
-License
+   README             this file
+   README.w32         additional Windows-specific information
+   LICENSE            terms of distribution and reuse (BSD-like)
 
-The source code to the demo programs may be used and distributed freely
-(even if you didn't buy the book--but feel free to do so at any time),
-subject to the terms of the following BSD-like license:
+   Makefile.unx       Unix makefile
+   Makefile.w32       Windows (MSVC) makefile
+   makevms.com        OpenVMS build script
 
-     Copyright (c) 1998-1999 Greg Roelofs. All rights reserved.
+   rpng-win.c         Windows front end for the basic viewer
+   rpng-x.c           X Window System (Unix, OpenVMS) front end
+   readpng.c          generic back end for the basic viewer
+   readpng.h          header file for the basic viewer
 
-     This software is provided "as is," without warranty of any kind,
-     express or implied. In no event shall the author or contributors
-     be held liable for any damages arising in any way from the use of
-     this software.
+   rpng2-win.c        Windows front end for the progressive viewer
+   rpng2-x.c          X front end for the progressive viewer
+   readpng2.c         generic back end for the progressive viewer
+   readpng2.h         header file for the progressive viewer
 
-     Permission is granted to anyone to use this software for any
-     purpose, including commercial applications, and to alter it and
-     redistribute it freely, subject to the following restrictions:
+   wpng.c             generic (text) front end for the converter
+   writepng.c         generic back end for the converter
+   writepng.h         header file for the converter
 
-       1. Redistributions of source code must retain the above
-          copyright notice, disclaimer, and this list of conditions.
-       2. Redistributions in binary form must reproduce the above
-          copyright notice, disclaimer, and this list of conditions in
-          the documentation and/or other materials provided with the
-          distribution.
-       3. All advertising materials mentioning features or use of this
-          software must display the following acknowledgment:
+   toucan.png         transparent PNG for testing (by Stefan Schneider)
 
-               This product includes software developed by Greg Roelofs
-               and contributors for the book, "PNG: The Definitive
-               Guide," published by O'Reilly and Associates.
+Note that the programs are designed to be functional, but their primary
+purpose is to demonstrate how to use libpng to add PNG support to other
+programs.  As such, their user interfaces are crude and definitely not
+intended for everyday use.
 
-----------------------------------------------------------
-http://www.cdrom.com/pub/png/book/sources.html
+Please see http://www.cdrom.com/pub/png/pngbook.html for further infor-
+mation and links to the latest version of the source code, and Chapters
+13-15 of the book for detailed discussion of the three programs.
+
+Greg Roelofs
+19 March 2000
+
+
+BUILD INSTRUCTIONS
+
+ - Prerequisites:
+
+      - zlib		ftp://ftp.cdrom.com/pub/infozip/zlib/zlib.html
+      - libpng		http://www.cdrom.com/pub/png/pngcode.html
+      - pngbook		http://www.cdrom.com/pub/png/book/sources.html
+
+     The pngbook demo programs are explicitly designed to demonstrate proper
+     coding techniques for using the libpng reference library.  As a result,
+     you need to download and build both zlib (on which libpng depends) and
+     libpng.  A common build setup is to place the zlib, libpng and pngbook
+     subdirectory trees ("folders") in the same parent directory.  Then the
+     libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]),
+     and similarly for the pngbook build.
+
+     Note that all three packages are designed to be built from a command
+     line by default; those who wish to use a graphical or other integrated
+     development environments are on their own.
+
+
+ - Unix:
+
+     Unpack the latest pngbook sources (which should correspond to this
+     README file) into a directory and change into that directory.
+
+     Copy Makefile.unx to Makefile and edit the PNG* and Z* variables
+     appropriately (possibly also the X* variables if necessary).
+
+     make
+
+     There is no "install" target, so copy the three executables somewhere
+     in your path or run them from the current directory.  All three will
+     print a basic usage screen when run without any command-line arguments;
+     see the book for more details.
+
+
+ - Windows:
+
+     Unpack the latest pngbook sources (which should correspond to this
+     README file) into a folder, open a "DOS shell" or "command prompt"
+     or equivalent command-line window, and cd into the folder where you
+     unpacked the source code.
+
+     For MSVC, set up the necessary environment variables by invoking
+ 
+        %devstudio%\vc\bin\vcvars32.bat
+
+     where where %devstudio% is the installation directory for MSVC /
+     DevStudio.  If you get "environment out of space" errors under 95/98,
+     create a desktop shortcut with "c:\windows\command.com /e:4096" as
+     the program command line and set the working directory to the pngbook
+     directory.  Then double-click to open the new DOS-prompt window with
+     a bigger environment and retry the commands above.
+
+     Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables
+     appropriately (possibly also the "INC" and "LIB" variables if needed).
+     Note that the names of the dynamic and static libpng and zlib libraries
+     used in the makefile may change in later releases of the libraries.
+     Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work.
+     This makefile therefore builds statically linked executables, but if
+     the DLL problems ever get fixed, uncommenting the appropriate PNGLIB
+     and ZLIB lines will build dynamically linked executables instead.
+
+     Do the build by typing
+
+        nmake
+
+     The result should be three executables:  rpng-win.exe, rpng2-win.exe,
+     and wpng.exe.  Copy them somewhere in your PATH or run them from the
+     current folder.  Unlike the Unix versions, the two windowed programs
+     (rpng and rpng2) do not display a usage screen when invoked without
+     command-line arguments; see README.w32 for brief help or the book for
+     details.  Note that the programs use the Unix-style "-" character to
+     specify options, instead of the more common DOS/Windows "/" character.
+
+
+ - OpenVMS:
+
+     Unpack the pngbook sources into a subdirectory and change into that
+     subdirectory.
+
+     Edit makevms.com appropriately, specifically the zpath and pngpath
+     variables.
+
+     @makevms
+
+     To run the programs, they probably first need to be set up as "foreign
+     symbols," with "disk" and "dir" set appropriately:
+
+     $ rpng == "$disk:[dir]rpng-x.exe"
+     $ rpng2 == "$disk:[dir]rpng2-x.exe"
+     $ wpng == "$disk:[dir]wpng.exe"
+
+     All three will print a basic usage screen when run without any command-
+     line arguments; see the book for more details.  Note that the options
+     style is Unix-like, i.e., preceded by "-" rather than "/".
+
+
+RUNNING THE PROGRAMS:  (VERY) BRIEF INTRO
+
+     rpng is a simple PNG viewer that can display transparent PNGs with a
+     specified background color; for example,
+
+	rpng -bgcolor #ff0000 toucan.png
+
+     would display the image with a red background.  rpng2 is a progressive
+     viewer that simulates a web browser in some respects; it can display
+     images against either a background color or a dynamically generated
+     background image.  For example:
+
+	rpng2 -bgpat 16 toucan.png
+
+     wpng is a purely command-line image converter from binary PBMPLUS/NetPBM
+     format (.pgm or .ppm) to PNG; for example,
+
+	wpng -time < toucan.ppm > toucan.png
+
+     would convert the specified PPM file (using redirection) to PNG, auto-
+     matically setting the PNG modification-time chunk.
+
+     All options can be abbreviated to the shortest unique value; for example,
+     "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma.
diff --git a/contrib/gregbook/README.w32 b/contrib/gregbook/README.w32
new file mode 100644
index 0000000..736c001
--- /dev/null
+++ b/contrib/gregbook/README.w32
@@ -0,0 +1,53 @@
+See the main README file for basic instructions on compiling and running
+the programs.  See http://www.cdrom.com/pub/png/pngbook.html for further
+information and links to the source code, and Chapters 13-15 of the book
+for detailed discussion of the three programs.
+
+Since the two viewers, rpng and rpng2, are both designed to write infor-
+mation to the console (i.e., a DOS-window command line) while displaying
+the image in a graphical window--and since I haven't yet figured out how
+to do that under Windows--here are the usage screens for the two programs:
+
+
+rpng-win 1.02 of 19 March 2000:  Simple PNG Viewer for Windows
+   Compiled with libpng 1.0.5; using libpng 1.0.5.
+   Compiled with zlib 1.1.3; using zlib 1.1.3.
+
+Usage:  rpng-win [-gamma exp] [-bgcolor bg] file.png
+    exp 	transfer-function exponent (``gamma'') of the display
+		  system in floating-point format (e.g., ``2.2''); equal
+		  to the product of the lookup-table exponent (varies)
+		  and the CRT exponent (usually 2.2); must be positive
+    bg  	desired background color in 7-character hex RGB format
+		  (e.g., ``#ff7f00'' for orange:  same as HTML colors);
+		  used with transparent images
+
+Press Q, Esc or mouse button 1 after image is displayed to quit.
+
+
+rpng2-win 1.04 of 19 March 2000:  Progressive PNG Viewer for Windows
+   Compiled with libpng 1.0.5; using libpng 1.0.5.
+   Compiled with zlib 1.1.3; using zlib 1.1.3.
+
+Usage:  rpng2-win [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing] file.png
+
+    exp 	transfer-function exponent (``gamma'') of the display
+		  system in floating-point format (e.g., ``2.2''); equal
+		  to the product of the lookup-table exponent (varies)
+		  and the CRT exponent (usually 2.2); must be positive
+    bg  	desired background color in 7-character hex RGB format
+		  (e.g., ``#ff7f00'' for orange:  same as HTML colors);
+		  used with transparent images; overrides -bgpat
+    pat 	desired background pattern number (1-16); used with
+		  transparent images; overrides -bgcolor
+    -timing	enables delay for every block read, to simulate modem
+		  download of image (~36 Kbps)
+
+Press Q, Esc or mouse button 1 after image is displayed to quit.
+
+
+The usage screen for the third (non-windowed) program, wpng, can be seen
+simply by invoking it without any parameters (``wpng'').
+
+Greg Roelofs
+19 March 2000
diff --git a/contrib/gregbook/makevms.com b/contrib/gregbook/makevms.com
index 2ee2eb6..b8cbfae 100644
--- a/contrib/gregbook/makevms.com
+++ b/contrib/gregbook/makevms.com
@@ -1,11 +1,22 @@
 $!------------------------------------------------------------------------------
-$! make Contrib programs of libpng under OpenVMS
+$! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS
+$!
+$! Script created by Martin Zinser for libpng; modified by Greg Roelofs
+$! for standalone pngbook source distribution.
 $!
 $!
-$! Look for the compiler used
+$!    Set locations where zlib and libpng sources live.
 $!
-$ zlibsrc = "[---.zlib]"
-$ ccopt="/include=(''zlibsrc',[--])"
+$ zpath = "[-.zlib]"
+$ pngpath = "[-.libpng]"
+$!
+$! USE THESE INSTEAD if building from libpng's [.contrib.gregbook] directory:
+$! zpath = "[---.zlib]"
+$! pngpath = "[--]"
+$!
+$!    Look for the compiler used.
+$!
+$ ccopt="/include=(''zpath',''pngpath')"
 $ if f$getsyi("HW_MODEL").ge.1024
 $ then
 $  ccopt = "/prefix=all"+ccopt
@@ -29,13 +40,16 @@
 $  endif
 $ endif
 $ open/write lopt lib.opt
-$ write lopt "[--]libpng.olb/lib"
-$ write lopt "''zlibsrc'libz.olb/lib"
+$ write lopt "''pngpath'libpng.olb/lib"
+$ write lopt "''zpath'libz.olb/lib"
 $ close lopt
 $ open/write xopt x11.opt
 $ write xopt "sys$library:decw$xlibshr.exe/share"
 $ close xopt
-$ write sys$output "Compiling PNG contrib programs ..."
+$!
+$!    Build 'em.
+$!
+$ write sys$output "Compiling PNG book programs ..."
 $   CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" -
 	readpng.c readpng.h
 $   CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" -
diff --git a/contrib/gregbook/readpng.c b/contrib/gregbook/readpng.c
index 546293f..dc948ee 100644
--- a/contrib/gregbook/readpng.c
+++ b/contrib/gregbook/readpng.c
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -32,8 +32,13 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "png.h"      /* libpng header; includes zlib.h */
-#include "readpng.h"  /* typedefs, common macros, public prototypes */
+#include "png.h"        /* libpng header; includes zlib.h */
+#include "readpng.h"    /* typedefs, common macros, public prototypes */
+
+/* future versions of libpng will provide this macro: */
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr)   ((png_ptr)->jmpbuf)
+#endif
 
 
 static png_structp png_ptr = NULL;
@@ -44,7 +49,7 @@
 uch  *image_data = NULL;
 
 
-void readpng_version_info()
+void readpng_version_info(void)
 {
     fprintf(stderr, "   Compiled with libpng %s; using libpng %s.\n",
       PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -55,7 +60,7 @@
 
 /* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */
 
-int readpng_init(FILE *infile, long *pWidth, long *pHeight)
+int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight)
 {
     uch sig[8];
 
@@ -89,7 +94,7 @@
     /* setjmp() must be called in every function that calls a PNG-reading
      * libpng function */
 
-    if (setjmp(png_jmp_env(png_ptr))) {
+    if (setjmp(png_jmpbuf(png_ptr))) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return 2;
     }
@@ -130,7 +135,7 @@
     /* setjmp() must be called in every function that calls a PNG-reading
      * libpng function */
 
-    if (setjmp(png_jmp_env(png_ptr))) {
+    if (setjmp(png_jmpbuf(png_ptr))) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return 2;
     }
@@ -184,7 +189,7 @@
     /* setjmp() must be called in every function that calls a PNG-reading
      * libpng function */
 
-    if (setjmp(png_jmp_env(png_ptr))) {
+    if (setjmp(png_jmpbuf(png_ptr))) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return NULL;
     }
diff --git a/contrib/gregbook/readpng.h b/contrib/gregbook/readpng.h
index 31780c5..1c19aca 100644
--- a/contrib/gregbook/readpng.h
+++ b/contrib/gregbook/readpng.h
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -54,7 +54,7 @@
 
 void readpng_version_info(void);
 
-int readpng_init(FILE *infile, long *pWidth, long *pHeight);
+int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight);
 
 int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue);
 
diff --git a/contrib/gregbook/readpng2.c b/contrib/gregbook/readpng2.c
index 19d1f18..8f70c83 100644
--- a/contrib/gregbook/readpng2.c
+++ b/contrib/gregbook/readpng2.c
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -30,10 +30,10 @@
   ---------------------------------------------------------------------------*/
 
 
-#include <stdlib.h>    /* for exit() prototype */
+#include <stdlib.h>     /* for exit() prototype */
 
-#include "png.h"       /* libpng header; includes zlib.h and setjmp.h */
-#include "readpng2.h"  /* typedefs, common macros, public prototypes */
+#include "png.h"        /* libpng header; includes zlib.h and setjmp.h */
+#include "readpng2.h"   /* typedefs, common macros, public prototypes */
 
 
 /* local prototypes */
@@ -47,7 +47,7 @@
 
 
 
-void readpng2_version_info()
+void readpng2_version_info(void)
 {
     fprintf(stderr, "   Compiled with libpng %s; using libpng %s.\n",
       PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -70,7 +70,7 @@
 
 int readpng2_init(mainprog_info *mainprog_ptr)
 {
-    png_structp  png_ptr; /* note:  temporary variables! */
+    png_structp  png_ptr;       /* note:  temporary variables! */
     png_infop  info_ptr;
 
 
@@ -98,7 +98,7 @@
      * but compatible error handlers must either use longjmp() themselves
      * (as in this program) or exit immediately, so here we are: */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         return 2;
     }
@@ -136,7 +136,7 @@
     /* setjmp() must be called in every function that calls a PNG-reading
      * libpng function */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
         mainprog_ptr->png_ptr = NULL;
         mainprog_ptr->info_ptr = NULL;
@@ -176,7 +176,7 @@
 
     mainprog_ptr = png_get_progressive_ptr(png_ptr);
 
-    if (mainprog_ptr == NULL) { /* we be hosed */
+    if (mainprog_ptr == NULL) {         /* we be hosed */
         fprintf(stderr,
           "readpng2 error:  main struct not recoverable in info_callback.\n");
         fflush(stderr);
@@ -283,7 +283,7 @@
 
     png_read_update_info(png_ptr, info_ptr);
 
-    mainprog_ptr->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);
     mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr);
 
 
@@ -323,6 +323,11 @@
     mainprog_ptr = png_get_progressive_ptr(png_ptr);
 
 
+    /* save the pass number for optional use by the front end */
+
+    mainprog_ptr->pass = pass;
+
+
     /* have libpng either combine the new row data with the existing row data
      * from previous passes (if interlaced) or else just copy the new row
      * into the main program's image buffer */
@@ -408,7 +413,7 @@
     fflush(stderr);
 
     mainprog_ptr = png_get_error_ptr(png_ptr);
-    if (mainprog_ptr == NULL) { /* we are completely hosed now */
+    if (mainprog_ptr == NULL) {         /* we are completely hosed now */
         fprintf(stderr,
           "readpng2 severe error:  jmpbuf not recoverable; terminating.\n");
         fflush(stderr);
diff --git a/contrib/gregbook/readpng2.h b/contrib/gregbook/readpng2.h
index 2ffd776..cbc1fd8 100644
--- a/contrib/gregbook/readpng2.h
+++ b/contrib/gregbook/readpng2.h
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -61,7 +61,8 @@
     uch *image_data;
     uch **row_pointers;
     jmp_buf jmpbuf;
-    int passes;    /* not used */
+    int passes;              /* not used */
+    int pass;
     int rowbytes;
     int channels;
     int need_bgcolor;
diff --git a/contrib/gregbook/rpng-win.c b/contrib/gregbook/rpng-win.c
index a75e609..51e1974 100644
--- a/contrib/gregbook/rpng-win.c
+++ b/contrib/gregbook/rpng-win.c
@@ -16,7 +16,16 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+   Changelog:
+    - 1.00:  initial public release
+    - 1.01:  modified to allow abbreviated options; fixed long/ulong mis-
+              match; switched to png_jmpbuf() macro
+    - 1.02:  added extra set of parentheses to png_jmpbuf() macro; fixed
+              command-line parsing bug
+
+  ---------------------------------------------------------------------------
+
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -43,7 +52,7 @@
 
 #define PROGNAME  "rpng-win"
 #define LONGNAME  "Simple PNG Viewer for Windows"
-#define VERSION   "1.0 of 20 February 1999"
+#define VERSION   "1.02 of 19 March 2000"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -53,7 +62,7 @@
 
 /* #define DEBUG  :  this enables the Trace() macros */
 
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
+#include "readpng.h"    /* typedefs, common macros, readpng prototypes */
 
 
 /* could just include png.h, but this macro is the only thing we need
@@ -61,10 +70,10 @@
  * only happen with alpha (which could easily be avoided with
  * "ush acopy = (alpha);") */
 
-#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 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);               \
 }
 
 
@@ -78,7 +87,7 @@
 static char titlebar[1024], *window_name = titlebar;
 static char *progname = PROGNAME;
 static char *appname = LONGNAME;
-static char *icon_name = PROGNAME;    /* GRR:  not (yet) used */
+static char *icon_name = PROGNAME;     /* GRR:  not (yet) used */
 static char *filename;
 static FILE *infile;
 
@@ -104,15 +113,15 @@
 
 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
 {
-    char *args[1024];                /* arbitrary limit, but should suffice */
+    char *args[1024];                 /* arbitrary limit, but should suffice */
     char *p, *q, **argv = args;
     int argc = 0;
     int rc, alen, flen;
     int error = 0;
     int have_bg = FALSE;
-    double LUT_exponent;             /* just the lookup table */
-    double CRT_exponent = 2.2;       /* just the monitor */
-    double default_display_exponent; /* whole display system */
+    double LUT_exponent;              /* just the lookup table */
+    double CRT_exponent = 2.2;        /* just the monitor */
+    double default_display_exponent;  /* whole display system */
     MSG msg;
 
 
@@ -199,20 +208,24 @@
     /* Now parse the command line for options and the PNG filename. */
 
     while (*++argv && !error) {
-        if (!strcmp(*argv, "-gamma")) {
+        if (!strncmp(*argv, "-gamma", 2)) {
             if (!*++argv)
                 ++error;
-            display_exponent = atof(*argv);
-            if (display_exponent <= 0.0)
-                ++error;
-        } else if (!strcmp(*argv, "-bgcolor")) {
+            else {
+                display_exponent = atof(*argv);
+                if (display_exponent <= 0.0)
+                    ++error;
+            }
+        } else if (!strncmp(*argv, "-bgcolor", 2)) {
             if (!*++argv)
                 ++error;
-            bgstr = *argv;
-            if (strlen(bgstr) != 7 || bgstr[0] != '#')
-                ++error;
-            else
-                have_bg = TRUE;
+            else {
+                bgstr = *argv;
+                if (strlen(bgstr) != 7 || bgstr[0] != '#')
+                    ++error;
+                else
+                    have_bg = TRUE;
+            }
         } else {
             if (**argv != '-') {
                 filename = *argv;
@@ -255,6 +268,9 @@
             fclose(infile);
     }
 
+
+    /* usage screen */
+
     if (error) {
         fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
         readpng_version_info();
@@ -265,7 +281,7 @@
          "\t\t  to the product of the lookup-table exponent (varies)\n"
          "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
          "    bg  \tdesired background color in 7-character hex RGB format\n"
-         "\t\t  (e.g., ``#ff7f00'' for orange:  same as HTML colors);\n"
+         "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
          "\t\t  used with transparent images\n"
          "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
          "\n", PROGNAME, default_display_exponent);
@@ -336,6 +352,10 @@
 
     /* wait for the user to tell us when to quit */
 
+    printf(
+      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+    fflush(stdout);
+
     while (GetMessage(&msg, NULL, 0, 0)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
@@ -371,7 +391,7 @@
     if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
                               wimage_rowbytes*image_height)))
     {
-        return 4; /* fail */
+        return 4;   /* fail */
     }
 
 /*---------------------------------------------------------------------------
@@ -477,7 +497,7 @@
                 g = *src++;
                 b = *src++;
                 *dest++ = b;
-                *dest++ = g; /* note reverse order */
+                *dest++ = g;   /* note reverse order */
                 *dest++ = r;
             }
         } else /* if (image_channels == 4) */ {
@@ -582,15 +602,15 @@
 
         /* wait for the user to tell us when to quit */
         case WM_CHAR:
-            switch (wP) { /* only need one, so ignore repeat count */
+            switch (wP) {      /* only need one, so ignore repeat count */
                 case 'q':
                 case 'Q':
-                case 0x1B: /* Esc key */
+                case 0x1B:     /* Esc key */
                     PostQuitMessage(0);
             }
             return 0;
 
-        case WM_LBUTTONDOWN: /* another way of quitting */
+        case WM_LBUTTONDOWN:   /* another way of quitting */
         case WM_DESTROY:
             PostQuitMessage(0);
             return 0;
diff --git a/contrib/gregbook/rpng-x.c b/contrib/gregbook/rpng-x.c
index 5f0a8a1..aea975d 100644
--- a/contrib/gregbook/rpng-x.c
+++ b/contrib/gregbook/rpng-x.c
@@ -5,8 +5,8 @@
    This program decodes and displays PNG images, with gamma correction and
    optionally with a user-specified background color (in case the image has
    transparency).  It is very nearly the most basic PNG viewer possible.
-   This version is for the X Window System (tested under Unix, but may work
-   under VMS or OS/2 with a little tweaking).
+   This version is for the X Window System (tested by author under Unix and
+   by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking).
 
    to do:
     - 8-bit support
@@ -14,7 +14,17 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+   Changelog:
+    - 1.01:  initial public release
+    - 1.02:  modified to allow abbreviated options; fixed long/ulong mis-
+              match; switched to png_jmpbuf() macro
+    - 1.10:  added support for non-default visuals; fixed X pixel-conversion
+    - 1.11:  added extra set of parentheses to png_jmpbuf() macro; fixed
+              command-line parsing bug
+
+  ---------------------------------------------------------------------------
+
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -41,7 +51,7 @@
 
 #define PROGNAME  "rpng-x"
 #define LONGNAME  "Simple PNG Viewer for X"
-#define VERSION   "1.01 of 31 March 1999"
+#define VERSION   "1.11 of 19 March 2000"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -54,7 +64,7 @@
 
 /* #define DEBUG  :  this enables the Trace() macros */
 
-#include "readpng.h" /* typedefs, common macros, readpng prototypes */
+#include "readpng.h"   /* typedefs, common macros, readpng prototypes */
 
 
 /* could just include png.h, but this macro is the only thing we need
@@ -95,15 +105,16 @@
 static char *displayname;
 static XImage *ximage;
 static Display *display;
-static int bitmap_order;
 static int depth;
 static Visual *visual;
-static int RPixelShift, GPixelShift, BPixelShift;
-static ulg RedMask, GreenMask, BlueMask;
+static XVisualInfo *visual_list;
+static int RShift, GShift, BShift;
+static ulg RMask, GMask, BMask;
 static Window window;
 static GC gc;
 static Colormap colormap;
 
+static int have_nondefault_visual = FALSE;
 static int have_colormap = FALSE;
 static int have_window = FALSE;
 /*
@@ -123,9 +134,9 @@
     int rc, alen, flen;
     int error = 0;
     int have_bg = FALSE;
-    double LUT_exponent;             /* just the lookup table */
-    double CRT_exponent = 2.2;       /* just the monitor */
-    double default_display_exponent; /* whole display system */
+    double LUT_exponent;               /* just the lookup table */
+    double CRT_exponent = 2.2;         /* just the monitor */
+    double default_display_exponent;   /* whole display system */
     XEvent e;
     KeySym k;
 
@@ -188,24 +199,29 @@
     /* Now parse the command line for options and the PNG filename. */
 
     while (*++argv && !error) {
-        if (!strcmp(*argv, "-display")) {
+        if (!strncmp(*argv, "-display", 2)) {
             if (!*++argv)
                 ++error;
-            displayname = *argv;
-        } else if (!strcmp(*argv, "-gamma")) {
-            if (!*++argv)
-                ++error;
-            display_exponent = atof(*argv);
-            if (display_exponent <= 0.0)
-                ++error;
-        } else if (!strcmp(*argv, "-bgcolor")) {
-            if (!*++argv)
-                ++error;
-            bgstr = *argv;
-            if (strlen(bgstr) != 7 || bgstr[0] != '#')
-                ++error;
             else
-                have_bg = TRUE;
+                displayname = *argv;
+        } else if (!strncmp(*argv, "-gamma", 2)) {
+            if (!*++argv)
+                ++error;
+            else {
+                display_exponent = atof(*argv);
+                if (display_exponent <= 0.0)
+                    ++error;
+            }
+        } else if (!strncmp(*argv, "-bgcolor", 2)) {
+            if (!*++argv)
+                ++error;
+            else {
+                bgstr = *argv;
+                if (strlen(bgstr) != 7 || bgstr[0] != '#')
+                    ++error; 
+                else 
+                    have_bg = TRUE;
+            }
         } else {
             if (**argv != '-') {
                 filename = *argv;
@@ -222,8 +238,7 @@
         fprintf(stderr, PROGNAME ":  can't open PNG file [%s]\n", filename);
         ++error;
     } else {
-        if ((rc = readpng_init(infile, (long *)(&image_width),
-                               (long *)(&image_height))) != 0) {
+        if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
             switch (rc) {
                 case 1:
                     fprintf(stderr, PROGNAME
@@ -257,21 +272,25 @@
             fclose(infile);
     }
 
+
+    /* usage screen */
+
     if (error) {
         fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
         readpng_version_info();
         fprintf(stderr, "\n"
-         "Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
-         "    xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
-         "    exp \ttransfer-function exponent (``gamma'') of the display\n"
-         "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
-         "\t\t  to the product of the lookup-table exponent (varies)\n"
-         "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
-         "    bg  \tdesired background color in 7-character hex RGB format\n"
-         "\t\t  (e.g., ``#ff7f00'' for orange:  same as HTML colors);\n"
-         "\t\t  used with transparent images\n"
-         "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
-         "\n", PROGNAME, default_display_exponent);
+          "Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n"
+          "    xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
+          "    exp \ttransfer-function exponent (``gamma'') of the display\n"
+          "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
+          "\t\t  to the product of the lookup-table exponent (varies)\n"
+          "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
+          "    bg  \tdesired background color in 7-character hex RGB format\n"
+          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
+          "\t\t  used with transparent images\n"
+          "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
+          "is displayed) to quit.\n"
+          "\n", PROGNAME, default_display_exponent);
         exit(1);
     }
 
@@ -344,6 +363,10 @@
 
     /* wait for the user to tell us when to quit */
 
+    printf(
+      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+    fflush(stdout);
+
     do
         XNextEvent(display, &e);
     while (!(e.type == ButtonPress && e.xbutton.button == Button1) &&
@@ -362,11 +385,13 @@
 
 
 
-static int rpng_x_create_window()
+static int rpng_x_create_window(void)
 {
     uch *xdata;
+    int need_colormap = FALSE;
     int screen, pad;
     ulg bg_pixel = 0L;
+    ulg attrmask;
     Window root;
     XEvent e;
     XGCValues gcvalues;
@@ -378,11 +403,15 @@
     XWMHints *wm_hints;
 
 
-    bitmap_order = BitmapBitOrder(display);
     screen = DefaultScreen(display);
     depth = DisplayPlanes(display, screen);
     root = RootWindow(display, screen);
 
+#ifdef DEBUG
+    XSynchronize(display, True);
+#endif
+
+#if 0
 /* GRR:  add 8-bit support */
     if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
         fprintf(stderr,
@@ -394,27 +423,73 @@
     XMatchVisualInfo(display, screen, depth,
       (depth == 8)? PseudoColor : TrueColor, &visual_info);
     visual = visual_info.visual;
+#else
+    if (depth != 16 && depth != 24 && depth != 32) {
+        int visuals_matched = 0;
 
-    RedMask   = visual->red_mask;
-    GreenMask = visual->green_mask;
-    BlueMask  = visual->blue_mask;
+        Trace((stderr, "default depth is %d:  checking other visuals\n",
+          depth))
+
+        /* 24-bit first */
+        visual_info.screen = screen;
+        visual_info.depth = 24;
+        visual_list = XGetVisualInfo(display,
+          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
+        if (visuals_matched == 0) {
+/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
+            fprintf(stderr, "default screen depth %d not supported, and no"
+              " 24-bit visuals found\n", depth);
+            return 2;
+        }
+        Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
+          visuals_matched))
+        visual = visual_list[0].visual;
+        depth = visual_list[0].depth;
+/*
+        colormap_size = visual_list[0].colormap_size;
+        visual_class = visual->class;
+        visualID = XVisualIDFromVisual(visual);
+ */
+        have_nondefault_visual = TRUE;
+        need_colormap = TRUE;
+    } else {
+        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
+        visual = visual_info.visual;
+    }
+#endif
+
+    RMask = visual->red_mask;
+    GMask = visual->green_mask;
+    BMask = visual->blue_mask;
 
 /* GRR:  add/check 8-bit support */
-    if (depth == 8) {
+    if (depth == 8 || need_colormap) {
         colormap = XCreateColormap(display, root, visual, AllocNone);
         if (!colormap) {
             fprintf(stderr, "XCreateColormap() failed\n");
             return 2;
         }
         have_colormap = TRUE;
-    } else if (depth == 16) {
-        RPixelShift = 15 - rpng_x_msb(RedMask); /* these are right-shifts */
-        GPixelShift = 15 - rpng_x_msb(GreenMask);
-        BPixelShift = 15 - rpng_x_msb(BlueMask);
-    } else /* if (depth > 16) */ {
-        RPixelShift = rpng_x_msb(RedMask) - 7; /* these are left-shifts */
-        GPixelShift = rpng_x_msb(GreenMask) - 7;
-        BPixelShift = rpng_x_msb(BlueMask) - 7;
+    }
+    if (depth == 15 || depth == 16) {
+        RShift = 15 - rpng_x_msb(RMask);    /* these are right-shifts */
+        GShift = 15 - rpng_x_msb(GMask);
+        BShift = 15 - rpng_x_msb(BMask);
+    } else if (depth > 16) {
+#define NO_24BIT_MASKS
+#ifdef NO_24BIT_MASKS
+        RShift = rpng_x_msb(RMask) - 7;     /* these are left-shifts */
+        GShift = rpng_x_msb(GMask) - 7;
+        BShift = rpng_x_msb(BMask) - 7;
+#else
+        RShift = 7 - rpng_x_msb(RMask);     /* these are right-shifts, too */
+        GShift = 7 - rpng_x_msb(GMask);
+        BShift = 7 - rpng_x_msb(BMask);
+#endif
+    }
+    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
+        fprintf(stderr, "rpng internal logic error:  negative X shift(s)!\n");
+        return 2;
     }
 
 /*---------------------------------------------------------------------------
@@ -423,9 +498,16 @@
 
     attr.backing_store = Always;
     attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+    attrmask = CWBackingStore | CWEventMask;
+    if (have_nondefault_visual) {
+        attr.colormap = colormap;
+        attr.background_pixel = 0;
+        attr.border_pixel = 1;
+        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
+    }
 
-    window = XCreateWindow(display, root, 0, 0, image_width, image_height,
-      0, depth, InputOutput, visual, CWBackingStore | CWEventMask, &attr);
+    window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0,
+      depth, InputOutput, visual, attrmask, &attr);
 
     if (window == None) {
         fprintf(stderr, "XCreateWindow() failed\n");
@@ -446,8 +528,8 @@
     if ((size_hints = XAllocSizeHints()) != NULL) {
         /* window will not be resizable */
         size_hints->flags = PMinSize | PMaxSize;
-        size_hints->min_width = size_hints->max_width = image_width;
-        size_hints->min_height = size_hints->max_height = image_height;
+        size_hints->min_width = size_hints->max_width = (int)image_width;
+        size_hints->min_height = size_hints->max_height = (int)image_height;
     }
 
     if ((wm_hints = XAllocWMHints()) != NULL) {
@@ -469,13 +551,13 @@
   ---------------------------------------------------------------------------*/
 
     if (depth == 24 || depth == 32) {
-        bg_pixel = ((ulg)bg_red   << RPixelShift) |
-                   ((ulg)bg_green << GPixelShift) |
-                   ((ulg)bg_blue  << BPixelShift);
+        bg_pixel = ((ulg)bg_red   << RShift) |
+                   ((ulg)bg_green << GShift) |
+                   ((ulg)bg_blue  << BShift);
     } else if (depth == 16) {
-        bg_pixel = ((((ulg)bg_red   << 8) >> RPixelShift) & RedMask)   |
-                   ((((ulg)bg_green << 8) >> GPixelShift) & GreenMask) |
-                   ((((ulg)bg_blue  << 8) >> BPixelShift) & BlueMask);
+        bg_pixel = ((((ulg)bg_red   << 8) >> RShift) & RMask) |
+                   ((((ulg)bg_green << 8) >> GShift) & GMask) |
+                   ((((ulg)bg_blue  << 8) >> BShift) & BMask);
     } else /* depth == 8 */ {
 
         /* GRR:  add 8-bit support */
@@ -524,7 +606,7 @@
         return 3;
     }
 
-    /* to avoid testing the bitmap_order every pixel (or doubling the size of
+    /* to avoid testing the byte order every pixel (or doubling the size of
      * the drawing routine with a giant if-test), we arbitrarily set the byte
      * order to MSBFirst and let Xlib worry about inverting things on little-
      * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most
@@ -541,20 +623,24 @@
 
 
 
-static int rpng_x_display_image()
+static int rpng_x_display_image(void)
 {
     uch *src;
     char *dest;
     uch r, g, b, a;
-    int ximage_rowbytes = ximage->bytes_per_line;
     ulg i, row, lastrow = 0;
     ulg pixel;
+    int ximage_rowbytes = ximage->bytes_per_line;
+/*  int bpp = ximage->bits_per_pixel;  */
 
 
     Trace((stderr, "beginning display loop (image_channels == %d)\n",
       image_channels))
-    Trace((stderr, "(width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
+    Trace((stderr, "   (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n",
       image_width, image_rowbytes, ximage_rowbytes))
+    Trace((stderr, "   (bpp = %d)\n", ximage->bits_per_pixel))
+    Trace((stderr, "   (byte_order = %s)\n", ximage->byte_order == MSBFirst?
+      "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown")))
 
     if (depth == 24 || depth == 32) {
         ulg red, green, blue;
@@ -567,14 +653,27 @@
                     red   = *src++;
                     green = *src++;
                     blue  = *src++;
-                    pixel = (red   << RPixelShift) |
-                            (green << GPixelShift) |
-                            (blue  << BPixelShift);
+#ifdef NO_24BIT_MASKS
+                    pixel = (red   << RShift) |
+                            (green << GShift) |
+                            (blue  << BShift);
                     /* recall that we set ximage->byte_order = MSBFirst above */
-                    *dest++ = ((uch *)&pixel)[3];
-                    *dest++ = ((uch *)&pixel)[2];
-                    *dest++ = ((uch *)&pixel)[1];
-                    *dest++ = ((uch *)&pixel)[0];
+                    /* GRR BUG:  this assumes bpp == 32, but may be 24: */
+                    *dest++ = (char)((pixel >> 24) & 0xff);
+                    *dest++ = (char)((pixel >> 16) & 0xff);
+                    *dest++ = (char)((pixel >>  8) & 0xff);
+                    *dest++ = (char)( pixel        & 0xff);
+#else
+                    red   = (RShift < 0)? red   << (-RShift) : red   >> RShift;
+                    green = (GShift < 0)? green << (-GShift) : green >> GShift;
+                    blue  = (BShift < 0)? blue  << (-BShift) : blue  >> BShift;
+                    pixel = (red & RMask) | (green & GMask) | (blue & BMask);
+                    /* recall that we set ximage->byte_order = MSBFirst above */
+                    *dest++ = (char)((pixel >> 24) & 0xff);
+                    *dest++ = (char)((pixel >> 16) & 0xff);
+                    *dest++ = (char)((pixel >>  8) & 0xff);
+                    *dest++ = (char)( pixel        & 0xff);
+#endif
                 }
             } else /* if (image_channels == 4) */ {
                 for (i = image_width;  i > 0;  --i) {
@@ -598,20 +697,20 @@
                         alpha_composite(green, g, a, bg_green);
                         alpha_composite(blue,  b, a, bg_blue);
                     }
-                    pixel = (red   << RPixelShift) |
-                            (green << GPixelShift) |
-                            (blue  << BPixelShift);
+                    pixel = (red   << RShift) |
+                            (green << GShift) |
+                            (blue  << BShift);
                     /* recall that we set ximage->byte_order = MSBFirst above */
-                    *dest++ = ((uch *)&pixel)[3];
-                    *dest++ = ((uch *)&pixel)[2];
-                    *dest++ = ((uch *)&pixel)[1];
-                    *dest++ = ((uch *)&pixel)[0];
+                    *dest++ = (char)((pixel >> 24) & 0xff);
+                    *dest++ = (char)((pixel >> 16) & 0xff);
+                    *dest++ = (char)((pixel >>  8) & 0xff);
+                    *dest++ = (char)( pixel        & 0xff);
                 }
             }
             /* display after every 16 lines */
             if (((row+1) & 0xf) == 0) {
-                XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
-                  image_width, 16);
+                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+                  (int)lastrow, image_width, 16);
                 XFlush(display);
                 lastrow = row + 1;
             }
@@ -631,12 +730,12 @@
                     ++src;
                     blue  = ((ush)(*src) << 8);
                     ++src;
-                    pixel = ((red   >> RPixelShift) & RedMask)   |
-                            ((green >> GPixelShift) & GreenMask) |
-                            ((blue  >> BPixelShift) & BlueMask);
+                    pixel = ((red   >> RShift) & RMask) |
+                            ((green >> GShift) & GMask) |
+                            ((blue  >> BShift) & BMask);
                     /* recall that we set ximage->byte_order = MSBFirst above */
-                    *dest++ = ((uch *)&pixel)[1];
-                    *dest++ = ((uch *)&pixel)[0];
+                    *dest++ = (char)((pixel >>  8) & 0xff);
+                    *dest++ = (char)( pixel        & 0xff);
                 }
             } else /* if (image_channels == 4) */ {
                 for (i = image_width;  i > 0;  --i) {
@@ -663,18 +762,18 @@
                         green = ((ush)g << 8);
                         blue  = ((ush)b << 8);
                     }
-                    pixel = ((red   >> RPixelShift) & RedMask)   |
-                            ((green >> GPixelShift) & GreenMask) |
-                            ((blue  >> BPixelShift) & BlueMask);
+                    pixel = ((red   >> RShift) & RMask) |
+                            ((green >> GShift) & GMask) |
+                            ((blue  >> BShift) & BMask);
                     /* recall that we set ximage->byte_order = MSBFirst above */
-                    *dest++ = ((uch *)&pixel)[1];
-                    *dest++ = ((uch *)&pixel)[0];
+                    *dest++ = (char)((pixel >>  8) & 0xff);
+                    *dest++ = (char)( pixel        & 0xff);
                 }
             }
             /* display after every 16 lines */
             if (((row+1) & 0xf) == 0) {
-                XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
-                  image_width, 16);
+                XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+                  (int)lastrow, image_width, 16);
                 XFlush(display);
                 lastrow = row + 1;
             }
@@ -688,8 +787,8 @@
 
     Trace((stderr, "calling final XPutImage()\n"))
     if (lastrow < image_height) {
-        XPutImage(display, window, gc, ximage, 0, lastrow, 0, lastrow,
-          image_width, image_height-lastrow);
+        XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0,
+          (int)lastrow, image_width, image_height-lastrow);
         XFlush(display);
     }
 
@@ -699,7 +798,7 @@
 
 
 
-static void rpng_x_cleanup()
+static void rpng_x_cleanup(void)
 {
     if (image_data) {
         free(image_data);
@@ -722,6 +821,9 @@
 
     if (have_colormap)
         XFreeColormap(display, colormap);
+
+    if (have_nondefault_visual)
+        XFree(visual_list);
 }
 
 
diff --git a/contrib/gregbook/rpng2-win.c b/contrib/gregbook/rpng2-win.c
index 66e682e..9bc66c7 100644
--- a/contrib/gregbook/rpng2-win.c
+++ b/contrib/gregbook/rpng2-win.c
@@ -22,10 +22,13 @@
    Changelog:
     - 1.01:  initial public release
     - 1.02:  fixed cut-and-paste error in usage screen (oops...)
+    - 1.03:  modified to allow abbreviated options
+    - 1.04:  removed bogus extra argument from usage fprintf() [Glenn R-P?];
+              fixed command-line parsing bug
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -52,14 +55,14 @@
 
 #define PROGNAME  "rpng2-win"
 #define LONGNAME  "Progressive PNG Viewer for Windows"
-#define VERSION   "1.02 of 22 September 1999"
+#define VERSION   "1.04 of 19 March 2000"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <setjmp.h>   /* for jmpbuf declaration in readpng2.h */
+#include <setjmp.h>    /* for jmpbuf declaration in readpng2.h */
 #include <time.h>
-#include <math.h>     /* only for PvdM background code */
+#include <math.h>      /* only for PvdM background code */
 #include <windows.h>
 
 /* all for PvdM background code: */
@@ -80,9 +83,9 @@
 #define rgb2_max   bg_bsat
 #define rgb2_min   bg_brot
 
-/* #define DEBUG */      /* this enables the Trace() macros */
+/* #define DEBUG */     /* this enables the Trace() macros */
 
-#include "readpng2.h"    /* typedefs, common macros, readpng2 prototypes */
+#include "readpng2.h"   /* typedefs, common macros, readpng2 prototypes */
 
 
 /* could just include png.h, but this macro is the only thing we need
@@ -90,18 +93,18 @@
  * only happen with alpha (which could easily be avoided with
  * "ush acopy = (alpha);") */
 
-#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 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 INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
-                        *  block size corresponds roughly to a download
-                        *  speed 10% faster than theoretical 33.6K maximum
-                        *  (assuming 8 data bits, 1 stop bit and no other
-                        *  overhead) */
+#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this
+                          *  block size corresponds roughly to a download
+                          *  speed 10% faster than theoretical 33.6K maximum
+                          *  (assuming 8 data bits, 1 stop bit and no other
+                          *  overhead) */
 
 /* local prototypes */
 static void       rpng2_win_init(void);
@@ -116,7 +119,7 @@
 static char titlebar[1024], *window_name = titlebar;
 static char *progname = PROGNAME;
 static char *appname = LONGNAME;
-static char *icon_name = PROGNAME; /* GRR:  not (yet) used */
+static char *icon_name = PROGNAME;    /* GRR:  not (yet) used */
 static char *filename;
 static FILE *infile;
 
@@ -125,7 +128,7 @@
 static uch inbuf[INBUFSIZE];
 static int incount;
 
-static int pat = 6;       /* must be less than num_bgpat */
+static int pat = 6;         /* must be less than num_bgpat */
 static int bg_image = 0;
 static int bgscale = 16;
 static ulg bg_rowbytes;
@@ -134,22 +137,22 @@
 static struct rgb_color {
     uch r, g, b;
 } rgb[] = {
-    {  0,   0,   0},   /*  0:  black */
-    {255, 255, 255},   /*  1:  white */
-    {173, 132,  57},   /*  2:  tan */
-    { 64, 132,   0},   /*  3:  medium green */
-    {189, 117,   1},   /*  4:  gold */
-    {253, 249,   1},   /*  5:  yellow */
-    {  0,   0, 255},   /*  6:  blue */
-    {  0,   0, 120},   /*  7:  medium blue */
-    {255,   0, 255},   /*  8:  magenta */
-    { 64,   0,  64},   /*  9:  dark magenta */
-    {255,   0,   0},   /* 10:  red */
-    { 64,   0,   0},   /* 11:  dark red */
-    {255, 127,   0},   /* 12:  orange */
-    {192,  96,   0},   /* 13:  darker orange */
-    { 24,  60,   0},   /* 14:  dark green-yellow */
-    { 85, 125, 200}    /* 15:  ice blue */
+    {  0,   0,   0},    /*  0:  black */
+    {255, 255, 255},    /*  1:  white */
+    {173, 132,  57},    /*  2:  tan */
+    { 64, 132,   0},    /*  3:  medium green */
+    {189, 117,   1},    /*  4:  gold */
+    {253, 249,   1},    /*  5:  yellow */
+    {  0,   0, 255},    /*  6:  blue */
+    {  0,   0, 120},    /*  7:  medium blue */
+    {255,   0, 255},    /*  8:  magenta */
+    { 64,   0,  64},    /*  9:  dark magenta */
+    {255,   0,   0},    /* 10:  red */
+    { 64,   0,   0},    /* 11:  dark red */
+    {255, 127,   0},    /* 12:  orange */
+    {192,  96,   0},    /* 13:  darker orange */
+    { 24,  60,   0},    /* 14:  dark green-yellow */
+    { 85, 125, 200}     /* 15:  ice blue */
 };
 /* not used for now, but should be for error-checking:
 static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color);
@@ -174,25 +177,25 @@
  */
 static struct background_pattern {
     ush type;
-    int rgb1_max, rgb1_min;   /* or bg_freq, bg_gray */
-    int rgb2_max, rgb2_min;   /* or bg_bsat, bg_brot (both scaled by 10)*/
+    int rgb1_max, rgb1_min;     /* or bg_freq, bg_gray */
+    int rgb2_max, rgb2_min;     /* or bg_bsat, bg_brot (both scaled by 10)*/
 } bg[] = {
-    {0+8,   2,0,  1,15},       /* checkered:  tan/black vs. white/ice blue */
-    {0+24,  2,0,  1,0},        /* checkered:  tan/black vs. white/black */
-    {0+8,   4,5,  0,2},        /* checkered:  gold/yellow vs. black/tan */
-    {0+8,   4,5,  0,6},        /* checkered:  gold/yellow vs. black/blue */
-    {0,     7,0,  8,9},        /* checkered:  deep blue/black vs. magenta */
-    {0+8,  13,0,  5,14},       /* checkered:  orange/black vs. yellow */
-    {0+8,  12,0, 10,11},       /* checkered:  orange/black vs. red */
-    {1,     7,0,  8,0},        /* diamonds:  deep blue/black vs. magenta */
-    {1,    12,0, 11,0},        /* diamonds:  orange vs. dark red */
-    {1,    10,0,  7,0},        /* diamonds:  red vs. medium blue */
-    {1,     4,0,  5,0},        /* diamonds:  gold vs. yellow */
-    {1,     3,0,  0,0},        /* diamonds:  medium green vs. black */
-    {2,    16, 100,  20,   0}, /* radial:  ~hard radial color-beams */
-    {2,    18, 100,  10,   2}, /* radial:  soft, curved radial color-beams */
-    {2,    16, 256, 100, 250}, /* radial:  very tight spiral */
-    {2, 10000, 256,  11,   0}  /* radial:  dipole-moire' (almost fractal) */
+    {0+8,   2,0,  1,15},        /* checkered:  tan/black vs. white/ice blue */
+    {0+24,  2,0,  1,0},         /* checkered:  tan/black vs. white/black */
+    {0+8,   4,5,  0,2},         /* checkered:  gold/yellow vs. black/tan */
+    {0+8,   4,5,  0,6},         /* checkered:  gold/yellow vs. black/blue */
+    {0,     7,0,  8,9},         /* checkered:  deep blue/black vs. magenta */
+    {0+8,  13,0,  5,14},        /* checkered:  orange/black vs. yellow */
+    {0+8,  12,0, 10,11},        /* checkered:  orange/black vs. red */
+    {1,     7,0,  8,0},         /* diamonds:  deep blue/black vs. magenta */
+    {1,    12,0, 11,0},         /* diamonds:  orange vs. dark red */
+    {1,    10,0,  7,0},         /* diamonds:  red vs. medium blue */
+    {1,     4,0,  5,0},         /* diamonds:  gold vs. yellow */
+    {1,     3,0,  0,0},         /* diamonds:  medium green vs. black */
+    {2,    16, 100,  20,   0},  /* radial:  ~hard radial color-beams */
+    {2,    18, 100,  10,   2},  /* radial:  soft, curved radial color-beams */
+    {2,    16, 256, 100, 250},  /* radial:  very tight spiral */
+    {2, 10000, 256,  11,   0}   /* radial:  dipole-moire' (almost fractal) */
 };
 static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern);
 
@@ -212,16 +215,17 @@
 
 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode)
 {
-    char *args[1024];   /* arbitrary limit, but should suffice */
-    char *p, *q, *bgstr = NULL, **argv = args;
+    char *args[1024];                 /* arbitrary limit, but should suffice */
+    char **argv = args;
+    char *p, *q, *bgstr = NULL;
     int argc = 0;
     int rc, alen, flen;
     int error = 0;
     int timing = FALSE;
     int have_bg = FALSE;
-    double LUT_exponent;             /* just the lookup table */
-    double CRT_exponent = 2.2;       /* just the monitor */
-    double default_display_exponent; /* whole display system */
+    double LUT_exponent;              /* just the lookup table */
+    double CRT_exponent = 2.2;        /* just the monitor */
+    double default_display_exponent;  /* whole display system */
     MSG msg;
 
 
@@ -316,33 +320,39 @@
     /* Now parse the command line for options and the PNG filename. */
 
     while (*++argv && !error) {
-        if (!strcmp(*argv, "-gamma")) {
+        if (!strncmp(*argv, "-gamma", 2)) {
             if (!*++argv)
                 ++error;
-            rpng2_info.display_exponent = atof(*argv);
-            if (rpng2_info.display_exponent <= 0.0)
-                ++error;
-        } else if (!strcmp(*argv, "-bgcolor")) {
-            if (!*++argv)
-                ++error;
-            bgstr = *argv;
-            if (strlen(bgstr) != 7 || bgstr[0] != '#')
-                ++error;
             else {
-                have_bg = TRUE;
-                bg_image = FALSE;
+                rpng2_info.display_exponent = atof(*argv);
+                if (rpng2_info.display_exponent <= 0.0)
+                    ++error;
             }
-        } else if (!strcmp(*argv, "-bgpat")) {
+        } else if (!strncmp(*argv, "-bgcolor", 4)) {
             if (!*++argv)
                 ++error;
-            pat = atoi(*argv) - 1;
-            if (pat < 0 || pat >= num_bgpat)
+            else {
+                bgstr = *argv;
+                if (strlen(bgstr) != 7 || bgstr[0] != '#')
+                    ++error;
+                else {
+                    have_bg = TRUE;
+                    bg_image = FALSE;
+                }
+            }
+        } else if (!strncmp(*argv, "-bgpat", 4)) {
+            if (!*++argv)
                 ++error;
             else {
-                bg_image = TRUE;
-                have_bg = FALSE;
+                pat = atoi(*argv) - 1;
+                if (pat < 0 || pat >= num_bgpat)
+                    ++error;
+                else {
+                    bg_image = TRUE;
+                    have_bg = FALSE;
+                }
             }
-        } else if (!strcmp(*argv, "-timing")) {
+        } else if (!strncmp(*argv, "-timing", 2)) {
             timing = TRUE;
         } else {
             if (**argv != '-') {
@@ -387,6 +397,9 @@
             fclose(infile);
     }
 
+
+    /* usage screen */
+
     if (error) {
         fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
         readpng2_version_info();
@@ -398,14 +411,14 @@
           "\t\t  to the product of the lookup-table exponent (varies)\n"
           "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
           "    bg  \tdesired background color in 7-character hex RGB format\n"
-          "\t\t  (e.g., ``#ff7f00'' for orange:  same as HTML colors);\n"
+          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
           "\t\t  used with transparent images; overrides -bgpat\n"
           "    pat \tdesired background pattern number (1-%d); used with\n"
           "\t\t  transparent images; overrides -bgcolor\n"
           "    -timing\tenables delay for every block read, to simulate modem\n"
           "\t\t  download of image (~36 Kbps)\n"
           "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
-          "\n", PROGNAME, " ", default_display_exponent, num_bgpat);
+          "\n", PROGNAME, default_display_exponent, num_bgpat);
         exit(1);
     }
 
@@ -560,7 +573,7 @@
     if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) +
                               wimage_rowbytes*rpng2_info.height)))
     {
-        return 4; /* fail */
+        return 4;   /* fail */
     }
 
 /*---------------------------------------------------------------------------
@@ -655,7 +668,7 @@
         TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len);
         ReleaseDC(global_hwnd, hdc);
 
-        rpng2_win_load_bg_image(); /* resets bg_image if fails */
+        rpng2_win_load_bg_image();   /* resets bg_image if fails */
     }
 
     if (!bg_image) {
@@ -753,7 +766,7 @@
                 even_odd = even_odd_vert ^ even_odd_horiz;
                 invert_column =
                   (even_odd_horiz && (bg[pat].type & 0x10));
-                if (even_odd == 0) {   /* gradient #1 */
+                if (even_odd == 0) {         /* gradient #1 */
                     if (invert_column) {
                         *dest++ = r1_inv;
                         *dest++ = g1_inv;
@@ -763,16 +776,16 @@
                         *dest++ = g1;
                         *dest++ = b1;
                     }
-                } else {                /* gradient #2 */
+                } else {                     /* gradient #2 */
                     if ((invert_column && invert_gradient2) ||
                         (!invert_column && !invert_gradient2))
                     {
-                        *dest++ = r2;      /* not inverted or */
-                        *dest++ = g2;      /*  doubly inverted */
+                        *dest++ = r2;        /* not inverted or */
+                        *dest++ = g2;        /*  doubly inverted */
                         *dest++ = b2;
                     } else {
                         *dest++ = r2_inv;
-                        *dest++ = g2_inv;  /* singly inverted */
+                        *dest++ = g2_inv;    /* singly inverted */
                         *dest++ = b2_inv;
                     }
                 }
@@ -908,7 +921,7 @@
             g1 = *src++;
             b1 = *src++;
             *dest++ = b1;
-            *dest++ = g1; /* note reverse order */
+            *dest++ = g1;   /* note reverse order */
             *dest++ = r1;
         }
     }
@@ -962,7 +975,7 @@
             g = *src++;
             b = *src++;
             *dest++ = b;
-            *dest++ = g; /* note reverse order */
+            *dest++ = g;   /* note reverse order */
             *dest++ = r;
         }
     } else /* if (rpng2_info.channels == 4) */ {
@@ -1028,7 +1041,9 @@
      * that the image is done */
 
     rpng2_info.done = TRUE;
-    printf("Done.  Press Q, Esc or mouse button 1 to quit.\n");
+    printf(
+      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+    fflush(stdout);
 }
 
 
@@ -1084,15 +1099,15 @@
 
         /* wait for the user to tell us when to quit */
         case WM_CHAR:
-            switch (wP) { /* only need one, so ignore repeat count */
+            switch (wP) {       /* only need one, so ignore repeat count */
                 case 'q':
                 case 'Q':
-                case 0x1B: /* Esc key */
+                case 0x1B:      /* Esc key */
                     PostQuitMessage(0);
             }
             return 0;
 
-        case WM_LBUTTONDOWN: /* another way of quitting */
+        case WM_LBUTTONDOWN:    /* another way of quitting */
         case WM_DESTROY:
             PostQuitMessage(0);
             return 0;
diff --git a/contrib/gregbook/rpng2-x.c b/contrib/gregbook/rpng2-x.c
index 8e536e7..47ab5b9 100644
--- a/contrib/gregbook/rpng2-x.c
+++ b/contrib/gregbook/rpng2-x.c
@@ -6,9 +6,11 @@
    a web browser (though the front end is only set up to read from files).
    It supports gamma correction, user-specified background colors, and user-
    specified background patterns (for transparent images).  This version is
-   for the X Window System (tested under Unix, but may work under VMS or OS/2
-   with a little tweaking).  Thanks to Adam Costello and Pieter S. van der
-   Meulen for the "diamond" and "radial waves" patterns, respectively.
+   for the X Window System (tested by the author under Unix and by Martin
+   Zinser under OpenVMS; may work under OS/2 with a little tweaking).
+
+   Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond"
+   and "radial waves" patterns, respectively.
 
    to do:
     - 8-bit support
@@ -17,7 +19,16 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+   Changelog:
+    - 1.01:  initial public release
+    - 1.02:  modified to allow abbreviated options; fixed char/uchar mismatch
+    - 1.10:  added support for non-default visuals; fixed X pixel-conversion
+    - 1.11:  added -usleep option for demos; fixed command-line parsing bug
+    - 1.12:  added -pause option for demos and testing
+
+  ---------------------------------------------------------------------------
+
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -44,21 +55,21 @@
 
 #define PROGNAME  "rpng2-x"
 #define LONGNAME  "Progressive PNG Viewer for X"
-#define VERSION   "1.01 of 31 March 1999"
+#define VERSION   "1.12 of 19 March 2000"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <setjmp.h> /* for jmpbuf declaration in readpng2.h */
+#include <setjmp.h>       /* for jmpbuf declaration in readpng2.h */
 #include <time.h>
-#include <math.h>   /* only for PvdM background code */
+#include <math.h>         /* only for PvdM background code */
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/Xos.h>
-#include <X11/keysym.h> /* defines XK_* macros */
+#include <X11/keysym.h>   /* defines XK_* macros */
 
 #ifdef VMS
-#include <unistd.h>
+#  include <unistd.h>
 #endif
 
 /* all for PvdM background code: */
@@ -79,9 +90,9 @@
 #define rgb2_max   bg_bsat
 #define rgb2_min   bg_brot
 
-/* #define DEBUG */ /* this enables the Trace() macros */
+/* #define DEBUG */     /* this enables the Trace() macros */
 
-#include "readpng2.h" /* typedefs, common macros, readpng2 prototypes */
+#include "readpng2.h"   /* typedefs, common macros, readpng2 prototypes */
 
 
 /* could just include png.h, but this macro is the only thing we need
@@ -89,18 +100,18 @@
  * only happen with alpha (which could easily be avoided with
  * "ush acopy = (alpha);") */
 
-#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 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 INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this
-                        *  block size corresponds roughly to a download
-                        *  speed 10% faster than theoretical 33.6K maximum
-                        *  (assuming 8 data bits, 1 stop bit and no other
-                        *  overhead) */
+#define INBUFSIZE 4096   /* with pseudo-timing on (1 sec delay/block), this
+                          *  block size corresponds roughly to a download
+                          *  speed 10% faster than theoretical 33.6K maximum
+                          *  (assuming 8 data bits, 1 stop bit and no other
+                          *  overhead) */
 
 /* local prototypes */
 static void rpng2_x_init(void);
@@ -123,12 +134,16 @@
 static uch inbuf[INBUFSIZE];
 static int incount;
 
-static int pat = 6;  /* must be less than num_bgpat */
+static int pat = 6;        /* must be less than num_bgpat */
 static int bg_image = 0;
 static int bgscale = 16;
 static ulg bg_rowbytes;
 static uch *bg_data;
 
+int pause_after_pass = FALSE;
+int demo_timing = FALSE;
+ulg usleep_duration = 0L;
+
 static struct rgb_color {
     uch r, g, b;
 } rgb[] = {
@@ -201,12 +216,14 @@
 static Display *display;
 static int depth;
 static Visual *visual;
-static int RPixelShift, GPixelShift, BPixelShift;
-static ulg RedMask, GreenMask, BlueMask;
+static XVisualInfo *visual_list;
+static int RShift, GShift, BShift;
+static ulg RMask, GMask, BMask;
 static Window window;
 static GC gc;
 static Colormap colormap;
 
+static int have_nondefault_visual = FALSE;
 static int have_colormap = FALSE;
 static int have_window = FALSE;
 
@@ -294,37 +311,53 @@
     /* Now parse the command line for options and the PNG filename. */
 
     while (*++argv && !error) {
-        if (!strcmp(*argv, "-display")) {
+        if (!strncmp(*argv, "-display", 2)) {
             if (!*++argv)
                 ++error;
-            displayname = *argv;
-        } else if (!strcmp(*argv, "-gamma")) {
+            else
+                displayname = *argv;
+        } else if (!strncmp(*argv, "-gamma", 2)) {
             if (!*++argv)
                 ++error;
-            rpng2_info.display_exponent = atof(*argv);
-            if (rpng2_info.display_exponent <= 0.0)
-                ++error;
-        } else if (!strcmp(*argv, "-bgcolor")) {
-            if (!*++argv)
-                ++error;
-            bgstr = *argv;
-            if (strlen(bgstr) != 7 || bgstr[0] != '#')
-                ++error;
             else {
-                have_bg = TRUE;
-                bg_image = FALSE;
+                rpng2_info.display_exponent = atof(*argv);
+                if (rpng2_info.display_exponent <= 0.0)
+                    ++error;
             }
-        } else if (!strcmp(*argv, "-bgpat")) {
+        } else if (!strncmp(*argv, "-bgcolor", 4)) {
             if (!*++argv)
                 ++error;
-            pat = atoi(*argv) - 1;
-            if (pat < 0 || pat >= num_bgpat)
+            else {
+                bgstr = *argv;
+                if (strlen(bgstr) != 7 || bgstr[0] != '#')
+                    ++error;
+                else {
+                    have_bg = TRUE;
+                    bg_image = FALSE;
+                }
+            }
+        } else if (!strncmp(*argv, "-bgpat", 4)) {
+            if (!*++argv)
                 ++error;
             else {
-                bg_image = TRUE;
-                have_bg = FALSE;
+                pat = atoi(*argv) - 1;
+                if (pat < 0 || pat >= num_bgpat)
+                    ++error;
+                else {
+                    bg_image = TRUE;
+                    have_bg = FALSE;
+                }
             }
-        } else if (!strcmp(*argv, "-timing")) {
+        } else if (!strncmp(*argv, "-usleep", 2)) {
+            if (!*++argv)
+                ++error;
+            else {
+                usleep_duration = (ulg)atol(*argv);
+                demo_timing = TRUE;
+            }
+        } else if (!strncmp(*argv, "-pause", 2)) {
+            pause_after_pass = TRUE;
+        } else if (!strncmp(*argv, "-timing", 2)) {
             timing = TRUE;
         } else {
             if (**argv != '-') {
@@ -377,25 +410,32 @@
             fclose(infile);
     }
 
+
+    /* usage screen */
+
     if (error) {
         fprintf(stderr, "\n%s %s:  %s\n", PROGNAME, VERSION, appname);
         readpng2_version_info();
         fprintf(stderr, "\n"
           "Usage:  %s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n"
-          "        %*s [-timing] file.png\n\n"
+          "        %*s [-usleep dur | -timing] [-pause] file.png\n\n"
           "    xdpy\tname of the target X display (e.g., ``hostname:0'')\n"
           "    exp \ttransfer-function exponent (``gamma'') of the display\n"
           "\t\t  system in floating-point format (e.g., ``%.1f''); equal\n"
           "\t\t  to the product of the lookup-table exponent (varies)\n"
           "\t\t  and the CRT exponent (usually 2.2); must be positive\n"
           "    bg  \tdesired background color in 7-character hex RGB format\n"
-          "\t\t  (e.g., ``#ff7f00'' for orange:  same as HTML colors);\n"
+          "\t\t  (e.g., ``#ff7700'' for orange:  same as HTML colors);\n"
           "\t\t  used with transparent images; overrides -bgpat\n"
           "    pat \tdesired background pattern number (1-%d); used with\n"
           "\t\t  transparent images; overrides -bgcolor\n"
+          "    dur \tduration in microseconds to wait after displaying each\n"
+          "\t\t  row (for demo purposes)\n"
           "    -timing\tenables delay for every block read, to simulate modem\n"
           "\t\t  download of image (~36 Kbps)\n"
-          "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n"
+          "    -pause\tpauses after displaying each pass until key pressed\n"
+          "\nPress Q, Esc or mouse button 1 (within image window, after image\n"
+          "is displayed) to quit.\n"
           "\n", PROGNAME, strlen(PROGNAME), " ", default_display_exponent,
           num_bgpat);
         exit(1);
@@ -489,7 +529,7 @@
  * in turn is called by libpng after all of the pre-IDAT chunks have been
  * read and processed--i.e., we now have enough info to finish initializing */
 
-static void rpng2_x_init()
+static void rpng2_x_init(void)
 {
     ulg i;
     ulg rowbytes = rpng2_info.rowbytes;
@@ -531,12 +571,14 @@
 
 
 
-static int rpng2_x_create_window()
+static int rpng2_x_create_window(void)
 {
     ulg bg_red   = rpng2_info.bg_red;
     ulg bg_green = rpng2_info.bg_green;
     ulg bg_blue  = rpng2_info.bg_blue;
     ulg bg_pixel = 0L;
+    ulg attrmask;
+    int need_colormap = FALSE;
     int screen, pad;
     uch *xdata;
     Window root;
@@ -556,39 +598,70 @@
     depth = DisplayPlanes(display, screen);
     root = RootWindow(display, screen);
 
-/* GRR:  add 8-bit support */
-    if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) {
-        fprintf(stderr,
-          "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n",
-          depth);
-        return 2;
+#ifdef DEBUG
+    XSynchronize(display, True);
+#endif
+
+    if (depth != 16 && depth != 24 && depth != 32) {
+        int visuals_matched = 0;
+
+        Trace((stderr, "default depth is %d:  checking other visuals\n",
+          depth))
+
+        /* 24-bit first */
+        visual_info.screen = screen;
+        visual_info.depth = 24;
+        visual_list = XGetVisualInfo(display,
+          VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched);
+        if (visuals_matched == 0) {
+/* GRR:  add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */
+            fprintf(stderr, "default screen depth %d not supported, and no"
+              " 24-bit visuals found\n", depth);
+            return 2;
+        }
+        Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n",
+          visuals_matched))
+        visual = visual_list[0].visual;
+        depth = visual_list[0].depth;
+/*
+        colormap_size = visual_list[0].colormap_size;
+        visual_class = visual->class;
+        visualID = XVisualIDFromVisual(visual);
+ */
+        have_nondefault_visual = TRUE;
+        need_colormap = TRUE;
+    } else {
+        XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info);
+        visual = visual_info.visual;
     }
 
-    XMatchVisualInfo(display, screen, depth,
-      (depth == 8)? PseudoColor : TrueColor, &visual_info);
-    visual = visual_info.visual;
-
-    RedMask   = visual->red_mask;
-    GreenMask = visual->green_mask;
-    BlueMask  = visual->blue_mask;
+    RMask = visual->red_mask;
+    GMask = visual->green_mask;
+    BMask = visual->blue_mask;
 
 /* GRR:  add/check 8-bit support */
-    if (depth == 8) {
+    if (depth == 8 || need_colormap) {
         colormap = XCreateColormap(display, root, visual, AllocNone);
         if (!colormap) {
             fprintf(stderr, "XCreateColormap() failed\n");
             return 2;
         }
         have_colormap = TRUE;
-        bg_image = FALSE; /* gradient just wastes palette entries */
-    } else if (depth == 16) {
-        RPixelShift = 15 - rpng2_x_msb(RedMask);   /* these are right-shifts */
-        GPixelShift = 15 - rpng2_x_msb(GreenMask);
-        BPixelShift = 15 - rpng2_x_msb(BlueMask);
-    } else /* if (depth > 16) */ {
-        RPixelShift = rpng2_x_msb(RedMask) - 7;    /* these are left-shifts */
-        GPixelShift = rpng2_x_msb(GreenMask) - 7;
-        BPixelShift = rpng2_x_msb(BlueMask) - 7;
+        if (depth == 8)
+            bg_image = FALSE;   /* gradient just wastes palette entries */
+    }
+    if (depth == 15 || depth == 16) {
+        RShift = 15 - rpng2_x_msb(RMask);    /* these are right-shifts */
+        GShift = 15 - rpng2_x_msb(GMask);
+        BShift = 15 - rpng2_x_msb(BMask);
+    } else if (depth > 16) {
+        RShift = rpng2_x_msb(RMask) - 7;     /* these are left-shifts */
+        GShift = rpng2_x_msb(GMask) - 7;
+        BShift = rpng2_x_msb(BMask) - 7;
+    }
+    if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) {
+        fprintf(stderr, "rpng2 internal logic error:  negative X shift(s)!\n");
+        return 2;
     }
 
 /*---------------------------------------------------------------------------
@@ -597,10 +670,16 @@
 
     attr.backing_store = Always;
     attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+    attrmask = CWBackingStore | CWEventMask;
+    if (have_nondefault_visual) {
+        attr.colormap = colormap;
+        attr.background_pixel = 0;
+        attr.border_pixel = 1;
+        attrmask |= CWColormap | CWBackPixel | CWBorderPixel;
+    }
 
     window = XCreateWindow(display, root, 0, 0, rpng2_info.width,
-      rpng2_info.height, 0, depth, InputOutput, visual,
-      CWBackingStore | CWEventMask, &attr);
+      rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr);
 
     if (window == None) {
         fprintf(stderr, "XCreateWindow() failed\n");
@@ -621,8 +700,9 @@
     if ((size_hints = XAllocSizeHints()) != NULL) {
         /* window will not be resizable */
         size_hints->flags = PMinSize | PMaxSize;
-        size_hints->min_width = size_hints->max_width = rpng2_info.width;
-        size_hints->min_height = size_hints->max_height = rpng2_info.height;
+        size_hints->min_width = size_hints->max_width = (int)rpng2_info.width;
+        size_hints->min_height = size_hints->max_height =
+          (int)rpng2_info.height;
     }
 
     if ((wm_hints = XAllocWMHints()) != NULL) {
@@ -668,7 +748,7 @@
         return 3;
     }
 
-    /* to avoid testing the bitmap order every pixel (or doubling the size of
+    /* to avoid testing the byte order every pixel (or doubling the size of
      * the drawing routine with a giant if-test), we arbitrarily set the byte
      * order to MSBFirst and let Xlib worry about inverting things on little-
      * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the
@@ -684,17 +764,17 @@
   ---------------------------------------------------------------------------*/
 
     if (bg_image)
-        rpng2_x_load_bg_image(); /* resets bg_image if fails */
+        rpng2_x_load_bg_image();    /* resets bg_image if fails */
 
     if (!bg_image) {
         if (depth == 24 || depth == 32) {
-            bg_pixel = (bg_red   << RPixelShift) |
-                       (bg_green << GPixelShift) |
-                       (bg_blue  << BPixelShift);
+            bg_pixel = (bg_red   << RShift) |
+                       (bg_green << GShift) |
+                       (bg_blue  << BShift);
         } else if (depth == 16) {
-            bg_pixel = (((bg_red   << 8) >> RPixelShift) & RedMask)   |
-                       (((bg_green << 8) >> GPixelShift) & GreenMask) |
-                       (((bg_blue  << 8) >> BPixelShift) & BlueMask);
+            bg_pixel = (((bg_red   << 8) >> RShift) & RMask) |
+                       (((bg_green << 8) >> GShift) & GMask) |
+                       (((bg_blue  << 8) >> BShift) & BMask);
         } else /* depth == 8 */ {
 
             /* GRR:  add 8-bit support */
@@ -723,7 +803,7 @@
 
 
 
-static int rpng2_x_load_bg_image()
+static int rpng2_x_load_bg_image(void)
 {
     uch *src;
     char *dest;
@@ -772,8 +852,8 @@
         int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min;
 
         for (row = 0;  row < rpng2_info.height;  ++row) {
-            yidx = row % bgscale;
-            even_odd_vert = (row / bgscale) & 1;
+            yidx = (int)(row % bgscale);
+            even_odd_vert = (int)((row / bgscale) & 1);
 
             r1 = r1_min + (r1_diff * yidx) / yidx_max;
             g1 = g1_min + (g1_diff * yidx) / yidx_max;
@@ -789,13 +869,13 @@
             g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max;
             b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max;
 
-            dest = (char *)(bg_data + row*bg_rowbytes);
+            dest = (char *)bg_data + row*bg_rowbytes;
             for (i = 0;  i < rpng2_info.width;  ++i) {
-                even_odd_horiz = (i / bgscale) & 1;
+                even_odd_horiz = (int)((i / bgscale) & 1);
                 even_odd = even_odd_vert ^ even_odd_horiz;
                 invert_column =
                   (even_odd_horiz && (bg[pat].type & 0x10));
-                if (even_odd == 0) { /* gradient #1 */
+                if (even_odd == 0) {        /* gradient #1 */
                     if (invert_column) {
                         *dest++ = r1_inv;
                         *dest++ = g1_inv;
@@ -805,16 +885,16 @@
                         *dest++ = g1;
                         *dest++ = b1;
                     }
-                } else {              /* gradient #2 */
+                } else {                    /* gradient #2 */
                     if ((invert_column && invert_gradient2) ||
                         (!invert_column && !invert_gradient2))
                     {
-                        *dest++ = r2;      /* not inverted or */
-                        *dest++ = g2;      /*  doubly inverted */
+                        *dest++ = r2;       /* not inverted or */
+                        *dest++ = g2;       /*  doubly inverted */
                         *dest++ = b2;
                     } else {
                         *dest++ = r2_inv;
-                        *dest++ = g2_inv;  /* singly inverted */
+                        *dest++ = g2_inv;   /* singly inverted */
                         *dest++ = b2_inv;
                     }
                 }
@@ -839,12 +919,12 @@
         b2 = rgb[bg[pat].rgb2_max].b;
 
         for (row = 0;  row < rpng2_info.height;  ++row) {
-            yidx = row % bgscale;
+            yidx = (int)(row % bgscale);
             if (yidx > hmax)
                 yidx = bgscale-1 - yidx;
-            dest = (char *)(bg_data + row*bg_rowbytes);
+            dest = (char *)bg_data + row*bg_rowbytes;
             for (i = 0;  i < rpng2_info.width;  ++i) {
-                xidx = i % bgscale;
+                xidx = (int)(i % bgscale);
                 if (xidx > hmax)
                     xidx = bgscale-1 - xidx;
                 k = xidx + yidx;
@@ -871,8 +951,8 @@
           PROGNAME);
         fflush(stderr);
 
-        hh = rpng2_info.height / 2;
-        hw = rpng2_info.width / 2;
+        hh = (int)(rpng2_info.height / 2);
+        hw = (int)(rpng2_info.width / 2);
 
         /* variables for radial waves:
          *   aoffset:  number of degrees to rotate hue [CURRENTLY NOT USED]
@@ -891,10 +971,10 @@
         maxDist = (double)((hw*hw) + (hh*hh));
 
         for (row = 0;  row < rpng2_info.height;  ++row) {
-            y = row - hh;
-            dest = (char *)(bg_data + row*bg_rowbytes);
+            y = (int)(row - hh);
+            dest = (char *)bg_data + row*bg_rowbytes;
             for (i = 0;  i < rpng2_info.width;  ++i) {
-                x = i - hw;
+                x = (int)(i - hw);
                 angle = (x == 0)? PI_2 : atan((double)y / (double)x);
                 gray = (double)MAX(ABS(y), ABS(x)) / grayspot;
                 gray = MIN(1.0, gray);
@@ -951,14 +1031,15 @@
                 red   = *src++;
                 green = *src++;
                 blue  = *src++;
-                pixel = (red   << RPixelShift) |
-                        (green << GPixelShift) |
-                        (blue  << BPixelShift);
+                pixel = (red   << RShift) |
+                        (green << GShift) |
+                        (blue  << BShift);
                 /* recall that we set ximage->byte_order = MSBFirst above */
-                *dest++ = ((uch *)&pixel)[3];
-                *dest++ = ((uch *)&pixel)[2];
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                /* GRR BUG:  this assumes bpp == 32, but may be 24: */
+                *dest++ = (char)((pixel >> 24) & 0xff);
+                *dest++ = (char)((pixel >> 16) & 0xff);
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         }
 
@@ -969,18 +1050,15 @@
             src = bg_data + row*bg_rowbytes;
             dest = ximage->data + row*ximage_rowbytes;
             for (i = rpng2_info.width;  i > 0;  --i) {
-                red   = ((ush)(*src) << 8);
-                ++src;
-                green = ((ush)(*src) << 8);
-                ++src;
-                blue  = ((ush)(*src) << 8);
-                ++src;
-                pixel = ((red   >> RPixelShift) & RedMask)   |
-                        ((green >> GPixelShift) & GreenMask) |
-                        ((blue  >> BPixelShift) & BlueMask);
+                red   = ((ush)(*src) << 8);  ++src;
+                green = ((ush)(*src) << 8);  ++src;
+                blue  = ((ush)(*src) << 8);  ++src;
+                pixel = ((red   >> RShift) & RMask) |
+                        ((green >> GShift) & GMask) |
+                        ((blue  >> BShift) & BMask);
                 /* recall that we set ximage->byte_order = MSBFirst above */
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         }
 
@@ -1011,7 +1089,7 @@
     uch r, g, b, a;
     int ximage_rowbytes = ximage->bytes_per_line;
     ulg i, pixel;
-    static int rows=0;
+    static int rows=0, prevpass=(-1);
     static ulg firstrow;
 
 /*---------------------------------------------------------------------------
@@ -1022,8 +1100,28 @@
 
     Trace((stderr, "beginning rpng2_x_display_row()\n"))
 
+    if (rpng2_info.pass != prevpass) {
+        if (pause_after_pass && rpng2_info.pass > 0) {
+            XEvent e;
+            KeySym k;
+
+            fprintf(stderr,
+              "%s:  end of pass %d of 7; click in image window to continue\n",
+              PROGNAME, prevpass + 1);
+            do
+                XNextEvent(display, &e);
+            while (!(e.type == ButtonPress && e.xbutton.button == Button1)
+                   && !(e.type == KeyPress &&
+                   ((k = XLookupKeysym(&e.xkey, 0)) == XK_q
+                    || k == XK_Escape) )) ;
+        }
+        fprintf(stderr, "%s:  pass %d of 7\r", PROGNAME, rpng2_info.pass + 1);
+        fflush(stderr);
+        prevpass = rpng2_info.pass;
+    }
+
     if (rows == 0)
-        firstrow = row;   /* first row not yet displayed */
+        firstrow = row;   /* first row that is not yet displayed */
 
     ++rows;   /* count of rows received but not yet displayed */
 
@@ -1046,14 +1144,15 @@
                 red   = *src++;
                 green = *src++;
                 blue  = *src++;
-                pixel = (red   << RPixelShift) |
-                        (green << GPixelShift) |
-                        (blue  << BPixelShift);
-                /* recall that we set ximage->byte_order = MSBFirst */
-                *dest++ = ((uch *)&pixel)[3];
-                *dest++ = ((uch *)&pixel)[2];
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                pixel = (red   << RShift) |
+                        (green << GShift) |
+                        (blue  << BShift);
+                /* recall that we set ximage->byte_order = MSBFirst above */
+                /* GRR BUG:  this assumes bpp == 32, but may be 24: */
+                *dest++ = (char)((pixel >> 24) & 0xff);
+                *dest++ = (char)((pixel >> 16) & 0xff);
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         } else /* if (rpng2_info.channels == 4) */ {
             for (i = rpng2_info.width;  i > 0;  --i) {
@@ -1082,14 +1181,15 @@
                     alpha_composite(green, g, a, bg_green);
                     alpha_composite(blue,  b, a, bg_blue);
                 }
-                pixel = (red   << RPixelShift) |
-                        (green << GPixelShift) |
-                        (blue  << BPixelShift);
-                /* recall that we set ximage->byte_order = MSBFirst */
-                *dest++ = ((uch *)&pixel)[3];
-                *dest++ = ((uch *)&pixel)[2];
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                pixel = (red   << RShift) |
+                        (green << GShift) |
+                        (blue  << BShift);
+                /* recall that we set ximage->byte_order = MSBFirst above */
+                /* GRR BUG:  this assumes bpp == 32, but may be 24: */
+                *dest++ = (char)((pixel >> 24) & 0xff);
+                *dest++ = (char)((pixel >> 16) & 0xff);
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         }
 
@@ -1108,12 +1208,12 @@
                 ++src;
                 blue  = ((ush)(*src) << 8);
                 ++src;
-                pixel = ((red   >> RPixelShift) & RedMask)   |
-                        ((green >> GPixelShift) & GreenMask) |
-                        ((blue  >> BPixelShift) & BlueMask);
-                /* recall that we set ximage->byte_order = MSBFirst */
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                pixel = ((red   >> RShift) & RMask) |
+                        ((green >> GShift) & GMask) |
+                        ((blue  >> BShift) & BMask);
+                /* recall that we set ximage->byte_order = MSBFirst above */
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         } else /* if (rpng2_info.channels == 4) */ {
             for (i = rpng2_info.width;  i > 0;  --i) {
@@ -1145,12 +1245,12 @@
                     green = ((ush)g << 8);
                     blue  = ((ush)b << 8);
                 }
-                pixel = ((red   >> RPixelShift) & RedMask)   |
-                        ((green >> GPixelShift) & GreenMask) |
-                        ((blue  >> BPixelShift) & BlueMask);
-                /* recall that we set ximage->byte_order = MSBFirst */
-                *dest++ = ((uch *)&pixel)[1];
-                *dest++ = ((uch *)&pixel)[0];
+                pixel = ((red   >> RShift) & RMask) |
+                        ((green >> GShift) & GMask) |
+                        ((blue  >> BShift) & BMask);
+                /* recall that we set ximage->byte_order = MSBFirst above */
+                *dest++ = (char)((pixel >>  8) & 0xff);
+                *dest++ = (char)( pixel        & 0xff);
             }
         }
 
@@ -1162,13 +1262,23 @@
 
 
 /*---------------------------------------------------------------------------
-    Display after every 16 rows or when on last row.  (Region may include
-    previously displayed lines due to interlacing--i.e., not contiguous.)
+    Display after every 16 rows or when on one of last two rows.  (Region
+    may include previously displayed lines due to interlacing--i.e., not
+    contiguous.  Also, second-to-last row is final one in interlaced images
+    with odd number of rows.)  For demos, flush (and delay) after every 16th
+    row so "sparse" passes don't go twice as fast.
   ---------------------------------------------------------------------------*/
 
-    if ((rows & 0xf) == 0 || row == rpng2_info.height-1) {
-        XPutImage(display, window, gc, ximage, 0, firstrow, 0, firstrow,
-          rpng2_info.width, row - firstrow + 1);
+    if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) {
+        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
+          (int)firstrow, rpng2_info.width, row - firstrow + 1);
+        XFlush(display);
+        rows = 0;
+        usleep(usleep_duration);
+    } else
+    if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) {
+        XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0,
+          (int)firstrow, rpng2_info.width, row - firstrow + 1);
         XFlush(display);
         rows = 0;
     }
@@ -1179,7 +1289,7 @@
 
 
 
-static void rpng2_x_finish_display()
+static void rpng2_x_finish_display(void)
 {
     Trace((stderr, "beginning rpng2_x_finish_display()\n"))
 
@@ -1188,14 +1298,16 @@
      * the image is done */
 
     rpng2_info.done = TRUE;
-    printf("Done.  Press Q, Esc or mouse button 1 to quit.\n");
+    printf(
+      "Done.  Press Q, Esc or mouse button 1 (within image window) to quit.\n");
+    fflush(stdout);
 }
 
 
 
 
 
-static void rpng2_x_cleanup()
+static void rpng2_x_cleanup(void)
 {
     if (bg_image && bg_data) {
         free(bg_data);
@@ -1228,6 +1340,9 @@
 
     if (have_colormap)
         XFreeColormap(display, colormap);
+
+    if (have_nondefault_visual)
+        XFree(visual_list);
 }
 
 
diff --git a/contrib/gregbook/toucan.png b/contrib/gregbook/toucan.png
new file mode 100644
index 0000000..03960d4
--- /dev/null
+++ b/contrib/gregbook/toucan.png
Binary files differ
diff --git a/contrib/gregbook/wpng.c b/contrib/gregbook/wpng.c
index 7709b33..d6e8514 100644
--- a/contrib/gregbook/wpng.c
+++ b/contrib/gregbook/wpng.c
@@ -19,7 +19,15 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+   Changelog:
+    - 1.01:  initial public release
+    - 1.02:  modified to allow abbreviated options
+    - 1.03:  removed extraneous character from usage screen; fixed bug in
+              command-line parsing
+
+  ---------------------------------------------------------------------------
+
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -45,7 +53,7 @@
   ---------------------------------------------------------------------------*/
 
 #define PROGNAME  "wpng"
-#define VERSION   "1.01 of 31 March 1999"
+#define VERSION   "1.03 of 19 March 2000"
 #define APPNAME   "Simple PGM/PPM/PAM to PNG Converter"
 
 #if defined(__MSDOS__) || defined(__OS2__)
@@ -57,27 +65,27 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <setjmp.h>  /* for jmpbuf declaration in writepng.h */
+#include <setjmp.h>     /* for jmpbuf declaration in writepng.h */
 #include <time.h>
 
 #ifdef DOS_OS2_W32
-#  include <io.h>    /* for isatty(), setmode() prototypes */
-#  include <fcntl.h> /* O_BINARY for fdopen() without text translation */
+#  include <io.h>       /* for isatty(), setmode() prototypes */
+#  include <fcntl.h>    /* O_BINARY for fdopen() without text translation */
 #  ifdef __EMX__
 #    ifndef getch
-#      define getch() _read_kbd(0, 1, 0) /* need getche() */
+#      define getch() _read_kbd(0, 1, 0)    /* need getche() */
 #    endif
 #  else /* !__EMX__ */
 #    ifdef __GO32__
 #      include <pc.h>
-#      define getch() getkey() /* GRR:  need getche() */
+#      define getch() getkey()  /* GRR:  need getche() */
 #    else
-#      include <conio.h> /* for getche() console input */
+#      include <conio.h>        /* for getche() console input */
 #    endif
 #  endif /* ?__EMX__ */
 #  define FGETS(buf,len,stream)  dos_kbd_gets(buf,len)
 #else
-#  include <unistd.h>  /* for isatty() prototype */
+#  include <unistd.h>           /* for isatty() prototype */
 #  define FGETS fgets
 #endif
 
@@ -87,7 +95,7 @@
    text that includes control characters discouraged by the PNG spec; text
    that includes an escape character (27) must be re-entered regardless */
 
-#include "writepng.h" /* typedefs, common macros, writepng prototypes */
+#include "writepng.h"   /* typedefs, common macros, writepng prototypes */
 
 
 
@@ -112,7 +120,7 @@
     FILE *keybd;
 #endif
 #ifdef sgi
-    FILE *tmpfile; /* or we could just use keybd, since no overlap */
+    FILE *tmpfile;      /* or we could just use keybd, since no overlap */
     char tmpline[80];
 #endif
     char *inname = NULL, outname[256];
@@ -204,36 +212,40 @@
     /* Now parse the command line for options and the PNM filename. */
 
     while (*++argv && !error) {
-        if (!strcmp(*argv, "-interlaced")) {
+        if (!strncmp(*argv, "-i", 2)) {
             wpng_info.interlaced = TRUE;
-        } else if (!strcmp(*argv, "-time")) {
+        } else if (!strncmp(*argv, "-time", 3)) {
             wpng_info.modtime = time(NULL);
             wpng_info.have_time = TRUE;
-        } else if (!strcmp(*argv, "-text")) {
+        } else if (!strncmp(*argv, "-text", 3)) {
             text = TRUE;
-        } else if (!strcmp(*argv, "-gamma")) {
+        } else if (!strncmp(*argv, "-gamma", 2)) {
             if (!*++argv)
                 ++error;
-            wpng_info.gamma = atof(*argv);
-            if (wpng_info.gamma <= 0.0)
-                ++error;
-            else if (wpng_info.gamma > 1.01)
-                fprintf(stderr, PROGNAME
-                  " warning:  file gammas are usually less than 1.0\n");
-        } else if (!strcmp(*argv, "-bgcolor")) {
-            if (!*++argv)
-                ++error;
-            bgstr = *argv;
-            if (strlen(bgstr) != 7 || bgstr[0] != '#')
-                ++error;
             else {
-                unsigned r, g, b;  /* this approach quiets compiler warnings */
+                wpng_info.gamma = atof(*argv);
+                if (wpng_info.gamma <= 0.0)
+                    ++error;
+                else if (wpng_info.gamma > 1.01)
+                    fprintf(stderr, PROGNAME
+                      " warning:  file gammas are usually less than 1.0\n");
+            }
+        } else if (!strncmp(*argv, "-bgcolor", 4)) {
+            if (!*++argv)
+                ++error;
+            else {
+                bgstr = *argv;
+                if (strlen(bgstr) != 7 || bgstr[0] != '#')
+                    ++error;
+                else {
+                    unsigned r, g, b;  /* this way quiets compiler warnings */
 
-                sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
-                wpng_info.bg_red   = (uch)r;
-                wpng_info.bg_green = (uch)g;
-                wpng_info.bg_blue  = (uch)b;
-                wpng_info.have_bg = TRUE;
+                    sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b);
+                    wpng_info.bg_red   = (uch)r;
+                    wpng_info.bg_green = (uch)g;
+                    wpng_info.bg_blue  = (uch)b;
+                    wpng_info.have_bg = TRUE;
+                }
             }
         } else {
             if (**argv != '-') {
@@ -362,7 +374,7 @@
          "\t\t  (where LUT = lookup-table exponent and CRT = CRT exponent;\n"
          "\t\t  first varies, second is usually 2.2, all are positive)\n"
          "    bg  \tdesired background color for alpha-channel images, in\n"
-         "\t\t  7-character hex RGB format (e.g., ``#ff7f00'' for orange:\n"
+         "\t\t  7-character hex RGB format (e.g., ``#ff7700'' for orange:\n"
          "\t\t  same as HTML colors)\n"
          "    -text\tprompt interactively for text info (tEXt chunks)\n"
          "    -time\tinclude a tIME chunk (last modification time)\n"
@@ -419,7 +431,7 @@
                     wpng_info.have_text &= ~TEXT_TITLE;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_TITLE;
                         valid = FALSE;
                     }
@@ -449,7 +461,7 @@
                     wpng_info.have_text &= ~TEXT_AUTHOR;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_AUTHOR;
                         valid = FALSE;
                     }
@@ -489,7 +501,7 @@
                     wpng_info.have_text &= ~TEXT_DESC;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_DESC;
                         valid = FALSE;
                     }
@@ -519,7 +531,7 @@
                     wpng_info.have_text &= ~TEXT_COPY;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_COPY;
                         valid = FALSE;
                     }
@@ -549,7 +561,7 @@
                     wpng_info.have_text &= ~TEXT_EMAIL;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_EMAIL;
                         valid = FALSE;
                     }
@@ -579,7 +591,7 @@
                     wpng_info.have_text &= ~TEXT_URL;
                     valid = FALSE;
 #else
-                    if (p[result] == 27) { /* escape character */
+                    if (p[result] == 27) {    /* escape character */
                         wpng_info.have_text &= ~TEXT_URL;
                         valid = FALSE;
                     }
@@ -755,7 +767,7 @@
 
 
 
-static void wpng_cleanup()
+static void wpng_cleanup(void)
 {
     if (wpng_info.outfile) {
         fclose(wpng_info.outfile);
@@ -791,11 +803,11 @@
         buf[count++] = ch = getche();
     } while (ch != '\r' && count < len-1);
 
-    buf[count--] = '\0';     /* terminate string */
-    if (buf[count] == '\r')  /* Enter key makes CR, so change to newline */
+    buf[count--] = '\0';        /* terminate string */
+    if (buf[count] == '\r')     /* Enter key makes CR, so change to newline */
         buf[count] = '\n';
 
-    fprintf(stderr, "\n");   /* Enter key does *not* cause a newline */
+    fprintf(stderr, "\n");      /* Enter key does *not* cause a newline */
     fflush(stderr);
 
     return buf;
diff --git a/contrib/gregbook/writepng.c b/contrib/gregbook/writepng.c
index b94c677..6802b12 100644
--- a/contrib/gregbook/writepng.c
+++ b/contrib/gregbook/writepng.c
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
@@ -30,10 +30,10 @@
   ---------------------------------------------------------------------------*/
 
 
-#include <stdlib.h>   /* for exit() prototype */
+#include <stdlib.h>     /* for exit() prototype */
 
-#include "png.h"      /* libpng header; includes zlib.h and setjmp.h */
-#include "writepng.h" /* typedefs, common macros, public prototypes */
+#include "png.h"        /* libpng header; includes zlib.h and setjmp.h */
+#include "writepng.h"   /* typedefs, common macros, public prototypes */
 
 
 /* local prototype */
@@ -42,7 +42,7 @@
 
 
 
-void writepng_version_info()
+void writepng_version_info(void)
 {
   fprintf(stderr, "   Compiled with libpng %s; using libpng %s.\n",
     PNG_LIBPNG_VER_STRING, png_libpng_ver);
@@ -82,7 +82,7 @@
      * but compatible error handlers must either use longjmp() themselves
      * (as in this program) or exit immediately, so here we go: */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_write_struct(&png_ptr, &info_ptr);
         return 2;
     }
@@ -239,7 +239,7 @@
     /* as always, setjmp() must be called in every function that calls a
      * PNG-writing libpng function */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_write_struct(&png_ptr, &info_ptr);
         mainprog_ptr->png_ptr = NULL;
         mainprog_ptr->info_ptr = NULL;
@@ -277,7 +277,7 @@
     /* as always, setjmp() must be called in every function that calls a
      * PNG-writing libpng function */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_write_struct(&png_ptr, &info_ptr);
         mainprog_ptr->png_ptr = NULL;
         mainprog_ptr->info_ptr = NULL;
@@ -307,7 +307,7 @@
     /* as always, setjmp() must be called in every function that calls a
      * PNG-writing libpng function */
 
-    if (setjmp(png_jmp_env(mainprog_ptr))) {
+    if (setjmp(mainprog_ptr->jmpbuf)) {
         png_destroy_write_struct(&png_ptr, &info_ptr);
         mainprog_ptr->png_ptr = NULL;
         mainprog_ptr->info_ptr = NULL;
diff --git a/contrib/gregbook/writepng.h b/contrib/gregbook/writepng.h
index 123d2d6..93c3da8 100644
--- a/contrib/gregbook/writepng.h
+++ b/contrib/gregbook/writepng.h
@@ -4,7 +4,7 @@
 
   ---------------------------------------------------------------------------
 
-      Copyright (c) 1998-1999 Greg Roelofs.  All rights reserved.
+      Copyright (c) 1998-2000 Greg Roelofs.  All rights reserved.
 
       This software is provided "as is," without warranty of any kind,
       express or implied.  In no event shall the author or contributors
diff --git a/contrib/pngminus/png2pnm.c b/contrib/pngminus/png2pnm.c
index 2754d9a..84e2448 100644
--- a/contrib/pngminus/png2pnm.c
+++ b/contrib/pngminus/png2pnm.c
@@ -42,6 +42,11 @@
 
 #include "png.h"
 
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
 /* function prototypes */
 
 int  main (int argc, char *argv[]);
@@ -223,7 +228,7 @@
     return FALSE;   /* out of memory */
   }
 
-  if (setjmp (png_jmp_env(png_ptr)))
+  if (setjmp (png_jmpbuf(png_ptr)))
   {
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
     return FALSE;
diff --git a/contrib/pngminus/pnm2png.c b/contrib/pngminus/pnm2png.c
index 9329fcd..4cdfad8 100644
--- a/contrib/pngminus/pnm2png.c
+++ b/contrib/pngminus/pnm2png.c
@@ -40,6 +40,11 @@
 
 #include "png.h"
 
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
 /* function prototypes */
 
 int  main (int argc, char *argv[]);
@@ -386,7 +391,7 @@
   }
 
   /* setjmp() must be called in every function that calls a PNG-reading libpng function */
-  if (setjmp (png_jmp_env(png_ptr)))
+  if (setjmp (png_jmpbuf(png_ptr)))
   {
     png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
     return FALSE;