Imported from libpng-1.0.4-pre1.tar
diff --git a/ANNOUNCE b/ANNOUNCE
index 77eea6e..e14d5c3 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,53 +1,56 @@
 
-Libpng 1.0.3 - January 14, 1999
+Libpng 1.0.4 - September 17, 1999
 
 This is a public release of libpng, intended for use in production codes.
 
-Changes since the previous public release (1.0.2):
+Changes since the last public release (1.0.3):
 
-libpng-1.0.3:
-
-  Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
-  Fixed a bug in png_do_filler() that made it fail to write filler bytes in
-    the left-most pixel of each row (Kevin Bracey).
-  Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
-    in pngtest.c (Duncan Simpson).
-  Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
-    even when no tIME chunk was present in the source file.
-  Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
-  Fixed a problem in png_read_push_finish_row(), which would not skip some
-    passes that it should skip, for images that are less than 3 pixels high.
-  Interchanged the order of calls to png_do_swap() and png_do_shift()
-    in pngwtran.c (John Cromer).
-  Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
-  Changed "bad adaptive filter type" from error to warning in pngrutil.c .
-  Fixed a documentation error about default filtering with 8-bit indexed-color.
-  Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
-    (L. Peter Deutsch).
-  Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
-  Added png_get_copyright() and png_get_header_version() functions.
-  Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
-  Added information about debugging in libpng.txt and libpng.3 .
-  Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
-  Removed lines after Dynamic Dependencies" in makefile.aco .
-  Revised makefile.dec to make a shared library (Jeremie Petit).
-  Removed trailing blanks from all files. 
-  Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
-  Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
-  Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
-  Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
-    which is obsolete.
-  Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
-  Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
+  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+     if an attempt is made to read an interlaced image when it's not supported.
+  Added check if png_ptr->trans is defined before free'ing it in pngread.c
+  Modified the Y2K statement to include versions back to version 0.71
+  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+  Replaced leading blanks with tab characters in makefile.hux
+  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+  Changed (float)red and (float)green to (double)red, (double)green
+     in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+  Updated documentation to refer to the PNG-1.2 specification.
+  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+  Fixed bugs in calculation of the length of rowbytes when adding alpha
+    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+  Added function png_set_user_transform_info() to store user_transform_ptr,
+    user_depth, and user_channels into the png_struct, and a function
+    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+  Added function png_set_empty_plte_permitted() to make libpng useable
+    in MNG applications.
+  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+    consistent with PNG-1.2, and allow variance of 500 before complaining.
+  Added assembler code contributed by Intel in file pngvcrd.c and modified
+    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+  Changed leading blanks to tabs in all makefiles.
+  Made alternate versions of  png_set_expand() in pngrtran.c, namely
+    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+    (Greg Roelofs, in "PNG: The Definitive Guide").
+  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+  Revised calculation of num_blocks in pngmem.c to avoid a potentially
+    negative shift distance, whose results are undefined in the C language.
+  Added a check in pngset.c to prevent writing multiple tIME chunks.
+  Added a check in pngwrite.c to detect invalid small window_bits sizes.
+  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+  Made several minor corrections to pngtest.c
+  Changed "hptr += 16L" to "hptr = hptr + 16L" in pngmem.c for Turbo 3.0
 
 Send comments/corrections/commendations to
-png-implement@dworkin.wustl.edu or to randeg@alumni.rpi.edu
+png-implement@ccrc.wustl.edu or to randeg@alum.rpi.edu
 
 Glenn R-P
-
-Send comments/corrections/commendations to
-png-implement@dworkin.wustl.edu or to randeg@alumni.rpi.edu
-
-Glenn Randers-Pehrson
-libpng maintainer
-PNG Development Group
diff --git a/CHANGES b/CHANGES
index d2dcde3..c0e416b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -386,4 +386,57 @@
     which is obsolete.
 version 1.0.3 [January 14, 1999]
   Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
-  Added a statement of Y2K compliance in png.h, libpng.1, and Y2KINFO.
+  Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
+version 1.0.3a [August 12, 1999]
+  Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+     if an attempt is made to read an interlaced image when it's not supported.
+  Added check if png_ptr->trans is defined before free'ing it in pngread.c
+  Modified the Y2K statement to include versions back to version 0.71
+  Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+  Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+  Replaced leading blanks with tab characters in makefile.hux
+  Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+  Changed (float)red and (float)green to (double)red, (double)green
+     in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+  Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+  Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+  Updated documentation to refer to the PNG-1.2 specification.
+  Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+    in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+  Fixed bugs in calculation of the length of rowbytes when adding alpha
+    channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+  Added function png_set_user_transform_info() to store user_transform_ptr,
+    user_depth, and user_channels into the png_struct, and a function
+    png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+  Added function png_set_empty_plte_permitted() to make libpng useable
+    in MNG applications.
+  Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+  Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+    consistent with PNG-1.2, and allow variance of 500 before complaining.
+  Added assembler code contributed by Intel in file pngvcrd.c and modified
+    makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+  Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+  Added some aliases for png_set_expand() in pngrtran.c, namely
+    png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
+    (Greg Roelofs, in "PNG: The Definitive Guide").
+  Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+version 1.0.3b [August 26, 1999]
+  Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+  Changed leading blanks to tabs in all makefiles.
+  Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+  Made alternate versions of  png_set_expand() in pngrtran.c, namely
+    png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+    (Greg Roelofs, in "PNG: The Definitive Guide").  Deleted the 1.0.3a aliases.
+  Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+  Revised calculation of num_blocks in pngmem.c to avoid a potentially
+    negative shift distance, whose results are undefined in the C language.
+  Added a check in pngset.c to prevent writing multiple tIME chunks.
+  Added a check in pngwrite.c to detect invalid small window_bits sizes.
+version 1.0.3d [September 4, 1999]
+  Fixed type casting of igamma in pngrutil.c
+  Added new png_expand functions to scripts/pngdef.pas and pngos2.def
+  Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+version 1.0.4 [September 17, 1999]
+  Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+  Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
+  Made several minor corrections to pngtest.c
diff --git a/INSTALL b/INSTALL
index 554b771..2ed6932 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,5 @@
 
-Installing libpng version 1.0.3 - January 14, 1999
+Installing libpng version 1.0.4 - September 17, 1999
 
 Before installing libpng, you must first install zlib.  zlib
 can usually be found wherever you got libpng.  zlib can be
@@ -10,7 +10,7 @@
 version of zlib that's installed.
 
 You can rename the directories that you downloaded (they
-might be called "libpng-1.0.3" or "lpng103" and "zlib-1.1.3"
+might be called "libpng-1.0.4" or "lpng103" and "zlib-1.1.3"
 or "zlib113") so that you have directories called "zlib" and "libpng".
 
 Your directory structure should look like this:
@@ -41,18 +41,21 @@
       descrip.mms   =>  VMS makefile for MMS or MMK
       makefile.std  =>  Generic UNIX makefile
       makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
+                        (Requires ansi2knr.c from ftp://ftp.cs.wisc.edu/ghost)
       makefile.dec  =>  DEC Alpha UNIX makefile
       makefile.hux  =>  HPUX (10.20 and 11.00) makefile
       makefile.sgi  =>  Silicon Graphics IRIX makefile
       makefile.sun  =>  Sun makefile
-      makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
-      makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
+      makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0.4)
+      makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0.4)
+      makefile.sco  =>  For SCO OSr5  ELF and Unixware 7 with Native cc
       makefile.mip  =>  MIPS makefile
       makefile.aco  =>  Acorn makefile
       makefile.ama  =>  Amiga makefile
       smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
                         (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
       makefile.atr  =>  Atari makefile
+      makefile.beo  =>  BEOS makefile for X86
       makefile.bor  =>  Borland makefile
       build.bat     =>  MS-DOS batch file for Borland compiler
       makefile.dj2  =>  DJGPP 2 makefile
@@ -65,6 +68,7 @@
       makevms.com   =>  VMS build script
       pngdll.mak    =>  To make a png32bd.dll with Borland C++ 4.5
       pngdef.pas    =>  Defines for a png32bd.dll with Borland C++ 4.5
+      SCOPTIONS.ppc =>  Used with smakefile.ppc
 
 Copy the file (or files) that you need from the
 scripts directory into this directory, for example
diff --git a/KNOWNBUG b/KNOWNBUG
index 2238908..7c640a8 100644
--- a/KNOWNBUG
+++ b/KNOWNBUG
@@ -1,5 +1,5 @@
 
-Known bugs and suggested enhancements in libpng-1.0.3
+Known bugs and suggested enhancements in libpng-1.0.4
 
 
 1. March 15, 1998 -- OPTIMIZATION -- Kevin Bracey
@@ -14,12 +14,12 @@
    Question whether i-- or --i is better.
 
    STATUS: Under investigation, postponed until after
-   libpng-1.0.3.  About 160 loops will be turned around
+   libpng-1.0.4.  About 160 loops will be turned around
    in libpng-1.0.Nn, for testing.
 
 2. July 4, 1998 -- ENHANCEMENT -- Glenn R-P
 
-   libpng-1.0.2 and earlier transform colors to gamma=1.0 space for
+   libpng-1.0.4 and earlier transform colors to gamma=1.0 space for
    merging with background, and then back to the image's gamma.  The
    bit_depth of the intermediate (gamma=1.0) representation is probably
    not sufficient.  In the typical gamma=1/2.2 situation, the linear
@@ -29,4 +29,12 @@
 
    STATUS: under development.
 
+3. September 1999 -- ENHANCEMENT --
+
+   It should be possible to use libpng without floating-point aritmetic.
+
+   STATUS: Under investigation, implementation postponed until after
+   libpng-1.0.4.  The application interface will change because replacements
+   for the png_set_gAMA(), png_set_cHRM(), and corresponding png_get_()
+   functions will be needed.
 
diff --git a/README b/README
index 3bd0893..6281b22 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-README for libpng 1.0.3 - January 14, 1999 (shared library 2.1)
+README for libpng 1.0.4 - September 17, 1999 (shared library 2.1)
 See the note about version numbers near the top of png.h
 
 See INSTALL for instructions on how to install libpng.
@@ -49,7 +49,7 @@
 critical or an ancillary chunk.
 
 The changes made to the library, and bugs fixed are based on discussions
-on the PNG implementation mailing list <png-implement@dworking.wustl.edu>
+on the PNG implementation mailing list <png-implement@ccrc.wustl.edu>
 and not on material submitted to Guy.
 
 For a detailed description on using libpng, read libpng.txt.  For
@@ -98,8 +98,8 @@
 This release was created and will be supported by myself (of course
 based in a large way on Guy's and Andreas' earlier work), and the PNG group.
 
-randeg@alumni.rpi.edu
-png-implement@dworkin.wustl.edu
+randeg@alum.rpi.edu
+png-implement@ccrc.wustl.edu
 
 You can't reach Guy, the original libpng author, at the addresses
 given in previous versions of this document.  He and Andreas will read mail
@@ -108,7 +108,7 @@
 Please do not send general questions about PNG.  Send them to
 the address in the specification (png-group@w3.org).  At the same
 time, please do not send libpng questions to that address, send them to me
-or to png-implement@dworkin.wustl.edu.  I'll
+or to png-implement@ccrc.wustl.edu.  I'll
 get them in the end anyway.  If you have a question about something
 in the PNG specification that is related to using libpng, send it
 to me.  Send me any questions that start with "I was using libpng,
@@ -126,8 +126,6 @@
       CHANGES       =>  Description of changes between libpng versions
       README        =>  This file
       TODO          =>  Things not implemented in the current library
-      ansi2knr.1    =>  Manual page for ansi2knr
-      ansi2knr.c    =>  Converts files to K&R style function declarations
       build.bat     =>  MS-DOS batch file for Borland compiler
       descrip.mms   =>  VMS project file
       example.c     =>  Example code for using libpng functions
@@ -155,38 +153,42 @@
       pngwtran.c    =>  Write data transformations
       pngwutil.c    =>  Write utility functions
       scripts       =>  Directory containing scripts for building libpng:
-        descrip.mms   =>  VMS makefile for MMS or MMK
-        makefile.std  =>  Generic UNIX makefile
-        makefile.knr  =>  Archaic UNIX Makefile that converts files with ansi2knr
-        makefile.dec  =>  DEC Alpha UNIX makefile
-        makefile.hux  =>  HPUX (10.20 and 11.00) makefile
-        makefile.sgi  =>  Silicon Graphics IRIX makefile
-        makefile.sun  =>  Sun makefile
-        makefile.s2x  =>  Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
-        makefile.lnx  =>  Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
-        makefile.mip  =>  MIPS makefile
-        makefile.aco  =>  Acorn makefile
-        makefile.ama  =>  Amiga makefile
-        smakefile.ppc =>  AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
-                          (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
-        makefile.atr  =>  Atari makefile
-        makefile.bor  =>  Borland makefile
-        build.bat     =>  MS-DOS batch file for Borland compiler
-        makefile.dj2  =>  DJGPP 2 makefile
-        makefile.msc  =>  Microsoft C makefile
-        makefile.w32  =>  makefile for Microsoft Visual C++ 4.0 and later
-        makefile.tc3  =>  Turbo C 3.0 makefile
-        makefile.os2  =>  OS/2 Makefile (gcc and emx, requires pngos2.def)
-        makefile.wat  =>  Watcom 10a+ Makefile, 32-bit flat memory model
-        pngos2.def    =>  OS/2 module definition file used by makefile.os2
-        makevms.com   =>  VMS build script
-        pngdll.mak    =>  To make a png32bd.dll with Borland C++ 4.5
-        pngdef.pas    =>  Defines for a png32bd.dll with Borland C++ 4.5
+        descrip.mms   => VMS makefile for MMS or MMK
+        makefile.std  => Generic UNIX makefile
+        makefile.knr  => Archaic UNIX Makefile that converts files with ansi2knr
+                        (Requires ansi2knr.c from ftp://ftp.cs.wisc.edu/ghost)
+        makefile.dec  => DEC Alpha UNIX makefile
+        makefile.hux  => HPUX (10.20 and 11.00) makefile
+        makefile.sgi  => Silicon Graphics IRIX makefile
+        makefile.sun  => Sun makefile
+        makefile.s2x  => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
+        makefile.lnx  => Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
+        makefile.sco  => For SCO OSr5  ELF and Unixware 7 with Native cc
+        makefile.mip  => MIPS makefile
+        makefile.aco  => Acorn makefile
+        makefile.ama  => Amiga makefile
+        smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+                         (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+        makefile.atr  => Atari makefile
+        makefile.beo  => BEOS makefile for X86
+        makefile.bor  => Borland makefile
+        build.bat     => MS-DOS batch file for Borland compiler
+        makefile.dj2  => DJGPP 2 makefile
+        makefile.msc  => Microsoft C makefile
+        makefile.w32  => makefile for Microsoft Visual C++ 4.0 and later
+        makefile.tc3  => Turbo C 3.0 makefile
+        makefile.os2  => OS/2 Makefile (gcc and emx, requires pngos2.def)
+        pngos2.def    => OS/2 module definition file used by makefile.os2
+        makefile.wat  => Watcom 10a+ Makefile, 32-bit flat memory model
+        makevms.com   => VMS build script
+        pngdll.mak    => To make a png32bd.dll with Borland C++ 4.5
+        pngdef.pas    => Defines for a png32bd.dll with Borland C++ 4.5
+        SCOPTIONS.ppc => Used with smakefile.ppc
 
 Good luck, and happy coding.
 
 -Glenn Randers-Pehrson
- Internet: randeg@alumni.rpi.edu
+ Internet: randeg@alum.rpi.edu
  Web: http://www.rpi.edu/~randeg/index.html
 
 -Andreas Eric Dilger
diff --git a/TODO b/TODO
index 52f32b8..9c420bc 100644
--- a/TODO
+++ b/TODO
@@ -10,7 +10,6 @@
 Improve setjmp/longjmp usage or remove it in favor of returning error codes.
 High-level API for reading images.
 Add "grayscale->palette" transformation and "palette->grayscale" detection.
-Color to gray transformation.
 Improved dithering.
 Multi-lingual error and warning message support.
 Complete sRGB transformation (presently it simply uses gamma=0.45455).
@@ -22,3 +21,4 @@
 Histogram creation.
 Text conversion between different code pages (Latin-1 -> Mac and DOS).
 Improve API by hiding the info_ptr.
+Make a no-floating-point version.
diff --git a/Y2KINFO b/Y2KINFO
index bf41676..8219b60 100644
--- a/Y2KINFO
+++ b/Y2KINFO
@@ -6,9 +6,9 @@
       Since the PNG Development group is an ad-hoc body, we can't make
       an official declaration.
       
-      This is your unofficial assurance that libpng from version 0.81 and
-      upward are Y2K compliant.  It is my belief that earlier versions were
-      also Y2K compliant.
+      This is your unofficial assurance that libpng from version 0.71 and
+      upward through 1.0.4 are Y2K compliant.  It is my belief that earlier
+      versions were also Y2K compliant.
       
       Libpng only has three year fields.  One is a 2-byte unsigned integer
       that will hold years up to 65535.  The other two hold the date in text
@@ -37,14 +37,17 @@
       clock time, which returns (year - 1900), which we properly convert to
       the full 4-digit year.  There is a possibility that applications using
       libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-      function, or incorrectly passing only a 2-digit year instead of
-      "year - 1900" into the png_convert_from_struct_tm() function, but this
-      is not under our control.  The libpng documentation has always stated
-      that it works with 4-digit years, and the APIs have been documented as
-      such.
+      function, or that they are incorrectly passing only a 2-digit year
+      instead of "year - 1900" into the png_convert_from_struct_tm() function,
+      but this is not under our control.  The libpng documentation has always
+      stated that it works with 4-digit years, and the APIs have been
+      documented as such.
       
       The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
       integer to hold the year, and can hold years as large as 65535.
+
+      zlib, upon which libpng depends, is also Y2K compliant.  It contains
+      no date-related code.
       
       
          Glenn Randers-Pehrson
diff --git a/ansi2knr.1 b/ansi2knr.1
deleted file mode 100644
index f9ee5a6..0000000
--- a/ansi2knr.1
+++ /dev/null
@@ -1,36 +0,0 @@
-.TH ANSI2KNR 1 "19 Jan 1996"
-.SH NAME
-ansi2knr \- convert ANSI C to Kernighan & Ritchie C
-.SH SYNOPSIS
-.I ansi2knr
-[--varargs] input_file [output_file]
-.SH DESCRIPTION
-If no output_file is supplied, output goes to stdout.
-.br
-There are no error messages.
-.sp
-.I ansi2knr
-recognizes function definitions by seeing a non-keyword identifier at the left
-margin, followed by a left parenthesis, with a right parenthesis as the last
-character on the line, and with a left brace as the first token on the
-following line (ignoring possible intervening comments).  It will recognize a
-multi-line header provided that no intervening line ends with a left or right
-brace or a semicolon.  These algorithms ignore whitespace and comments, except
-that the function name must be the first thing on the line.
-.sp
-The following constructs will confuse it:
-.br
-     - Any other construct that starts at the left margin and follows the
-above syntax (such as a macro or function call).
-.br
-     - Some macros that tinker with the syntax of the function header.
-.sp
-The --varargs switch is obsolete, and is recognized only for
-backwards compatibility.  The present version of
-.I ansi2knr
-will always attempt to convert a ... argument to va_alist and va_dcl.
-.SH AUTHOR
-L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
-continues to maintain the current version; most of the code in the current
-version is his work.  ansi2knr also includes contributions by Francois
-Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
diff --git a/ansi2knr.c b/ansi2knr.c
deleted file mode 100644
index dfb29a2..0000000
--- a/ansi2knr.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* ansi2knr.c */
-
-/* Convert ANSI C function definitions to K&R ("traditional C") syntax
-Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
-Copyright (C) 1988 Richard M. Stallman
-
-ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY.  No author or distributor accepts responsibility to anyone for the
-consequences of using it or for whether it serves any particular purpose or
-works at all, unless he says so in writing.  Refer to the GNU General Public
-License (the "GPL") for full details.
-
-Everyone is granted permission to copy, modify and redistribute ansi2knr,
-but only under the conditions described in the GPL.  A copy of this license
-is supposed to have been given to you along with ansi2knr so you can know
-your rights and responsibilities.  It should be in a file named COPYLEFT.
-[In the LIBPNG distribution, the GPL appears below, not in a separate file.]
-Among other things, the copyright notice and this notice must be preserved
-on all copies.
-
-We explicitly state here what we believe is already implied by the GPL: if
-the ansi2knr program is distributed as a separate source file and a
-separate executable file which are aggregated on a storage medium together
-with another program, this in itself does not bring the other program under
-the GPL, nor does the mere fact that such a program or the procedures for
-constructing it invoke the ansi2knr executable bring any other part of the
-program under the GPL.
-*/
-
-/*
----------- Here is the GNU GPL file COPYLEFT, referred to above ----------
------ These terms do NOT apply to the LIBPNG software itself; see README ------
-
-		    GHOSTSCRIPT GENERAL PUBLIC LICENSE
-		    (Clarified 11 Feb 1988)
-
- Copyright (C) 1988 Richard M. Stallman
- Everyone is permitted to copy and distribute verbatim copies of this
- license, but changing it is not allowed.  You can also use this wording
- to make the terms for other programs.
-
-  The license agreements of most software companies keep you at the
-mercy of those companies.  By contrast, our general public license is
-intended to give everyone the right to share Ghostscript.  To make sure
-that you get the rights we want you to have, we need to make
-restrictions that forbid anyone to deny you these rights or to ask you
-to surrender the rights.  Hence this license agreement.
-
-  Specifically, we want to make sure that you have the right to give
-away copies of Ghostscript, that you receive source code or else can get
-it if you want it, that you can change Ghostscript or use pieces of it
-in new free programs, and that you know you can do these things.
-
-  To make sure that everyone has such rights, we have to forbid you to
-deprive anyone else of these rights.  For example, if you distribute
-copies of Ghostscript, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must tell them their rights.
-
-  Also, for our own protection, we must make certain that everyone finds
-out that there is no warranty for Ghostscript.  If Ghostscript is
-modified by someone else and passed on, we want its recipients to know
-that what they have is not what we distributed, so that any problems
-introduced by others will not reflect on our reputation.
-
-  Therefore we (Richard M. Stallman and the Free Software Foundation,
-Inc.) make the following terms which say what you must do to be allowed
-to distribute or change Ghostscript.
-
-
-			COPYING POLICIES
-
-  1. You may copy and distribute verbatim copies of Ghostscript source
-code as you receive it, in any medium, provided that you conspicuously
-and appropriately publish on each copy a valid copyright and license
-notice "Copyright (C) 1989 Aladdin Enterprises.  All rights reserved.
-Distributed by Free Software Foundation, Inc." (or with whatever year is
-appropriate); keep intact the notices on all files that refer to this
-License Agreement and to the absence of any warranty; and give any other
-recipients of the Ghostscript program a copy of this License Agreement
-along with the program.  You may charge a distribution fee for the
-physical act of transferring a copy.
-
-  2. You may modify your copy or copies of Ghostscript or any portion of
-it, and copy and distribute such modifications under the terms of
-Paragraph 1 above, provided that you also do the following:
-
-    a) cause the modified files to carry prominent notices stating
-    that you changed the files and the date of any change; and
-
-    b) cause the whole of any work that you distribute or publish,
-    that in whole or in part contains or is a derivative of Ghostscript
-    or any part thereof, to be licensed at no charge to all third
-    parties on terms identical to those contained in this License
-    Agreement (except that you may choose to grant more extensive
-    warranty protection to some or all third parties, at your option).
-
-    c) You may charge a distribution fee for the physical act of
-    transferring a copy, and you may at your option offer warranty
-    protection in exchange for a fee.
-
-Mere aggregation of another unrelated program with this program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other program under the scope of these terms.
-
-  3. You may copy and distribute Ghostscript (or a portion or derivative
-of it, under Paragraph 2) in object code or executable form under the
-terms of Paragraphs 1 and 2 above provided that you also do one of the
-following:
-
-    a) accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    b) accompany it with a written offer, valid for at least three
-    years, to give any third party free (except for a nominal
-    shipping charge) a complete machine-readable copy of the
-    corresponding source code, to be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    c) accompany it with the information you received as to where the
-    corresponding source code may be obtained.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form alone.)
-
-For an executable file, complete source code means all the source code for
-all modules it contains; but, as a special exception, it need not include
-source code for modules which are standard libraries that accompany the
-operating system on which the executable file runs.
-
-  4. You may not copy, sublicense, distribute or transfer Ghostscript
-except as expressly provided under this License Agreement.  Any attempt
-otherwise to copy, sublicense, distribute or transfer Ghostscript is
-void and your rights to use the program under this License agreement
-shall be automatically terminated.  However, parties who have received
-computer software programs from you with this License Agreement will not
-have their licenses terminated so long as such parties remain in full
-compliance.
-
-  5. If you wish to incorporate parts of Ghostscript into other free
-programs whose distribution conditions are different, write to the Free
-Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
-yet worked out a simple rule that can be stated here, but we will often
-permit this.  We will be guided by the two goals of preserving the free
-status of all derivatives of our free software and of promoting the
-sharing and reuse of software.
-
-Your comments and suggestions about our licensing policies and our
-software are welcome!  Please contact the Free Software Foundation,
-Inc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
-
-		       NO WARRANTY
-
-  BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
-NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
-WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
-M. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
-PROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
-EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE
-ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
-YOU.  SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
-STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
-ENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
-GHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
-ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
-INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
-PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
-HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
-BY ANY OTHER PARTY.
-
--------------------- End of file COPYLEFT ------------------------------
-*/
-
-/*
- * Usage:
-	ansi2knr input_file [output_file]
- * If no output_file is supplied, output goes to stdout.
- * There are no error messages.
- *
- * ansi2knr recognizes function definitions by seeing a non-keyword
- * identifier at the left margin, followed by a left parenthesis,
- * with a right parenthesis as the last character on the line,
- * and with a left brace as the first token on the following line
- * (ignoring possible intervening comments).
- * It will recognize a multi-line header provided that no intervening
- * line ends with a left or right brace or a semicolon.
- * These algorithms ignore whitespace and comments, except that
- * the function name must be the first thing on the line.
- * The following constructs will confuse it:
- *	- Any other construct that starts at the left margin and
- *	    follows the above syntax (such as a macro or function call).
- *	- Some macros that tinker with the syntax of the function header.
- */
-
-/*
- * The original and principal author of ansi2knr is L. Peter Deutsch
- * <ghost@aladdin.com>.  Other authors are noted in the change history
- * that follows (in reverse chronological order):
-	lpd 96-01-21 added code to cope with not HAVE_CONFIG_H and with
-		compilers that don't understand void, as suggested by
-		Tom Lane
-	lpd 96-01-15 changed to require that the first non-comment token
-		on the line following a function header be a left brace,
-		to reduce sensitivity to macros, as suggested by Tom Lane
-		<tgl@sss.pgh.pa.us>
-	lpd 95-06-22 removed #ifndefs whose sole purpose was to define
-		undefined preprocessor symbols as 0; changed all #ifdefs
-		for configuration symbols to #ifs
-	lpd 95-04-05 changed copyright notice to make it clear that
-		including ansi2knr in a program does not bring the entire
-		program under the GPL
-	lpd 94-12-18 added conditionals for systems where ctype macros
-		don't handle 8-bit characters properly, suggested by
-		Francois Pinard <pinard@iro.umontreal.ca>;
-		removed --varargs switch (this is now the default)
-	lpd 94-10-10 removed CONFIG_BROKETS conditional
-	lpd 94-07-16 added some conditionals to help GNU `configure',
-		suggested by Francois Pinard <pinard@iro.umontreal.ca>;
-		properly erase prototype args in function parameters,
-		contributed by Jim Avera <jima@netcom.com>;
-		correct error in writeblanks (it shouldn't erase EOLs)
-	lpd 89-xx-xx original version
- */
-
-/* Most of the conditionals here are to make ansi2knr work with */
-/* or without the GNU configure machinery. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-
-#if HAVE_CONFIG_H
-
-/*
-   For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
-   This will define HAVE_CONFIG_H and so, activate the following lines.
- */
-
-# if STDC_HEADERS || HAVE_STRING_H
-#  include <string.h>
-# else
-#  include <strings.h>
-# endif
-
-#else /* not HAVE_CONFIG_H */
-
-/* Otherwise do it the hard way */
-
-# ifdef BSD
-#  include <strings.h>
-# else
-#  ifdef VMS
-    extern int strlen(), strncmp();
-#  else
-#   include <string.h>
-#  endif
-# endif
-
-#endif /* not HAVE_CONFIG_H */
-
-#if STDC_HEADERS
-# include <stdlib.h>
-#else
-/*
-   malloc and free should be declared in stdlib.h,
-   but if you've got a K&R compiler, they probably aren't.
- */
-# ifdef MSDOS
-#  include <malloc.h>
-# else
-#  ifdef VMS
-     extern char *malloc();
-     extern void free();
-#  else
-     extern char *malloc();
-     extern int free();
-#  endif
-# endif
-
-#endif
-
-/*
- * The ctype macros don't always handle 8-bit characters correctly.
- * Compensate for this here.
- */
-#ifdef isascii
-#  undef HAVE_ISASCII		/* just in case */
-#  define HAVE_ISASCII 1
-#else
-#endif
-#if STDC_HEADERS || !HAVE_ISASCII
-#  define is_ascii(c) 1
-#else
-#  define is_ascii(c) isascii(c)
-#endif
-
-#define is_space(c) (is_ascii(c) && isspace(c))
-#define is_alpha(c) (is_ascii(c) && isalpha(c))
-#define is_alnum(c) (is_ascii(c) && isalnum(c))
-
-/* Scanning macros */
-#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
-#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
-
-/* Forward references */
-char *skipspace();
-int writeblanks();
-int test1();
-int convert1();
-
-/* The main program */
-int
-main(argc, argv)
-    int argc;
-    char *argv[];
-{	FILE *in, *out;
-#define bufsize 5000			/* arbitrary size */
-	char *buf;
-	char *line;
-	char *more;
-	/*
-	 * In previous versions, ansi2knr recognized a --varargs switch.
-	 * If this switch was supplied, ansi2knr would attempt to convert
-	 * a ... argument to va_alist and va_dcl; if this switch was not
-	 * supplied, ansi2knr would simply drop any such arguments.
-	 * Now, ansi2knr always does this conversion, and we only
-	 * check for this switch for backward compatibility.
-	 */
-	int convert_varargs = 1;
-
-	if ( argc > 1 && argv[1][0] == '-' )
-	  {	if ( !strcmp(argv[1], "--varargs") )
-		  {	convert_varargs = 1;
-			argc--;
-			argv++;
-		  }
-		else
-		  {	fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
-			exit(1);
-		  }
-	  }
-	switch ( argc )
-	   {
-	default:
-		printf("Usage: ansi2knr input_file [output_file]\n");
-		exit(0);
-	case 2:
-		out = stdout;
-		break;
-	case 3:
-		out = fopen(argv[2], "w");
-		if ( out == NULL )
-		   {	fprintf(stderr, "Cannot open output file %s\n", argv[2]);
-			exit(1);
-		   }
-	   }
-	in = fopen(argv[1], "r");
-	if ( in == NULL )
-	   {	fprintf(stderr, "Cannot open input file %s\n", argv[1]);
-		exit(1);
-	   }
-	fprintf(out, "#line 1 \"%s\"\n", argv[1]);
-	buf = malloc(bufsize);
-	line = buf;
-	while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
-	   {
-test:		line += strlen(line);
-		switch ( test1(buf) )
-		   {
-		case 2:			/* a function header */
-			convert1(buf, out, 1, convert_varargs);
-			break;
-		case 1:			/* a function */
-			/* Check for a { at the start of the next line. */
-			more = ++line;
-f:			if ( line >= buf + (bufsize - 1) ) /* overflow check */
-			  goto wl;
-			if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
-			  goto wl;
-			switch ( *skipspace(more, 1) )
-			  {
-			  case '{':
-			    /* Definitely a function header. */
-			    convert1(buf, out, 0, convert_varargs);
-			    fputs(more, out);
-			    break;
-			  case 0:
-			    /* The next line was blank or a comment: */
-			    /* keep scanning for a non-comment. */
-			    line += strlen(line);
-			    goto f;
-			  default:
-			    /* buf isn't a function header, but */
-			    /* more might be. */
-			    fputs(buf, out);
-			    strcpy(buf, more);
-			    line = buf;
-			    goto test;
-			  }
-			break;
-		case -1:		/* maybe the start of a function */
-			if ( line != buf + (bufsize - 1) ) /* overflow check */
-			  continue;
-			/* falls through */
-		default:		/* not a function */
-wl:			fputs(buf, out);
-			break;
-		   }
-		line = buf;
-	   }
-	if ( line != buf )
-	  fputs(buf, out);
-	free(buf);
-	fclose(out);
-	fclose(in);
-	return 0;
-}
-
-/* Skip over space and comments, in either direction. */
-char *
-skipspace(p, dir)
-    register char *p;
-    register int dir;			/* 1 for forward, -1 for backward */
-{	for ( ; ; )
-	   {	while ( is_space(*p) )
-		  p += dir;
-		if ( !(*p == '/' && p[dir] == '*') )
-		  break;
-		p += dir;  p += dir;
-		while ( !(*p == '*' && p[dir] == '/') )
-		   {	if ( *p == 0 )
-			  return p;	/* multi-line comment?? */
-			p += dir;
-		   }
-		p += dir;  p += dir;
-	   }
-	return p;
-}
-
-/*
- * Write blanks over part of a string.
- * Don't overwrite end-of-line characters.
- */
-int
-writeblanks(start, end)
-    char *start;
-    char *end;
-{	char *p;
-	for ( p = start; p < end; p++ )
-	  if ( *p != '\r' && *p != '\n' )
-	    *p = ' ';
-	return 0;
-}
-
-/*
- * Test whether the string in buf is a function definition.
- * The string may contain and/or end with a newline.
- * Return as follows:
- *	0 - definitely not a function definition;
- *	1 - definitely a function definition;
- *	2 - definitely a function prototype (NOT USED);
- *	-1 - may be the beginning of a function definition,
- *		append another line and look again.
- * The reason we don't attempt to convert function prototypes is that
- * Ghostscript's declaration-generating macros look too much like
- * prototypes, and confuse the algorithms.
- */
-int
-test1(buf)
-    char *buf;
-{	register char *p = buf;
-	char *bend;
-	char *endfn;
-	int contin;
-
-	if ( !isidfirstchar(*p) )
-	  return 0;		/* no name at left margin */
-	bend = skipspace(buf + strlen(buf) - 1, -1);
-	switch ( *bend )
-	   {
-	   case ';': contin = 0 /*2*/; break;
-	   case ')': contin = 1; break;
-	   case '{': return 0;		/* not a function */
-	   case '}': return 0;		/* not a function */
-	   default: contin = -1;
-	   }
-	while ( isidchar(*p) )
-	  p++;
-	endfn = p;
-	p = skipspace(p, 1);
-	if ( *p++ != '(' )
-	  return 0;		/* not a function */
-	p = skipspace(p, 1);
-	if ( *p == ')' )
-	  return 0;		/* no parameters */
-	/* Check that the apparent function name isn't a keyword. */
-	/* We only need to check for keywords that could be followed */
-	/* by a left parenthesis (which, unfortunately, is most of them). */
-	   {	static char *words[] =
-		   {	"asm", "auto", "case", "char", "const", "double",
-			"extern", "float", "for", "if", "int", "long",
-			"register", "return", "short", "signed", "sizeof",
-			"static", "switch", "typedef", "unsigned",
-			"void", "volatile", "while", 0
-		   };
-		char **key = words;
-		char *kp;
-		int len = endfn - buf;
-
-		while ( (kp = *key) != 0 )
-		   {	if ( strlen(kp) == len && !strncmp(kp, buf, len) )
-			  return 0;	/* name is a keyword */
-			key++;
-		   }
-	   }
-	return contin;
-}
-
-/* Convert a recognized function definition or header to K&R syntax. */
-int
-convert1(buf, out, header, convert_varargs)
-    char *buf;
-    FILE *out;
-    int header;			/* Boolean */
-    int convert_varargs;	/* Boolean */
-{	char *endfn;
-	register char *p;
-	char **breaks;
-	unsigned num_breaks = 2;	/* for testing */
-	char **btop;
-	char **bp;
-	char **ap;
-	char *vararg = 0;
-
-	/* Pre-ANSI implementations don't agree on whether strchr */
-	/* is called strchr or index, so we open-code it here. */
-	for ( endfn = buf; *(endfn++) != '('; )
-	  ;
-top:	p = endfn;
-	breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
-	if ( breaks == 0 )
-	   {	/* Couldn't allocate break table, give up */
-		fprintf(stderr, "Unable to allocate break table!\n");
-		fputs(buf, out);
-		return -1;
-	   }
-	btop = breaks + num_breaks * 2 - 2;
-	bp = breaks;
-	/* Parse the argument list */
-	do
-	   {	int level = 0;
-		char *lp = NULL;
-		char *rp;
-		char *end = NULL;
-
-		if ( bp >= btop )
-		   {	/* Filled up break table. */
-			/* Allocate a bigger one and start over. */
-			free((char *)breaks);
-			num_breaks <<= 1;
-			goto top;
-		   }
-		*bp++ = p;
-		/* Find the end of the argument */
-		for ( ; end == NULL; p++ )
-		   {	switch(*p)
-			   {
-			   case ',':
-				if ( !level ) end = p;
-				break;
-			   case '(':
-				if ( !level ) lp = p;
-				level++;
-				break;
-			   case ')':
-				if ( --level < 0 ) end = p;
-				else rp = p;
-				break;
-			   case '/':
-				p = skipspace(p, 1) - 1;
-				break;
-			   default:
-				;
-			   }
-		   }
-		/* Erase any embedded prototype parameters. */
-		if ( lp )
-		  writeblanks(lp + 1, rp);
-		p--;			/* back up over terminator */
-		/* Find the name being declared. */
-		/* This is complicated because of procedure and */
-		/* array modifiers. */
-		for ( ; ; )
-		   {	p = skipspace(p - 1, -1);
-			switch ( *p )
-			   {
-			   case ']':	/* skip array dimension(s) */
-			   case ')':	/* skip procedure args OR name */
-			   {	int level = 1;
-				while ( level )
-				 switch ( *--p )
-				   {
-				   case ']': case ')': level++; break;
-				   case '[': case '(': level--; break;
-				   case '/': p = skipspace(p, -1) + 1; break;
-				   default: ;
-				   }
-			   }
-				if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
-				   {	/* We found the name being declared */
-					while ( !isidfirstchar(*p) )
-					  p = skipspace(p, 1) + 1;
-					goto found;
-				   }
-				break;
-			   default:
-				goto found;
-			   }
-		   }
-found:		if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
-		  {	if ( convert_varargs )
-			  {	*bp++ = "va_alist";
-				vararg = p-2;
-			  }
-			else
-			  {	p++;
-				if ( bp == breaks + 1 )	/* sole argument */
-				  writeblanks(breaks[0], p);
-				else
-				  writeblanks(bp[-1] - 1, p);
-				bp--;
-			  }
-		   }
-		else
-		   {	while ( isidchar(*p) ) p--;
-			*bp++ = p+1;
-		   }
-		p = end;
-	   }
-	while ( *p++ == ',' );
-	*bp = p;
-	/* Make a special check for 'void' arglist */
-	if ( bp == breaks+2 )
-	   {	p = skipspace(breaks[0], 1);
-		if ( !strncmp(p, "void", 4) )
-		   {	p = skipspace(p+4, 1);
-			if ( p == breaks[2] - 1 )
-			   {	bp = breaks;	/* yup, pretend arglist is empty */
-				writeblanks(breaks[0], p + 1);
-			   }
-		   }
-	   }
-	/* Put out the function name and left parenthesis. */
-	p = buf;
-	while ( p != endfn ) putc(*p, out), p++;
-	/* Put out the declaration. */
-	if ( header )
-	  {	fputs(");", out);
-		for ( p = breaks[0]; *p; p++ )
-		  if ( *p == '\r' || *p == '\n' )
-		    putc(*p, out);
-	  }
-	else
-	  {	for ( ap = breaks+1; ap < bp; ap += 2 )
-		  {	p = *ap;
-			while ( isidchar(*p) )
-			  putc(*p, out), p++;
-			if ( ap < bp - 1 )
-			  fputs(", ", out);
-		  }
-		fputs(")  ", out);
-		/* Put out the argument declarations */
-		for ( ap = breaks+2; ap <= bp; ap += 2 )
-		  (*ap)[-1] = ';';
-		if ( vararg != 0 )
-		  {	*vararg = 0;
-			fputs(breaks[0], out);		/* any prior args */
-			fputs("va_dcl", out);		/* the final arg */
-			fputs(bp[0], out);
-		  }
-		else
-		  fputs(breaks[0], out);
-	  }
-	free((char *)breaks);
-	return 0;
-}
diff --git a/example.c b/example.c
index 088aad3..a83ea48 100644
--- a/example.c
+++ b/example.c
@@ -151,7 +151,7 @@
    /* tell libpng to strip 16 bit/color files down to 8 bits/color */
    png_set_strip_16(png_ptr);
 
-   /* Strip alpha bytes from the input data without combining with th
+   /* Strip alpha bytes from the input data without combining with the
     * background (not recommended).
     */
    png_set_strip_alpha(png_ptr);
diff --git a/libpng.3 b/libpng.3
index f970736..47091d4 100644
--- a/libpng.3
+++ b/libpng.3
@@ -1,416 +1,610 @@
-.TH LIBPNG 3 "January 14, 1999"
+.TH LIBPNG 3 "September 17, 1999"
 .SH NAME
-libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
+libpng \- Portable Network Graphics (PNG) Reference Library 1.0.4 - September 17, 1999
 .SH SYNOPSIS
+\fI\fB
 
-#include <png.h>
+\fB#include <png.h>\fP
 
-int png_check_sig (png_bytep sig, int num);
+\fI\fB
 
-void png_chunk_error (png_structp png_ptr, png_const_charp
-error);
+\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP
 
-void png_chunk_warning (png_structp png_ptr, png_const_charp
-message);
+\fI\fB
 
-void png_convert_from_struct_tm (png_timep ptime, struct tm FAR
-* ttime);
+\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
 
-void png_convert_from_time_t (png_timep ptime, time_t ttime);
+\fI\fB
 
-png_charp png_convert_to_rfc1123 (png_structp png_ptr,
-png_timep ptime);
+\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-png_infop png_create_info_struct (png_structp png_ptr);
+\fI\fB
 
-png_structp png_create_read_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
+\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
 
-png_structp png_create_read_struct_2(png_const_charp user_png_ver,
-png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr
-warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
-png_free_ptr free_fn)
+\fI\fB
 
-png_structp png_create_write_struct (png_const_charp
-user_png_ver, voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn);
+\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
 
-png_structp png_create_write_struct_2(png_const_charp
-user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
-png_error_ptr warn_fn, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+\fI\fB
 
-int png_debug(int level, png_const_charp message)
+\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
 
-int png_debug1(int level, png_const_charp message, p1)
+\fI\fB
 
-int png_debug2(int level, png_const_charp message, p1, p2)
+\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_destroy_info_struct (png_structp png_ptr, png_infopp
-info_ptr_ptr);
+\fI\fB
 
-void png_destroy_read_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr);
+\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)
+
+\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
+
+\fI\fB
 
-void png_destroy_write_struct (png_structpp png_ptr_ptr,
-png_infopp info_ptr_ptr);
+\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
 
-void png_error (png_structp png_ptr, png_const_charp error);
+\fI\fB
 
-void png_free (png_structp png_ptr, png_voidp ptr);
+\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
 
-void png_free_default(png_structp png_ptr, png_voidp ptr)
+\fI\fB
 
-png_byte png_get_bit_depth (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
 
-png_uint_32 png_get_bKGD (png_structp png_ptr, png_infop
-info_ptr, png_color_16p *background);
+\fI\fB
 
-png_byte png_get_channels (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP
 
-png_uint_32 png_get_cHRM (png_structp png_ptr, png_infop
-info_ptr, double *white_x, double *white_y, double *red_x,
-double *red_y, double *green_x, double *green_y, double
-*blue_x, double *blue_y);
+\fI\fB
 
-png_byte png_get_color_type (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
 
-png_byte png_get_compression_type (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_byte png_get_copyright (png_structp png_ptr);
+\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_voidp png_get_error_ptr (png_structp png_ptr);
+\fI\fB
 
-png_byte png_get_filter_type (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
 
-png_uint_32 png_get_gAMA (png_structp png_ptr, png_infop
-info_ptr, double *file_gamma);
+\fI\fB
 
-png_byte png_get_header_version (png_structp png_ptr);
+\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
 
-png_uint_32 png_get_hIST (png_structp png_ptr, png_infop
-info_ptr, png_uint_16p *hist);
+\fI\fB
 
-png_uint_32 png_get_IHDR (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *width, png_uint_32 *height, int
-*bit_depth, int *color_type, int *interlace_type, int
-*compression_type, int *filter_type);
+\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
 
-png_uint_32 png_get_image_height (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_image_width (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
 
-png_byte png_get_interlace_type (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-png_voidp png_get_io_ptr (png_structp png_ptr);
+\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
 
-png_voidp png_get_mem_ptr(png_structp png_ptr)
+\fI\fB
 
-png_uint_32 png_get_oFFs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y, int
-*unit_type);
+\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
 
-png_uint_32 png_get_pCAL (png_structp png_ptr, png_infop
-info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
-int *type, int *nparams, png_charp *units, png_charpp *params);
+\fI\fB
 
-png_uint_32 png_get_pHYs (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int
-*unit_type);
+\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
 
-float png_get_pixel_aspect_ratio (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_voidp png_get_progressive_ptr (png_structp png_ptr);
+\fI\fB
 
-png_uint_32 png_get_PLTE (png_structp png_ptr, png_infop
-info_ptr, png_colorp *palette, int *num_palette);
+\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
 
-png_byte png_get_rgb_to_gray_status (png_structp png_ptr)
+\fI\fB
 
-png_uint_32 png_get_rowbytes (png_structp png_ptr, png_infop
-info_ptr);
+\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_sBIT (png_structp png_ptr, png_infop
-info_ptr, png_color_8p *sig_bit);
+\fI\fB
 
-png_bytep png_get_signature (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_sRGB (png_structp png_ptr, png_infop
-info_ptr, int *intent);
+\fI\fB
 
-png_uint_32 png_get_text (png_structp png_ptr, png_infop
-info_ptr, png_textp *text_ptr, int *num_text);
+\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_tIME (png_structp png_ptr, png_infop
-info_ptr, png_timep *mod_time);
+\fI\fB
 
-png_uint_32 png_get_tRNS (png_structp png_ptr, png_infop
-info_ptr, png_bytep *trans, int *num_trans, png_color_16p
-*trans_values);
+\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
 
-png_uint_32 png_get_valid (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 flag);
+\fI\fB
 
-png_uint_32 png_get_x_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
 
-png_uint_32 png_get_x_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_x_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-png_uint_32 png_get_y_offset_microns (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-png_uint_32 png_get_y_offset_pixels (png_structp png_ptr,
-png_infop info_ptr);
+\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
 
-png_uint_32 png_get_y_pixels_per_meter (png_structp png_ptr,
-png_infop info_ptr);
+\fI\fB
 
-void png_info_init (png_infop info_ptr);
+\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_init_io (png_structp png_ptr, FILE *fp);
+\fI\fB
 
-png_voidp png_malloc (png_structp png_ptr, png_uint_32 size);
+\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP
 
-png_voidp png_malloc_default(png_structp png_ptr,
-png_uint_32 size)
+\fI\fB
 
-voidp png_memcpy (png_voidp s1, png_voidp s2, png_size_t size);
+\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
 
-png_voidp png_memcpy_check (png_structp png_ptr, png_voidp s1,
-png_voidp s2, png_uint_32 size);
+\fI\fB
 
-voidp png_memset (png_voidp s1, int value, png_size_t size);
+\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
 
-png_voidp png_memset_check (png_structp png_ptr, png_voidp
-s1, int value, png_uint_32 size);
+\fI\fB
 
-void png_process_data (png_structp png_ptr, png_infop info_ptr,
-png_bytep buffer, png_size_t buffer_size);
+\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
 
-void png_progressive_combine_row (png_structp png_ptr,
-png_bytep old_row, png_bytep new_row);
+\fI\fB
 
-void png_read_destroy (png_structp png_ptr, png_infop info_ptr,
-png_infop end_info_ptr);
+\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
 
-void png_read_end (png_structp png_ptr, png_infop info_ptr);
+\fI\fB
 
-void png_read_image (png_structp png_ptr, png_bytepp image);
+\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
 
-void png_read_info (png_structp png_ptr, png_infop info_ptr);
+\fI\fB
 
-void png_read_row (png_structp png_ptr, png_bytep row,
-png_bytep display_row);
+\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
 
-void png_read_rows (png_structp png_ptr, png_bytepp row,
-png_bytepp display_row, png_uint_32 num_rows);
+\fI\fB
 
-void png_read_update_info (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
 
-void png_set_background (png_structp png_ptr, png_color_16p
-background_color, int background_gamma_code, int need_expand,
-double background_gamma);
+\fI\fB
 
-void png_set_bgr (png_structp png_ptr);
+\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fIerror_action\fP\fB);\fP
 
-void png_set_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_color_16p background);
+\fI\fB
 
-void png_set_cHRM (png_structp png_ptr, png_infop info_ptr,
-double white_x, double white_y, double red_x, double red_y,
-double green_x, double green_y, double blue_x, double blue_y);
+\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
 
-void png_set_compression_level (png_structp png_ptr, int
-level);
+\fI\fB
 
-void png_set_compression_mem_level (png_structp png_ptr, int
-mem_level);
+\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
 
-void png_set_compression_method (png_structp png_ptr, int
-method);
+\fI\fB
 
-void png_set_compression_strategy (png_structp png_ptr, int
-strategy);
+\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
 
-void png_set_compression_window_bits (png_structp png_ptr, int
-window_bits);
+\fI\fB
 
-void png_set_crc_action (png_structp png_ptr, int crit_action,
-int ancil_action);
+\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
 
-void png_set_dither (png_structp png_ptr, png_colorp palette,
-int num_palette, int maximum_colors, png_uint_16p histogram,
-int full_dither);
+\fI\fB
 
-void png_set_error_fn (png_structp png_ptr, png_voidp
-error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn);
+\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
 
-void png_set_expand (png_structp png_ptr);
+\fI\fB
 
-void png_set_filler (png_structp png_ptr, png_uint_32 filler,
-int flags);
+\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_filter (png_structp png_ptr, int method, int
-filters);
+\fI\fB
 
-void png_set_filter_heuristics (png_structp png_ptr, int
-heuristic_method, int num_weights, png_doublep filter_weights,
-png_doublep filter_costs);
+\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_flush (png_structp png_ptr, int nrows);
+\fI\fB
 
-void png_set_gamma (png_structp png_ptr, double screen_gamma,
-double default_file_gamma);
+\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_gAMA (png_structp png_ptr, png_infop info_ptr,
-double file_gamma);
+\fI\fB
 
-void png_set_gray_to_rgb (png_structp png_ptr);
+\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_16p hist);
+\fI\fB
 
-int png_set_interlace_handling (png_structp png_ptr);
+\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
 
-void png_set_invert_alpha (png_structp png_ptr);
+\fI\fB
 
-void png_set_invert_mono (png_structp png_ptr);
+\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
 
-void png_set_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 width, png_uint_32 height, int bit_depth, int
-color_type, int interlace_type, int compression_type, int
-filter_type);
+\fI\fB
 
-void png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr,
-png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP
 
-void png_set_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 offset_x, png_uint_32 offset_y, int unit_type);
+\fI\fB
 
-void png_set_packing (png_structp png_ptr);
+\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_packswap (png_structp png_ptr);
+\fI\fB
 
-void png_set_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int
-nparams, png_charp units, png_charpp params);
+\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
 
-void png_set_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 res_x, png_uint_32 res_y, int unit_type);
+\fI\fB
 
-void png_set_progressive_read_fn (png_structp png_ptr,
-png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
-png_progressive_row_ptr row_fn, png_progressive_end_ptr
-end_fn);
+\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
 
-void png_set_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_colorp palette, int num_palette);
+\fI\fB
 
-void png_set_read_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr read_data_fn);
+\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
 
-void png_set_read_status_fn (png_structp png_ptr, png_read_status_ptr
-read_row_fn);
+\fI\fB
 
-void png_set_read_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr read_user_transform_fn);
+\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
 
-void png_set_rgb_to_gray (png_structp png_ptr, int error_action);
+\fI\fB
 
-void png_set_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_color_8p sig_bit);
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
 
-void png_set_shift (png_structp png_ptr, png_color_8p
-true_bits);
+\fI\fB
 
-void png_set_sig_bytes (png_structp png_ptr, int num_bytes);
+\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_sRGB (png_structp png_ptr, png_infop info_ptr, int
-intent);
+\fI\fB
 
-void png_set_sRGB_gAMA_and_cHRM (png_structp png_ptr, png_infop
-info_ptr, int intent);
+\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
 
-void png_set_strip_16 (png_structp png_ptr);
+\fI\fB
 
-void png_set_strip_alpha (png_structp png_ptr);
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_set_swap (png_structp png_ptr);
+\fI\fB
 
-void png_set_swap_alpha (png_structp png_ptr);
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_set_text (png_structp png_ptr, png_infop info_ptr,
-png_textp text_ptr, int num_text);
+\fI\fB
 
-void png_set_tIME (png_structp png_ptr, png_infop info_ptr,
-png_timep mod_time);
+\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_set_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_bytep trans, int num_trans, png_color_16p trans_values);
+\fI\fB
 
-void png_set_write_fn (png_structp png_ptr, png_voidp io_ptr,
-png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn);
+\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_set_write_status_fn (png_structp png_ptr, png_write_status_ptr
-write_row_fn);
+\fI\fB
 
-void png_set_write_user_transform_fn (png_structp png_ptr,
-png_user_transform_ptr write_user_transform_fn);
+\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP
 
-int png_sig_cmp (png_bytep sig, png_size_t start, png_size_t
-num_to_check);
+\fI\fB
 
-void png_start_read_image (png_structp png_ptr);
+\fBvoid png_write_destroy_info (png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_warning (png_structp png_ptr, png_const_charp
-message);
+\fI\fB
 
-void png_write_chunk (png_structp png_ptr, png_bytep
-chunk_name, png_bytep data, png_size_t length);
+\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_write_chunk_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fI\fB
 
-void png_write_chunk_end (png_structp png_ptr);
+\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_write_chunk_start (png_structp png_ptr, png_bytep
-chunk_name, png_uint_32 length);
+\fI\fB
 
-void png_write_destroy (png_structp png_ptr);
+\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
 
-void png_write_destroy_info (png_infop info_ptr);
+\fI\fB
 
-void png_write_end (png_structp png_ptr, png_infop info_ptr);
+\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_write_flush (png_structp png_ptr);
+\fI\fB
 
-void png_write_image (png_structp png_ptr, png_bytepp image);
+\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_write_info (png_structp png_ptr, png_infop info_ptr);
+\fI\fB
 
-void png_write_row (png_structp png_ptr, png_bytep row);
+\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
 
-void png_write_rows (png_structp png_ptr, png_bytepp row,
-png_uint_32 num_rows);
+\fI\fB
 
 .SH DESCRIPTION
 The
@@ -423,9 +617,9 @@
 .SH LIBPNG.TXT
 libpng.txt - A description on how to use and modify libpng
 
- libpng version 1.0.3 - January 14, 1999
+ libpng version 1.0.4 - September 17, 1999
  Updated and distributed by Glenn Randers-Pehrson
- <randeg@alumni.rpi.edu>
+ <randeg@alum.rpi.edu>
  Copyright (c) 1998, 1999 Glenn Randers-Pehrson
  For conditions of distribution and use, see copyright
  notice in png.h.
@@ -445,6 +639,7 @@
  Copyright (c) 1995 Frank J. T. Wojcik
  December 18, 1995 && January 20, 1996
 
+ *
 .SH I. Introduction
 
 This file describes how to use and modify the PNG reference library
@@ -458,11 +653,17 @@
 
 Libpng was written as a companion to the PNG specification, as a way
 of reducing the amount of time and effort it takes to support the PNG
-file format in application programs.  The PNG specification is available
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.cdrom.com/png>.
+
+The PNG-1.0 specification is available
 as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
 W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
 additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>.  Other information
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
 about PNG, and the latest version of libpng, can be found at the PNG home
 page, <http://www.cdrom.com/pub/png/>.
 
@@ -684,6 +885,21 @@
 See pngtest.c for a working example.  Your function will be called
 after all of the other transformations have been processed.
 
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
 You are now ready to read all the file information up to the actual
 image data.  You do this with a call to png_read_info().
 
@@ -929,13 +1145,18 @@
 viewing application that wishes to treat all images in the same way.
 
     if (color_type == PNG_COLOR_TYPE_PALETTE &&
-        bit_depth <= 8) png_set_expand(png_ptr);
+        bit_depth <= 8) png_set_palette_to_rgb(png_ptr);
 
     if (color_type == PNG_COLOR_TYPE_GRAY &&
-        bit_depth < 8) png_set_expand(png_ptr);
+        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
 
     if (png_get_valid(png_ptr, info_ptr,
-        PNG_INFO_tRNS)) png_set_expand(png_ptr);
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
 
 PNG can have files with 16 bits per channel.  If you only can handle
 8 bits per channel, this will strip the pixels down to 8 bit.
@@ -1022,7 +1243,7 @@
     if (color_type == PNG_COLOR_TYPE_RGB ||
         color_type == PNG_COLOR_TYPE_RGB_ALPHA)
           png_set_rgb_to_gray(png_ptr, error_action,
-             float red_weight, float green_weight);
+             double red_weight, double green_weight);
 
     error_action = 1: silently do the conversion
     error_action = 2: issue a warning if the original
@@ -1071,7 +1292,8 @@
 The calculation is done in a linear colorspace, if the image gamma
 is known.
 
-If you have a grayscale and you are using png_set_expand() to change to
+If you have a grayscale and you are using png_set_expand_depth() or
+png_set_expand() to change to
 a higher bit-depth, you must either supply the background color as a gray
 value at the original file bit-depth (need_expand = 1) or else supply the
 background color as an RGB triplet at the final, expanded bit depth
@@ -1104,6 +1326,8 @@
 a (viewing_gamma=1.25) environment.  In a dim or brightly lit room, no
 compensation other than the display_gamma is needed (viewing_gamma=1.0).
 
+   double gamma, screen_gamma;
+
    if (/* We have a user-defined screen
        gamma value */)
    {
@@ -1114,7 +1338,7 @@
    else if ((gamma_str = getenv("SCREEN_GAMMA"))
       != NULL)
    {
-      screen_gamma = atof(gamma_str);
+      screen_gamma = (double)atof(gamma_str);
    }
    /* If we don't have another value */
    else
@@ -1254,7 +1478,7 @@
     png_read_row(png_ptr, &row_pointers, NULL);
 
 If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder.  The only current (PNG Specification version 1.0)
+somewhat harder.  The only current (PNG Specification version 1.2)
 interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
 is a somewhat complicated 2D interlace scheme, known as Adam7, that
 breaks down an image into seven smaller images of varying size, based
@@ -1617,7 +1841,7 @@
 not calling this function at all, as it has been tuned to deliver a good
 speed/compression ratio. The second parameter to png_set_filter() is
 the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0).  The third parameter is a
+July 1999 PNG specification, version 1.2).  The third parameter is a
 flag that indicates which filter type(s) are to be tested for each
 scanline.  See the Compression Library for details on the specific filter
 types.
@@ -1649,7 +1873,7 @@
 You now need to fill in the png_info structure with all the data you
 wish to write before the actual image.  Note that the only thing you
 are allowed to write after the image is the text chunks and the time
-chunk (as of PNG Specification 1.0, anyway).  See png_write_end() and
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
 the latest PNG specification for more information on that.  If you
 wish to write them before the image, fill them in now, and flag that
 data as being valid.  If you want to wait until after the data, don't
@@ -1978,7 +2202,21 @@
        row_info, png_bytep data)
 
 See pngtest.c for a working example.  Your function will be called
-before any of the other transformations have been processed.
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
 
 It is possible to have libpng flush any pending output, either manually,
 or automatically after a certain number of lines have been written.  To
@@ -2035,8 +2273,8 @@
     png_write_row(png_ptr, &row_pointer);
 
 When the file is interlaced, things can get a good deal more
-complicated.  The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
+complicated.  The only currently (as of August 1999 -- PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
 is the "Adam7" interlace scheme, that breaks down an
 image into seven smaller images of varying size.  libpng will build
 these images for you, or you can do them yourself.  If you want to
@@ -2081,7 +2319,6 @@
 
 For a more compact example of writing a PNG image, see the file example.c.
 
-
 .SH V. Modifying/Customizing libpng:
 
 There are two issues here.  The first is changing how libpng does
@@ -2108,7 +2345,8 @@
 png_struct and is initialized via png_init_io().  If you wish to change
 the method of I/O, the library supplies callbacks that you can set
 through the function png_set_read_fn() and png_set_write_fn() at run
-time, instead of calling the png_init_io() function.  These functions
+time, instead of calling the png_init_io() function.
+These functions
 also provide a void pointer that can be retrieved via the function
 png_get_io_ptr().  For example:
 
@@ -2275,7 +2513,7 @@
 for any images with bit depths less than 8 bits/pixel.
 
 The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification.  The 'filters'
+currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
 scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
 to turn filtering on and off, respectively.
@@ -2444,9 +2682,9 @@
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant.  It is my belief that earlier versions were
-also Y2K compliant.
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.0.4 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
 
 Libpng only has three year fields.  One is a 2-byte unsigned integer that
 will hold years up to 65535.  The other two hold the date in text
@@ -2475,15 +2713,18 @@
 clock time, which returns (year - 1900), which we properly convert to
 the full 4-digit year.  There is a possibility that applications using
 libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control.  The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
 
 The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
 integer to hold the year, and can hold years as large as 65535.
 
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
 
    Glenn Randers-Pehrson
    libpng maintainer
@@ -2560,13 +2801,13 @@
 
 .SH AUTHORS
 This man page: Glenn Randers-Pehrson
-<randeg@alumni.rpi.edu>
+<randeg@alum.rpi.edu>
   
 Contributing Authors: John Bowler, Kevin Bracey, Sam Bushell, Andreas Dilger,
 Magnus Holmgren, Tom Lane, Dave Martindale, Glenn Randers-Pehrson,
 Greg Roelofs, Guy Eric Schalnat, Paul Schmidt, Tom Tanner, Willem van
 Schaik, Tim Wegner.
-<png-implement@dworkin.wustl.edu>
+<png-implement@ccrc.wustl.edu>
 
 The contributing authors would like to thank all those who helped
 with testing, bug fixes, and patience.  This wouldn't have been
@@ -2574,19 +2815,19 @@
 
 Thanks to Frank J. T. Wojcik for helping with the documentation.
   
-Libpng version 1.0.3 - January 14, 1999:
+Libpng version 1.0.4 - September 17, 1999:
 Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
-Currently maintained by Glenn Randers-Pehrson (randeg@alumni.rpi.edu).
+Currently maintained by Glenn Randers-Pehrson (randeg@alum.rpi.edu).
 
 Supported by the PNG development group
 .br
-(png-implement@dworkin.wustl.edu).
+(png-implement@ccrc.wustl.edu).
 
 .SH COPYRIGHT NOTICE:
 
-Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
-Copyright (c) 1996, 1997 Andreas Dilger
 Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+Copyright (c) 1996, 1997 Andreas Dilger
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
 
 The PNG Reference Library (libpng) is supplied "AS IS".  The Contributing
 Authors and Group 42, Inc. disclaim all warranties, expressed or implied,
@@ -2617,5 +2858,13 @@
 source code in a product, acknowledgment is not required but would be
 appreciated.
 
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+   printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+file "pngnow.png".
+
 .\" end of man page
 
diff --git a/libpng.txt b/libpng.txt
index 1a30a9f..f0171b1 100644
--- a/libpng.txt
+++ b/libpng.txt
@@ -1,8 +1,8 @@
 libpng.txt - A description on how to use and modify libpng
 
- libpng version 1.0.3 - January 14, 1999
+ libpng version 1.0.4 - September 17, 1999
  Updated and distributed by Glenn Randers-Pehrson
- <randeg@alumni.rpi.edu>
+ <randeg@alum.rpi.edu>
  Copyright (c) 1998, 1999 Glenn Randers-Pehrson
  For conditions of distribution and use, see copyright
  notice in png.h.
@@ -22,6 +22,7 @@
  Copyright (c) 1995 Frank J. T. Wojcik
  December 18, 1995 && January 20, 1996
 
+ *
 I. Introduction
 
 This file describes how to use and modify the PNG reference library
@@ -35,11 +36,17 @@
 
 Libpng was written as a companion to the PNG specification, as a way
 of reducing the amount of time and effort it takes to support the PNG
-file format in application programs.  The PNG specification is available
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.cdrom.com/png>.
+
+The PNG-1.0 specification is available
 as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
 W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
 additional chunks are described in the special-purpose public chunks
-documents at <ftp://ftp.uu.net/graphics/png/documents/>.  Other information
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
 about PNG, and the latest version of libpng, can be found at the PNG home
 page, <http://www.cdrom.com/pub/png/>.
 
@@ -261,6 +268,21 @@
 See pngtest.c for a working example.  Your function will be called
 after all of the other transformations have been processed.
 
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+    png_set_user_transform_info(png_ptr, user_ptr,
+       user_depth, user_channels);
+
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp read_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
+
 You are now ready to read all the file information up to the actual
 image data.  You do this with a call to png_read_info().
 
@@ -506,13 +528,18 @@
 viewing application that wishes to treat all images in the same way.
 
     if (color_type == PNG_COLOR_TYPE_PALETTE &&
-        bit_depth <= 8) png_set_expand(png_ptr);
+        bit_depth <= 8) png_set_palette_to_rgb(png_ptr);
 
     if (color_type == PNG_COLOR_TYPE_GRAY &&
-        bit_depth < 8) png_set_expand(png_ptr);
+        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
 
     if (png_get_valid(png_ptr, info_ptr,
-        PNG_INFO_tRNS)) png_set_expand(png_ptr);
+        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability.  In some future version they may actually do different
+things.
 
 PNG can have files with 16 bits per channel.  If you only can handle
 8 bits per channel, this will strip the pixels down to 8 bit.
@@ -599,7 +626,7 @@
     if (color_type == PNG_COLOR_TYPE_RGB ||
         color_type == PNG_COLOR_TYPE_RGB_ALPHA)
           png_set_rgb_to_gray(png_ptr, error_action,
-             float red_weight, float green_weight);
+             double red_weight, double green_weight);
 
     error_action = 1: silently do the conversion
     error_action = 2: issue a warning if the original
@@ -648,7 +675,8 @@
 The calculation is done in a linear colorspace, if the image gamma
 is known.
 
-If you have a grayscale and you are using png_set_expand() to change to
+If you have a grayscale and you are using png_set_expand_depth() or
+png_set_expand() to change to
 a higher bit-depth, you must either supply the background color as a gray
 value at the original file bit-depth (need_expand = 1) or else supply the
 background color as an RGB triplet at the final, expanded bit depth
@@ -681,6 +709,8 @@
 a (viewing_gamma=1.25) environment.  In a dim or brightly lit room, no
 compensation other than the display_gamma is needed (viewing_gamma=1.0).
 
+   double gamma, screen_gamma;
+
    if (/* We have a user-defined screen
        gamma value */)
    {
@@ -691,7 +721,7 @@
    else if ((gamma_str = getenv("SCREEN_GAMMA"))
       != NULL)
    {
-      screen_gamma = atof(gamma_str);
+      screen_gamma = (double)atof(gamma_str);
    }
    /* If we don't have another value */
    else
@@ -831,7 +861,7 @@
     png_read_row(png_ptr, &row_pointers, NULL);
 
 If the file is interlaced (info_ptr->interlace_type != 0), things get
-somewhat harder.  The only current (PNG Specification version 1.0)
+somewhat harder.  The only current (PNG Specification version 1.2)
 interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
 is a somewhat complicated 2D interlace scheme, known as Adam7, that
 breaks down an image into seven smaller images of varying size, based
@@ -1194,7 +1224,7 @@
 not calling this function at all, as it has been tuned to deliver a good
 speed/compression ratio. The second parameter to png_set_filter() is
 the filter method, for which the only valid value is '0' (as of the
-October 1996 PNG specification, version 1.0).  The third parameter is a
+July 1999 PNG specification, version 1.2).  The third parameter is a
 flag that indicates which filter type(s) are to be tested for each
 scanline.  See the Compression Library for details on the specific filter
 types.
@@ -1226,7 +1256,7 @@
 You now need to fill in the png_info structure with all the data you
 wish to write before the actual image.  Note that the only thing you
 are allowed to write after the image is the text chunks and the time
-chunk (as of PNG Specification 1.0, anyway).  See png_write_end() and
+chunk (as of PNG Specification 1.2, anyway).  See png_write_end() and
 the latest PNG specification for more information on that.  If you
 wish to write them before the image, fill them in now, and flag that
 data as being valid.  If you want to wait until after the data, don't
@@ -1555,7 +1585,21 @@
        row_info, png_bytep data)
 
 See pngtest.c for a working example.  Your function will be called
-before any of the other transformations have been processed.
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr().  For example:
+
+    voidp write_user_transform_ptr =
+       png_get_user_transform_ptr(png_ptr);
 
 It is possible to have libpng flush any pending output, either manually,
 or automatically after a certain number of lines have been written.  To
@@ -1612,8 +1656,8 @@
     png_write_row(png_ptr, &row_pointer);
 
 When the file is interlaced, things can get a good deal more
-complicated.  The only currently (as of February 1998 -- PNG Specification
-version 1.0, dated October 1996) defined interlacing scheme for PNG files
+complicated.  The only currently (as of August 1999 -- PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
 is the "Adam7" interlace scheme, that breaks down an
 image into seven smaller images of varying size.  libpng will build
 these images for you, or you can do them yourself.  If you want to
@@ -1658,7 +1702,6 @@
 
 For a more compact example of writing a PNG image, see the file example.c.
 
-
 V. Modifying/Customizing libpng:
 
 There are two issues here.  The first is changing how libpng does
@@ -1685,7 +1728,8 @@
 png_struct and is initialized via png_init_io().  If you wish to change
 the method of I/O, the library supplies callbacks that you can set
 through the function png_set_read_fn() and png_set_write_fn() at run
-time, instead of calling the png_init_io() function.  These functions
+time, instead of calling the png_init_io() function.
+These functions
 also provide a void pointer that can be retrieved via the function
 png_get_io_ptr().  For example:
 
@@ -1852,7 +1896,7 @@
 for any images with bit depths less than 8 bits/pixel.
 
 The 'method' parameter sets the main filtering method, which is
-currently only '0' in the PNG 1.0 specification.  The 'filters'
+currently only '0' in the PNG 1.2 specification.  The 'filters'
 parameter sets which filter(s), if any, should be used for each
 scanline.  Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
 to turn filtering on and off, respectively.
@@ -2021,9 +2065,9 @@
 Since the PNG Development group is an ad-hoc body, we can't make
 an official declaration.
 
-This is your unofficial assurance that libpng from version 0.81 and
-upward are Y2K compliant.  It is my belief that earlier versions were
-also Y2K compliant.
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.0.4 are Y2K compliant.  It is my belief that earlier
+versions were also Y2K compliant.
 
 Libpng only has three year fields.  One is a 2-byte unsigned integer that
 will hold years up to 65535.  The other two hold the date in text
@@ -2052,15 +2096,18 @@
 clock time, which returns (year - 1900), which we properly convert to
 the full 4-digit year.  There is a possibility that applications using
 libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
-function, or incorrectly passing only a 2-digit year instead of
-"year - 1900" into the png_convert_from_struct_tm() function, but this
-is not under our control.  The libpng documentation has always stated
-that it works with 4-digit years, and the APIs have been documented as
-such.
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control.  The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
 
 The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
 integer to hold the year, and can hold years as large as 65535.
 
+zlib, upon which libpng depends, is also Y2K compliant.  It contains
+no date-related code.
+
 
    Glenn Randers-Pehrson
    libpng maintainer
diff --git a/libpngpf.3 b/libpngpf.3
index c2654e7..f3eac67 100644
--- a/libpngpf.3
+++ b/libpngpf.3
@@ -3,337 +3,495 @@
 libpng \- Portable Network Graphics (PNG) Reference Library 1.0.3 - January 14, 1999
 (private functions)
 .SH SYNOPSIS
-#include <png.h>
+\fB#include <png.h>\fP
 
-void png_build_gamma_table (png_structp png_ptr);
+\fI\fB
 
-void png_build_grayscale_palette (int bit_depth, png_colorp
-palette);
+\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_calculate_crc (png_structp png_ptr, png_bytep ptr,
-png_size_t length);
-void png_check_chunk_name (png_structp png_ptr, png_bytep
-chunk_name);
+\fI\fB
 
-png_size_t png_check_keyword (png_structp png_ptr, png_charp
-key, png_charpp new_key);
+\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP
 
-void png_combine_row (png_structp png_ptr, png_bytep row, int
-mask);
+\fI\fB
 
-void png_correct_palette (png_structp png_ptr, png_colorp
-palette, int num_palette);
+\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-int png_crc_error (png_structp png_ptr);
+\fI\fB
 
-int png_crc_finish (png_structp png_ptr, png_uint_32 skip);
+\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
 
-void png_crc_read (png_structp png_ptr, png_bytep buf,
-png_size_t length);
+\fI\fB
 
-png_voidp png_create_struct (int type, png_malloc_ptr malloc_fn);
+\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP
 
-png_voidp png_create_struct_2 (int type);
+\fI\fB
 
-void png_destroy_struct (png_voidp struct_ptr);
+\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fImask\fP\fB);\fP
 
-void png_destroy_struct_2 (png_voidp struct_ptr, png_free_ptr
-free_fn);
+\fI\fB
 
-void png_do_background (png_row_infop row_info, png_bytep row,
-png_color_16p trans_values, png_color_16p background,
-png_color_16p background_1, png_bytep gamma_table, png_bytep
-gamma_from_1, png_bytep gamma_to_1, png_uint_16pp gamma_16,
-png_uint_16pp gamma_16_from_1, png_uint_16pp gamma_16_to_1, int
-gamma_shift);
+\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_create_struct (int \fP\fItype\fP\fB, png_malloc_ptr \fImalloc_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_create_struct_2 (int \fItype\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_do_bgr (png_row_infop row_info, png_bytep row);
+\fI\fB
 
-void png_do_chop (png_row_infop row_info, png_bytep row);
+\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_do_dither (png_row_infop row_info, png_bytep row,
-png_bytep palette_lookup, png_bytep dither_lookup);
+\fI\fB
 
-void png_do_expand (png_row_infop row_info, png_bytep row,
-png_color_16p trans_value);
+\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_do_expand_palette (png_row_infop row_info, png_bytep
-row, png_colorp palette, png_bytep trans, int num_trans);
+\fI\fB
 
-void png_do_gamma (png_row_infop row_info, png_bytep row,
-png_bytep gamma_table, png_uint_16pp gamma_16_table, int
-gamma_shift);
+\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_do_gray_to_rgb (png_row_infop row_info, png_bytep
-row);
+\fI\fB
 
-void png_do_invert (png_row_infop row_info, png_bytep row);
+\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
 
-void png_do_pack (png_row_infop row_info, png_bytep row,
-png_uint_32 bit_depth);
+\fI\fB
 
-void png_do_packswap (png_row_infop row_info, png_bytep row);
+\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_do_read_filler (png_row_infop row_info, png_bytep row,
-png_uint_32 filler, png_uint_32 flags);
+\fI\fB
 
-void png_do_read_interlace (png_row_infop row_info, png_bytep
-row, int pass, png_uint_32 transformations);
+\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_do_read_invert_alpha (png_row_infop row_info,
-png_bytep row);
+\fI\fB
 
-void png_do_read_swap_alpha (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
 
-void png_do_read_transformations (png_structp png_ptr);
+\fI\fB
 
-int png_do_rgb_to_gray (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_do_shift (png_row_infop row_info, png_bytep row,
-png_color_8p bit_depth);
+\fI\fB
 
-void png_do_strip_filler (png_row_infop row_info, png_bytep
-row, png_uint_32 flags);
+\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_do_swap (png_row_infop row_info, png_bytep row);
+\fI\fB
 
-void png_do_unpack (png_row_infop row_info, png_bytep row);
+\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_do_unshift (png_row_infop row_info, png_bytep row,
-png_color_8p sig_bits);
+\fI\fB
 
-void png_do_write_interlace (png_row_infop row_info, png_bytep
-row, int pass);
+\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_do_write_invert_alpha (png_row_infop row_info,
-png_bytep row);
+\fI\fB
 
-void png_do_write_swap_alpha (png_row_infop row_info, png_bytep
-row);
+\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_do_write_transformations (png_structp png_ptr);
+\fI\fB
 
-void *png_far_to_near (png_structp png_ptr,png_voidp ptr,
-int check);
+\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_flush (png_structp png_ptr);
+\fI\fB
 
-png_int_32 png_get_int_32 (png_bytep buf);
+\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-png_uint_16 png_get_uint_16 (png_bytep buf);
+\fI\fB
 
-png_uint_32 png_get_uint_32 (png_bytep buf);
+\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
 
-void png_handle_bKGD (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_cHRM (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_handle_gAMA (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_hIST (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_handle_IEND (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_IHDR (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP
 
-void png_handle_oFFs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_pCAL (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_handle_pHYs (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_PLTE (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_init (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_handle_sBIT (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_sRGB (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_handle_tEXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_tIME (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_handle_tRNS (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
 
-void png_handle_zTXt (png_structp png_ptr, png_infop info_ptr,
-png_uint_32 length);
+\fI\fB
 
-void png_info_destroy (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_init_read_transformations (png_structp png_ptr);
+\fI\fB
 
-void png_process_IDAT_data (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
+\fBvoid png_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP
 
-void png_process_some_data (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_check_crc (png_structp png_ptr);
+\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP
 
-void png_push_crc_finish (png_structp png_ptr);
+\fI\fB
 
-void png_push_crc_skip (png_structp png_ptr, png_uint_32
-length);
+\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP
 
-void png_push_fill_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t length);
+\fI\fB
 
-void png_push_handle_tEXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_write_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fIcolor_type\fP\fB);\fP
 
-void png_push_handle_unknown (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fI\fB
 
-void png_push_handle_zTXt (png_structp png_ptr, png_infop
-info_ptr, png_uint_32 length);
+\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
 
-void png_push_have_end (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_have_info (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_push_have_row (png_structp png_ptr, png_bytep row);
+\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP
 
-void png_push_process_row (png_structp png_ptr);
+\fI\fB
 
-void png_push_read_chunk (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_write_find_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP
 
-void png_push_read_end (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_read_IDAT (png_structp png_ptr);
+\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_push_read_sig (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_read_tEXt (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
 
-void png_push_read_zTXt (png_structp png_ptr, png_infop
-info_ptr);
+\fI\fB
 
-void png_push_restore_buffer (png_structp png_ptr, png_bytep
-buffer, png_size_t buffer_length);
+\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP
 
-void png_push_save_buffer (png_structp png_ptr);
+\fI\fB
 
-void png_read_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fBvoid png_write_init (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_read_filter_row (png_structp png_ptr, png_row_infop
-row_info, png_bytep row, png_bytep prev_row, int filter);
+\fI\fB
 
-void png_read_finish_row (png_structp png_ptr);
+\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
 
-void png_read_init (png_structp png_ptr);
+\fI\fB
 
-void png_read_push_finish_row (png_structp png_ptr);
+\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_read_start_row (png_structp png_ptr);
+\fI\fB
 
-void png_read_transform_info (png_structp png_ptr, png_infop
-info_ptr);
+\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP
 
-void png_reset_crc (png_structp png_ptr);
+\fI\fB
 
-void png_save_int_32 (png_bytep buf, png_int_32 i);
+\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP
 
-void png_save_uint_16 (png_bytep buf, unsigned int i);
+\fI\fB
 
-void png_save_uint_32 (png_bytep buf, png_uint_32 i);
+\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
 
-void png_write_bKGD (png_structp png_ptr, png_color_16p values,
-int color_type);
+\fI\fB
 
-void png_write_cHRM (png_structp png_ptr, double white_x,
-double white_y, double red_x, double red_y, double green_x,
-double green_y, double blue_x, double blue_y);
+\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP
 
-void png_write_data (png_structp png_ptr, png_bytep data,
-png_size_t length);
-void png_write_filtered_row (png_structp png_ptr, png_bytep
-filtered_row);
+\fI\fB
 
-void png_write_find_filter (png_structp png_ptr, png_row_infop
-row_info);
+\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP
 
-void png_write_finish_row (png_structp png_ptr);
+\fI\fB
 
-void png_write_gAMA (png_structp png_ptr, double file_gamma);
+\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP
 
-void png_write_hIST (png_structp png_ptr, png_uint_16p hist,
-int num_hist);
+\fI\fB
 
-void png_write_init (png_structp png_ptr);
+\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_write_IDAT (png_structp png_ptr, png_bytep data,
-png_size_t length);
+\fI\fB
 
-void png_write_IEND (png_structp png_ptr);
+\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP
 
-void png_write_IHDR (png_structp png_ptr, png_uint_32 width,
-png_uint_32 height, int bit_depth, int color_type, int
-compression_type, int filter_type, int interlace_type);
+\fI\fB
 
-void png_write_oFFs (png_structp png_ptr, png_uint_32 x_offset,
-png_uint_32 y_offset, int unit_type);
+\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP
 
-void png_write_pCAL (png_structp png_ptr, png_charp purpose,
-png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp
-units, png_charpp params);
+\fI\fB
 
-void png_write_pHYs (png_structp png_ptr, png_uint_32
-x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int
-unit_type);
+\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP
 
-void png_write_PLTE (png_structp png_ptr, png_colorp palette,
-png_uint_32 num_pal);
+\fI\fB
 
-void png_write_sBIT (png_structp png_ptr, png_color_8p sbit,
-int color_type);
+\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
 
-void png_write_sig (png_structp png_ptr);
+\fI\fB
 
-void png_write_sRGB (png_structp png_ptr, int intent);
+\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP
 
-void png_write_start_row (png_structp png_ptr);
+\fI\fB
 
-void png_write_tEXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len);
+\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP
 
-void png_write_tIME (png_structp png_ptr, png_timep mod_time);
+\fI\fB
 
-void png_write_tRNS (png_structp png_ptr, png_bytep trans,
-png_color_16p values, int number, int color_type);
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
 
-void png_write_zTXt (png_structp png_ptr, png_charp key,
-png_charp text, png_size_t text_len, int compression);
+\fI\fB
 
-voidpf png_zalloc (voidpf png_ptr, uInt items, uInt size);
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
 
-void png_zfree (voidpf png_ptr, voidpf ptr);
+\fI\fB
 
 .SH DESCRIPTION
 The functions listed above are used privately by libpng
diff --git a/png.5 b/png.5
index 2c0fcde..1c088ec 100644
--- a/png.5
+++ b/png.5
@@ -1,4 +1,4 @@
-.TH PNG 5 "January 14, 1999"
+.TH PNG 5 "September 17, 1999"
 .SH NAME
 png \- Portable Network Graphics (PNG) format
 .SH DESCRIPTION
@@ -20,7 +20,14 @@
 .SH "SEE ALSO"
 .IR libpng(3), zlib(3), deflate(5), and zlib(5)
 .LP
-PNG specification:
+PNG 1.1 specification, January 1999:
+.IP
+.br
+http://www.cdrom.com/pub/png
+.LP
+PNG 1.0 specification, October 1996:
+.IP
+.br
 RFC 2083
 .IP
 .br
@@ -32,12 +39,19 @@
 .SH AUTHORS
 This man page: Glenn Randers-Pehrson
 .LP
+Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
+Glenn Randers-Pehrson and others (png-list@ccrc.wustl.edu).
+.LP
 Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
-Thomas Boutell and others (png-list@dworkin.wustl.edu).
+Thomas Boutell and others (png-list@ccrc.wustl.edu).
 .LP
 
+
 .SH COPYRIGHT NOTICE
-The PNG specification is copyright (c) 1996 Massachussets Institute of
+The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+The PNG-1.0 specification is copyright (c) 1996 Massachussets Institute of
 Technology.  See the specification for conditions of use and distribution.
 .LP
 .\" end of man page
diff --git a/png.c b/png.c
index e422332..d564783 100644
--- a/png.c
+++ b/png.c
@@ -1,7 +1,7 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * libpng version 1.0.3 - January 14, 1999
+ * libpng version 1.0.4 - September 17, 1999
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
  * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
@@ -16,7 +16,7 @@
  * string defined in png.h.
  */
 
-char png_libpng_ver[12] = "1.0.3";
+char png_libpng_ver[12] = "1.0.4";
 
 /* Place to hold the signature string for a PNG file. */
 png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
@@ -352,8 +352,8 @@
 {
    if(png_ptr == NULL)
      /* silence compiler warning about unused png_ptr */ ;
-   return("\n libpng version 1.0.3 - January 14, 1999\n\
+   return("\n libpng version 1.0.4 - September 17, 1999\n\
    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\
    Copyright (c) 1996, 1997 Andreas Dilger\n\
-   Copyright (c) 1998, 1999, Glenn Randers-Pehrson\n");
+   Copyright (c) 1998, 1999 Glenn Randers-Pehrson\n");
 }
diff --git a/png.h b/png.h
index b48e150..0c17b05 100644
--- a/png.h
+++ b/png.h
@@ -1,11 +1,17 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.0.3 - January 14, 1999
+ * libpng version 1.0.4 - September 17, 1999
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
  * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
  *
+ * Authors and maintainers:
+ *  libpng versions 0.71, May 1995, through 0.89c, May 1996: Guy Schalnat
+ *  libpng versions 0.90, December 1996, through 0.96, May 1997: Andreas Dilger
+ *  libpng versions 0.97, January 1998, through 1.0.4 - September 17, 1999: Glenn R-P
+ *  See also "Contributing Authors", below.
+ *
  * Y2K compliance in libpng:
  * =========================
  *    
@@ -14,9 +20,9 @@
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
  *    
- *    This is your unofficial assurance that libpng from version 0.81 and
- *    upward are Y2K compliant.  It is my belief that earlier versions were
- *    also Y2K compliant.
+ *    This is your unofficial assurance that libpng from version 0.71 and
+ *    upward through 1.0.4 are Y2K compliant.  It is my belief that earlier
+ *    versions were also Y2K compliant.
  *    
  *    Libpng only has three year fields.  One is a 2-byte unsigned integer
  *    that will hold years up to 65535.  The other two hold the date in text
@@ -44,15 +50,17 @@
  *    clock time, which returns (year - 1900), which we properly convert to
  *    the full 4-digit year.  There is a possibility that applications using
  *    libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
- *    function, or incorrectly passing only a 2-digit year instead of
- *    "year - 1900" into the png_convert_from_struct_tm() function, but this
- *    is not under our control.  The libpng documentation has always stated
- *    that it works with 4-digit years, and the APIs have been documented as
- *    such.
+ *    function, or that they are incorrectly passing only a 2-digit year
+ *    instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ *    but this is not under our control.  The libpng documentation has always
+ *    stated that it works with 4-digit years, and the APIs have been
+ *    documented as such.
  *    
  *    The tIME chunk itself is also Y2K compliant.  It uses a 2-byte unsigned
  *    integer to hold the year, and can hold years as large as 65535.
  *    
+ *    zlib, upon which libpng depends, is also Y2K compliant.  It contains
+ *    no date-related code.
  *    
  *       Glenn Randers-Pehrson
  *       libpng maintainer
@@ -66,32 +74,35 @@
  *    The following table summarizes matters since version 0.89c, which was
  *    the first widely used release:
  *
- *    source                    png.h    png.h   shared-lib
- *    version                   string     int   version
- *    -------                   ------   -----  ----------
- *    0.89c ("1.0 beta 3")      0.89        89  1.0.89
- *    0.90  ("1.0 beta 4")      0.90        90  0.90  [should have been 2.0.90]
- *    0.95  ("1.0 beta 5")      0.95        95  0.95  [should have been 2.0.95]
- *    0.96  ("1.0 beta 6")      0.96        96  0.96  [should have been 2.0.96]
- *    0.97b ("1.00.97 beta 7")  1.00.97     97  1.0.1 [should have been 2.0.97]
- *    0.97c                     0.97        97  2.0.97
- *    0.98                      0.98        98  2.0.98
- *    0.99                      0.99        98  2.0.99
- *    0.99a-m                   0.99        99  2.0.99
- *    1.00                      1.00       100  2.1.0 [int should be 10000]
- *    1.0.0                     1.0.0      100  2.1.0 [int should be 10000]
- *    1.0.1                     1.0.1    10001  2.1.0
- *    1.0.1a-e                  1.0.1a-e 10002  2.1.0.1a-e
- *    1.0.2                     1.0.2    10002  2.1.0.2
- *    1.0.2a-c                  1.0.2a   10003  2.1.0.2a-c
- *    1.0.3                     1.0.3    10003  2.1.0.3
+ *    source                   png.h    png.h   shared-lib
+ *    version                  string     int   version
+ *    -------                  ------   -----  ----------
+ *    0.89c ("1.0 beta 3")     0.89        89  1.0.89
+ *    0.90  ("1.0 beta 4")     0.90        90  0.90  [should have been 2.0.90]
+ *    0.95  ("1.0 beta 5")     0.95        95  0.95  [should have been 2.0.95]
+ *    0.96  ("1.0 beta 6")     0.96        96  0.96  [should have been 2.0.96]
+ *    0.97b ("1.00.97 beta 7") 1.00.97     97  1.0.1 [should have been 2.0.97]
+ *    0.97c                    0.97        97  2.0.97
+ *    0.98                     0.98        98  2.0.98
+ *    0.99                     0.99        98  2.0.99
+ *    0.99a-m                  0.99        99  2.0.99
+ *    1.00                     1.00       100  2.1.0 [int should be 10000]
+ *    1.0.0                    1.0.0      100  2.1.0 [int should be 10000]
+ *    1.0.1                    1.0.1    10001  2.1.0
+ *    1.0.1a-e                 1.0.1a-e 10002  2.1.0.1a-e
+ *    1.0.2                    1.0.2    10002  2.1.0.2
+ *    1.0.2a-b                 1.0.2a-b 10003  2.1.0.2a-b
+ *    1.0.3                    1.0.3    10003  2.1.0.3
+ *    1.0.3a-d                 1.0.3a-d 10004  2.1.0.3a-d
+ *    1.0.4                    1.0.4    10004  2.1.0.4
  *
  *    Henceforth the source version will match the shared-library minor
  *    and patch numbers; the shared-library major version number will be
  *    used for changes in backward compatibility, as it is intended.  The
  *    PNG_PNGLIB_VER macro, which is not used within libpng but is available
  *    for applications, is an unsigned integer of the form xyyzz corresponding
- *    to the source version x.y.z (leading zeros in y and z).
+ *    to the source version x.y.z (leading zeros in y and z).  Internal
+ *    png-group versions (x.y.z[a-z]) will be given the next higher number.
  *
  * See libpng.txt or libpng.3 for more information.  The PNG specification
  * is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
@@ -121,6 +132,13 @@
  *
  * COPYRIGHT NOTICE:
  *
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ * (libpng versions 0.5, May 1995, through 0.89c, May 1996)
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * (libpng versions 0.90, December 1996, through 0.96, May 1997)
+ * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ * (libpng versions 0.97, January 1998, through 1.0.4 - September 17, 1999)
+ *
  * The PNG Reference Library is supplied "AS IS".  The Contributing Authors
  * and Group 42, Inc. disclaim all warranties, expressed or implied,
  * including, without limitation, the warranties of merchantability and of
@@ -149,10 +167,6 @@
 #ifndef _PNG_H
 #define _PNG_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
 /* This is not the place to learn how to use libpng.  The file libpng.txt
  * describes how to use libpng, and the file example.c summarizes it
  * with some code on which to build.  This file is useful for looking
@@ -165,6 +179,11 @@
 /* include all user configurable info */
 #include "pngconf.h"
 
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 /* This file is arranged in several sections.  The first section contains
  * structure and type definitions.  The second section contains the external
  * library functions, while the third has the internal library functions,
@@ -172,14 +191,14 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.0.3"
+#define PNG_LIBPNG_VER_STRING "1.0.4"
 
 /* Careful here.  At one time, Guy wanted to use 082, but that would be octal.
  * We must not include leading zeros.
  * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
  * version 1.0.0 was mis-numbered 100 instead of 10000).  From
  * version 1.0.1 it's    xxyyzz, where x=major, y=minor, z=bugfix */
-#define PNG_LIBPNG_VER    10003  /* 1.0.3 */
+#define PNG_LIBPNG_VER    10004  /* 1.0.4 */
 
 /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
 #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
@@ -460,6 +479,9 @@
 typedef png_info FAR * png_infop;
 typedef png_info FAR * FAR * png_infopp;
 
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_MAX_UINT ((png_uint_32)0x7fffffffL)
+
 /* These describe the color_type field in png_info. */
 /* color type masks */
 #define PNG_COLOR_MASK_PALETTE    1
@@ -473,11 +495,11 @@
 #define PNG_COLOR_TYPE_RGB_ALPHA  (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
 #define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
 
-/* This is for compression type. PNG 1.0 only defines the single type. */
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
 #define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
 #define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
 
-/* This is for filter type. PNG 1.0 only defines the single type. */
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
 #define PNG_FILTER_TYPE_BASE      0 /* Single row per-byte filtering */
 #define PNG_FILTER_TYPE_DEFAULT   PNG_FILTER_TYPE_BASE
 
@@ -575,7 +597,7 @@
 #endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
 
 typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
-typedef void (*png_free_ptr) PNGARG((png_structp, png_structp));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
 
 /* The structure that holds the information to read and write PNG files.
  * The only people who need to care about what is inside of this are the
@@ -593,12 +615,19 @@
    png_voidp error_ptr;       /* user supplied struct for error functions */
    png_rw_ptr write_data_fn;  /* function for writing output data */
    png_rw_ptr read_data_fn;   /* function for reading input data */
-#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
-    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp io_ptr;          /* ptr to application struct for I/O functions*/
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    png_user_transform_ptr write_user_transform_fn; /* user write transform */
 #endif
-   png_voidp io_ptr;          /* ptr to application struct for I/O functions*/
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   png_voidp user_transform_ptr; /* user supplied struct for user transform */
+   int user_transform_depth;    /* bit depth of user transformed pixels */
+   int user_transform_channels; /* channels in user transformed pixels */
+#endif
 
    png_uint_32 mode;          /* tells us where we are in the PNG file */
    png_uint_32 flags;         /* flags indicating various things to libpng */
@@ -670,10 +699,10 @@
    float screen_gamma;   /* screen gamma value (display_gamma/viewing_gamma */
 #endif /* PNG_READ_GAMMA_SUPPORTED */
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
-   png_bytep gamma_table;     /* gamma table for 8 bit depth files */
+   png_bytep gamma_table;     /* gamma table for 8-bit depth files */
    png_bytep gamma_from_1;    /* converts from 1.0 to screen */
    png_bytep gamma_to_1;      /* converts from file to 1.0 */
-   png_uint_16pp gamma_16_table; /* gamma table for 16 bit depth files */
+   png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
    png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
    png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
 #endif /* PNG_READ_GAMMA_SUPPORTED || PNG_WRITE_GAMMA_SUPPORTED */
@@ -751,6 +780,10 @@
    png_byte rgb_to_gray_green_coeff;
    png_byte rgb_to_gray_blue_coeff;
 #endif
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+   png_byte empty_plte_permitted;
+#endif
 };
 
 typedef png_struct FAR * FAR * png_structpp;
@@ -847,8 +880,11 @@
 #endif /* PNG_WRITE_tIME_SUPPORTED */
 
 #if defined(PNG_READ_EXPAND_SUPPORTED)
-/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha if available. */
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
 extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
 #endif /* PNG_READ_EXPAND_SUPPORTED */
 
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
@@ -857,14 +893,14 @@
 #endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
-/* Expand the grayscale to 24 bit RGB if necessary. */
+/* Expand the grayscale to 24-bit RGB if necessary. */
 extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
 #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
 
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 /* Reduce RGB to grayscale. */
 extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
-   int error_action, float red, float green ));
+   int error_action, double red, double green ));
 extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
    png_ptr));
 #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
@@ -897,19 +933,19 @@
 #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
 
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
-/* Swap bytes in 16 bit depth files. */
+/* Swap bytes in 16-bit depth files. */
 extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
 #endif /* PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED */
 
 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
-/* Use 1 byte per pixel in 1, 2, or 4 bit depth files. */
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
 extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
 #endif /* PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED */
 
 #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
 /* Swap packing order of pixels in bytes. */
 extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPOR */
+#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPORTED */
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
 /* Converts files to legal bit depths. */
@@ -940,7 +976,7 @@
 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
-/* strip the second byte of information from a 16 bit depth file. */
+/* strip the second byte of information from a 16-bit depth file. */
 extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
 #endif /* PNG_READ_16_TO_8_SUPPORTED */
 
@@ -957,6 +993,13 @@
    double screen_gamma, double default_file_gamma));
 #endif /* PNG_READ_GAMMA_SUPPORTED */
 
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+    defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+   int empty_plte_permitted));
+#endif /* PNG_READ_EMPTY_PLTE_SUPPORTED */
+
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
 /* Set how many lines between output flushes - 0 for no flushing */
 extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
@@ -1217,6 +1260,16 @@
    png_ptr, png_user_transform_ptr write_user_transform_fn));
 #endif
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+   png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+   int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+   PNGARG((png_structp png_ptr));
+#endif
+
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 /* Sets the function callbacks for the push reader, and a pointer to a
  * user-defined structure available to the callback functions.
@@ -1552,7 +1605,7 @@
 {
    if(png_ptr == NULL)
      /* silence compiler warning about unused png_ptr */ ;
-   return("\n libpng version 1.0.3 - January 14, 1999 (header)\n");
+   return("\n libpng version 1.0.4 - September 17, 1999 (header)\n");
 }
 #endif
 
@@ -1823,7 +1876,7 @@
 PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
 #endif
 
-/* Place a 16 bit number into a buffer in PNG byte order.
+/* Place a 16-bit number into a buffer in PNG byte order.
  * The parameter is declared unsigned int, not png_uint_16,
  * just to avoid potential problems on pre-ANSI C compilers.
  */
diff --git a/pngasmrd.h b/pngasmrd.h
new file mode 100644
index 0000000..50bc229
--- /dev/null
+++ b/pngasmrd.h
@@ -0,0 +1,32 @@
+/* pngasmrd.h - assembler version of utilities to read a PNG file
+ *
+ * libpng 1.0.4 - September 17, 1999
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1999 Glenn Randers-Pehrson
+ *
+ */
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+
+/* Set this in the makefile for VC++ on Pentium, not in pngconf.h */
+#ifdef PNG_USE_PNGVCRD
+/* Platform must be Pentium.  Makefile must assemble and load pngvcrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+
+/* Set this in the makefile for gcc on Pentium, not in pngconf.h */
+#ifdef PNG_USE_PNGGCCRD
+/* Platform must be Pentium.  Makefile must assemble and load pnggccrd.c
+ * (not available in libpng-1.0.3a).
+ * MMX will be detected at run time and used if present.
+ */
+#define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+#define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+#define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+
+#endif
diff --git a/pngconf.h b/pngconf.h
index 028f2a1..05e84e0 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,7 +1,7 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -54,25 +54,24 @@
  * prevent these from being compiled and used. #defining PNG_NO_STDIO
  * will also prevent these, plus will prevent the entire set of stdio
  * macros and functions (FILE *, printf, etc.) from being compiled and used,
- * unless PNG_DEBUG has been #defined.
+ * unless (PNG_DEBUG > 0) has been #defined.
  *
  * #define PNG_NO_CONSOLE_IO
  * #define PNG_NO_STDIO
  */
 
-#ifdef PNG_DEBUG
-#  if (PNG_DEBUG > 0)
-#    include <stdio.h>
-#  endif
-#else
 #  ifdef PNG_NO_STDIO
 #    ifndef PNG_NO_CONSOLE_IO
 #      define PNG_NO_CONSOLE_IO
 #    endif
+#    ifdef PNG_DEBUG
+#      if (PNG_DEBUG > 0)
+#        include <stdio.h>
+#      endif
+#    endif
 #  else
 #    include <stdio.h>
 #  endif
-#endif
 
 /* This macro protects us against machines that don't have function
  * prototypes (ie K&R style headers).  If your compiler does not handle
@@ -173,7 +172,7 @@
 #endif
 
 /* Codewarrior on NT has linking problems without this. */
-#if defined(__MWERKS__) && defined(WIN32)
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
 #define PNG_ALWAYS_EXTERN
 #endif
 
@@ -339,6 +338,10 @@
 #define PNG_READ_COMPOSITE_NODIV_SUPPORTED    /* well tested on Intel and SGI */
 #endif
 
+#ifndef PNG_NO_READ_EMPTY_PLTE
+#define PNG_READ_EMPTY_PLTE_SUPPORTED  /* useful for MNG applications */
+#endif
+
 #ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
 #ifndef PNG_NO_WRITE_SHIFT
 #define PNG_WRITE_SHIFT_SUPPORTED
@@ -384,6 +387,10 @@
 #define PNG_WRITE_FLUSH_SUPPORTED
 #endif
 
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+#define PNG_WRITE_EMPTY_PLTE_SUPPORTED  /* useful for MNG applications */
+#endif
+
 #ifndef PNG_NO_STDIO
 #define PNG_TIME_RFC1123_SUPPORTED
 #endif
@@ -408,6 +415,10 @@
 #define PNG_EASY_ACCESS_SUPPORTED
 #endif
 
+#ifndef PNG_NO_ASSEMBLER_CODE
+#define PNG_ASSEMBLER_CODE_SUPPORTED
+#endif
+
 /* These are currently experimental features, define them if you want */
 
 /* very little testing */
diff --git a/pngerror.c b/pngerror.c
index c591000..73b2f96 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -1,7 +1,7 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
diff --git a/pngget.c b/pngget.c
index 484a011..582ca71 100644
--- a/pngget.c
+++ b/pngget.c
@@ -1,7 +1,7 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -454,7 +454,7 @@
          channels++;
       pixel_depth = *bit_depth * channels;
       rowbytes_per_pixel = (pixel_depth + 7) >> 3;
-      if ((*width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+      if ((*width > PNG_MAX_UINT/rowbytes_per_pixel))
       {
          png_warning(png_ptr,
             "Width too large for libpng to process image data.");
diff --git a/pngmem.c b/pngmem.c
index 06c4c1b..8cc220d 100644
--- a/pngmem.c
+++ b/pngmem.c
@@ -1,7 +1,7 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -157,8 +157,9 @@
                ret = NULL;
             }
 
-            num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
-            if (num_blocks < 1)
+            if(png_ptr->zlib_window_bits > 14)
+               num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+            else
                num_blocks = 1;
             if (png_ptr->zlib_mem_level >= 7)
                num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
@@ -192,12 +193,12 @@
             if ((png_size_t)hptr & 0xf)
             {
                hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
-               hptr += 16L;
+               hptr = hptr + 16L;  /* "hptr += 16L" fails on Turbo C++ 3.0 */
             }
             for (i = 0; i < num_blocks; i++)
             {
                png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
-               hptr += (png_uint_32)65536L;
+               hptr = hptr + (png_uint_32)65536L;  /* "+=" fails on TC++3.0 */
             }
 
             png_ptr->offset_table_number = num_blocks;
diff --git a/pngpread.c b/pngpread.c
index b446518..efc55e9 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1,7 +1,7 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
diff --git a/pngread.c b/pngread.c
index 01613b1..36df20a 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,7 +1,7 @@
 
 /* pngread.c - read a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -188,7 +188,8 @@
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
 
-      png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+      png_debug2(0, "Reading %s chunk, length=%d.\n", png_ptr->chunk_name,
+         length);
 
       /* This should be a binary subdivision search or a hash for
        * matching the chunk name rather than a linear search.
@@ -530,7 +531,7 @@
  * not called png_set_interlace_handling(), the display_row buffer will
  * be ignored, so pass NULL to it.
  *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.4.
  */
 
 void
@@ -579,7 +580,7 @@
  * only call this function once.  If you desire to have an image for
  * each pass of a interlaced image, use png_read_rows() instead.
  *
- * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.3.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.4.
  */
 void
 png_read_image(png_structp png_ptr, png_bytepp image)
@@ -590,7 +591,16 @@
 
    png_debug(1, "in png_read_image\n");
    /* save jump buffer and error functions */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
    pass = png_set_interlace_handling(png_ptr);
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+        "Cannot read interlaced image -- interlace handler disabled.");
+   pass = 1;
+#endif
+
 
    image_height=png_ptr->height;
    png_ptr->num_rows = image_height; /* Make sure this is set correctly */
@@ -805,8 +815,11 @@
 #endif
    if (png_ptr->flags & PNG_FLAG_FREE_PALETTE)
       png_zfree(png_ptr, png_ptr->palette);
+#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \
+    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    if (png_ptr->flags & PNG_FLAG_FREE_TRANS)
       png_free(png_ptr, png_ptr->trans);
+#endif
 #if defined(PNG_READ_hIST_SUPPORTED)
    if (png_ptr->flags & PNG_FLAG_FREE_HIST)
       png_free(png_ptr, png_ptr->hist);
diff --git a/pngrio.c b/pngrio.c
index 23bbb2b..bf624e8 100644
--- a/pngrio.c
+++ b/pngrio.c
@@ -1,7 +1,7 @@
 
 /* pngrio.c - functions for data input
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
diff --git a/pngrtran.c b/pngrtran.c
index ce486bd..8a4d6d2 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -1,7 +1,7 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -523,7 +523,7 @@
 
 #if defined(PNG_READ_EXPAND_SUPPORTED)
 /* Expand paletted images to rgb, expand grayscale images of
- * less than 8 bit depth to 8 bit depth, and expand tRNS chunks
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
  * to alpha channels.
  */
 void
@@ -532,7 +532,45 @@
    png_debug(1, "in png_set_expand\n");
    png_ptr->transformations |= PNG_EXPAND;
 }
-#endif
+
+/* GRR 19990627:  the following three functions currently are identical
+ *  to png_set_expand().  However, it is entirely reasonable that someone
+ *  might wish to expand an indexed image to RGB but *not* expand a single,
+ *  fully transparent palette entry to a full alpha channel--perhaps instead
+ *  convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ *  the transparent color with a particular RGB value, or drop tRNS entirely.
+ *  IOW, a future version of the library may make the transformations flag
+ *  a bit more fine-grained, with separate bits for each of these three
+ *  functions.
+ *
+ *  More to the point, these functions make it obvious what libpng will be
+ *  doing, whereas "expand" can (and does) mean any number of things.
+ */
+
+/* Expand paletted images to RGB. */
+void
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+   png_debug(1, "in png_set_expand\n");
+   png_ptr->transformations |= PNG_EXPAND;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
 void
@@ -548,8 +586,8 @@
  * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
  */
 void
-png_set_rgb_to_gray(png_structp png_ptr, int error_action, float red,
-  float green)
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+  double green)
 {
    png_debug(1, "in png_set_rgb_to_gray\n");
    switch(error_action)
@@ -570,8 +608,8 @@
    }
 #endif
    {
-      png_byte red_byte = (png_byte)(red*255.0 + 0.5);
-      png_byte green_byte = (png_byte)(green*255.0 + 0.5);
+      png_byte red_byte = (png_byte)((float)red*255.0 + 0.5);
+      png_byte green_byte = (png_byte)((float)green*255.0 + 0.5);
       if(red < 0.0 || green < 0.0)
       {
          red_byte = 54;
@@ -1018,6 +1056,16 @@
       ++info_ptr->channels;
 #endif
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   if(png_ptr->transformations & PNG_USER_TRANSFORM)
+     {
+       if(info_ptr->bit_depth < png_ptr->user_transform_depth)
+         info_ptr->bit_depth = png_ptr->user_transform_depth;
+       if(info_ptr->channels < png_ptr->user_transform_channels)
+         info_ptr->channels = png_ptr->user_transform_channels;
+     }
+#endif
+
    info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
       info_ptr->bit_depth);
    info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
@@ -1223,6 +1271,7 @@
 
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
    if (png_ptr->transformations & PNG_USER_TRANSFORM)
+    {
       if(png_ptr->read_user_transform_fn != NULL)
         (*(png_ptr->read_user_transform_fn)) /* user read transform function */
           (png_ptr,                    /* png_ptr */
@@ -1234,6 +1283,15 @@
              /*  png_byte channels;          number of channels (1-4) */
              /*  png_byte pixel_depth;       bits per pixel (depth*channels) */
            png_ptr->row_buf + 1);      /* start of pixel data for row */
+      if(png_ptr->user_transform_depth)
+         png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+      if(png_ptr->user_transform_channels)
+         png_ptr->row_info.channels = png_ptr->user_transform_channels;
+      png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+         png_ptr->row_info.channels);
+      png_ptr->row_info.rowbytes = (png_ptr->row_info.width * 
+         png_ptr->row_info.pixel_depth+7)>>3;
+   }
 #endif
 
 }
@@ -1737,7 +1795,7 @@
             *(--dp) = lo_filler;
             row_info->channels = 2;
             row_info->pixel_depth = 32;
-            row_info->rowbytes = row_width * 2;
+            row_info->rowbytes = row_width * 4;
          }
          /* This changes the data from GG to XXGG */
          else
@@ -1752,8 +1810,8 @@
                *(--dp) = lo_filler;
             }
             row_info->channels = 2;
-            row_info->pixel_depth = 16;
-            row_info->rowbytes = row_width * 2;
+            row_info->pixel_depth = 32;
+            row_info->rowbytes = row_width * 4;
          }
       }
    } /* COLOR_TYPE == GRAY */
@@ -1817,7 +1875,7 @@
             *(--dp) = lo_filler;
             row_info->channels = 4;
             row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 4;
+            row_info->rowbytes = row_width * 8;
          }
          /* This changes the data from RRGGBB to XXRRGGBB */
          else
@@ -1837,7 +1895,7 @@
             }
             row_info->channels = 4;
             row_info->pixel_depth = 64;
-            row_info->rowbytes = row_width * 4;
+            row_info->rowbytes = row_width * 8;
          }
       }
    } /* COLOR_TYPE == RGB */
@@ -1869,8 +1927,7 @@
             {
                *(dp--) = *sp;
                *(dp--) = *sp;
-               *(dp--) = *sp;
-               sp--;
+               *(dp--) = *(sp--);
             }
          }
          else
@@ -1883,10 +1940,8 @@
                *(dp--) = *(sp - 1);
                *(dp--) = *sp;
                *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               sp--;
-               sp--;
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
             }
          }
       }
@@ -1901,8 +1956,7 @@
                *(dp--) = *(sp--);
                *(dp--) = *sp;
                *(dp--) = *sp;
-               *(dp--) = *sp;
-               sp--;
+               *(dp--) = *(sp--);
             }
          }
          else
@@ -1917,10 +1971,8 @@
                *(dp--) = *(sp - 1);
                *(dp--) = *sp;
                *(dp--) = *(sp - 1);
-               *(dp--) = *sp;
-               *(dp--) = *(sp - 1);
-               sp--;
-               sp--;
+               *(dp--) = *(sp--);
+               *(dp--) = *(sp--);
             }
          }
       }
diff --git a/pngrutil.c b/pngrutil.c
index 9320a71..3919fce 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1,7 +1,7 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.3b - August 26, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -14,6 +14,10 @@
 #define PNG_INTERNAL
 #include "png.h"
 
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#include "pngasmrd.h"
+#endif
+
 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
 png_uint_32
@@ -165,8 +169,8 @@
    interlace_type = buf[12];
 
    /* check for width and height valid values */
-   if (width == 0 || width > (png_uint_32)2147483647L || height == 0 ||
-        height > (png_uint_32)2147483647L)
+   if (width == 0 || width > PNG_MAX_UINT || height == 0 ||
+        height > PNG_MAX_UINT)
       png_error(png_ptr, "Invalid image size in IHDR");
 
    /* check other values */
@@ -178,7 +182,7 @@
       color_type == 5 || color_type > 6)
       png_error(png_ptr, "Invalid color type in IHDR");
 
-   if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
+   if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
        ((color_type == PNG_COLOR_TYPE_RGB ||
          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
@@ -420,7 +424,7 @@
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sRGB)
-      if(igamma != (png_uint_32)45000L)
+      if(fabs((float)igamma - 45455.)>500.)
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
@@ -692,7 +696,7 @@
 
 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
    if ((info_ptr->valid & PNG_INFO_gAMA))
-      if((png_uint_32)(png_ptr->gamma*(float)100000.+.5) != (png_uint_32)45000L)
+      if(fabs((png_ptr->gamma*(float)100000.+.5)-45455.) > 500.)
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
@@ -871,9 +875,21 @@
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
       png_ptr->background.index = buf[0];
-      png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
-      png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
-      png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+      if(info_ptr->num_palette)
+      {
+          if(buf[0] > info_ptr->num_palette)
+          {
+             png_warning(png_ptr, "Incorrect bKGD chunk index value");
+             png_crc_finish(png_ptr, length);
+             return;
+          }
+          png_ptr->background.red =
+             (png_uint_16)png_ptr->palette[buf[0]].red;
+          png_ptr->background.green =
+             (png_uint_16)png_ptr->palette[buf[0]].green;
+          png_ptr->background.blue =
+             (png_uint_16)png_ptr->palette[buf[0]].blue;
+      }
    }
    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
    {
@@ -1480,8 +1496,12 @@
    to any alpha or transparency value associated with the pixel.  If
    you want all pixels to be combined, pass 0xff (255) in mask.  */
 void
-png_combine_row(png_structp png_ptr, png_bytep row,
-   int mask)
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+png_combine_row_c
+#else
+png_combine_row
+#endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */
+   (png_structp png_ptr, png_bytep row, int mask)
 {
    png_debug(1,"in png_combine_row\n");
    if (mask == 0xff)
@@ -1684,7 +1704,12 @@
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED)
 void
-png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
+png_do_read_interlace_c
+#else
+png_do_read_interlace
+#endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */
+   (png_row_infop row_info, png_bytep row, int pass,
    png_uint_32 transformations)
 {
    png_debug(1,"in png_do_read_interlace\n");
@@ -1894,13 +1919,16 @@
 #endif
 
 void
-png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+png_read_filter_row_c
+#else
+png_read_filter_row
+#endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
+   (png_structp png_ptr, png_row_infop row_info, png_bytep row,
    png_bytep prev_row, int filter)
 {
    png_debug(1, "in png_read_filter_row\n");
    png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
-
-
    switch (filter)
    {
       case PNG_FILTER_VALUE_NONE:
diff --git a/pngset.c b/pngset.c
index 3200836..07fc581 100644
--- a/pngset.c
+++ b/pngset.c
@@ -1,7 +1,7 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -107,7 +107,7 @@
 
    /* check for overflow */
    rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
-   if (( width > (png_uint_32)2147483647L/rowbytes_per_pixel))
+   if (( width > PNG_MAX_UINT/rowbytes_per_pixel))
    {
       png_warning(png_ptr,
          "Width too large to process image data; rowbytes will overflow.");
@@ -344,7 +344,8 @@
 png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
 {
    png_debug1(1, "in %s storage function\n", "tIME");
-   if (png_ptr == NULL || info_ptr == NULL)
+   if (png_ptr == NULL || info_ptr == NULL ||
+       (png_ptr->flags & PNG_FLAG_WROTE_tIME))
       return;
 
    png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
@@ -378,3 +379,13 @@
 }
 #endif
 
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
+void
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+   png_debug1(1, "in png_permit_empty_plte\n", "");
+   if (png_ptr == NULL)
+      return;
+   png_ptr->empty_plte_permitted=(png_byte)empty_plte_permitted;
+}
+#endif
diff --git a/pngtest.c b/pngtest.c
index a1ba8ec..30decde 100644
--- a/pngtest.c
+++ b/pngtest.c
@@ -1,7 +1,7 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * libpng 1.0.3 -January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -42,6 +42,8 @@
 static char tIME_string[30] = "no tIME chunk present in file";
 #endif /* PNG_TIME_RFC1123_SUPPORTED */
 
+static int verbose = 0;
+
 int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
 
 #ifdef __TURBOC__
@@ -60,12 +62,12 @@
 void
 read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
 {
-    if(png_ptr == NULL || row_number > 0x3fffffffL) return;
+    if(png_ptr == NULL || row_number > PNG_MAX_UINT) return;
     if(status_pass != pass)
     {
        fprintf(stdout,"\n Pass %d: ",pass);
        status_pass = pass;
-       status_dots = 30;
+       status_dots = 31;
     }
     status_dots--;
     if(status_dots == 0)
@@ -79,11 +81,24 @@
 void
 write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
 {
-    if(png_ptr == NULL || row_number > 0x3fffffffL || pass > 7) return;
+    if(png_ptr == NULL || row_number > PNG_MAX_UINT || pass > 7) return;
     fprintf(stdout, "w");
 }
 
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+/* Example of using user transform callback (we don't transform anything,
+   but merely examine the row filters.  We set this to 256 rather than
+   5 in case illegal filter values are present.) */
+static png_uint_32 filters_used[256];
+void
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+    if(png_ptr != NULL && row_info != NULL)
+      ++filters_used[*(data-1)];
+}
+#endif
+
 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 /* example of using user transform callback (we don't transform anything,
    but merely count the zero samples) */
@@ -105,6 +120,7 @@
     *  png_byte pixel_depth   bits per pixel (depth*channels)
     */
 
+
     /* counts the number of zero samples (or zero pixels if color_type is 3 */
 
     if(row_info->color_type == 0 || row_info->color_type == 3)
@@ -178,7 +194,6 @@
 }
 #endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
 
-static int verbose = 0;
 static int wrote_question = 0;
 
 #if defined(PNG_NO_STDIO)
@@ -584,10 +599,18 @@
       png_set_read_status_fn(read_ptr, NULL);
    }
 
-#  if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
-     zero_samples=0;
-     png_set_write_user_transform_fn(write_ptr, count_zero_samples);
-#  endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+   {
+     int i;
+     for(i=0; i<256; i++)
+        filters_used[i]=0;
+     png_set_read_user_transform_fn(read_ptr, count_filters);
+   }
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+   zero_samples=0;
+   png_set_write_user_transform_fn(write_ptr, count_zero_samples);
+#endif
 
    png_debug(0, "Reading info struct\n");
    png_read_info(read_ptr, read_info_ptr);
@@ -859,7 +882,7 @@
 
       if (png_memcmp(inbuf, outbuf, num_in))
       {
-         fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
+         fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
          if(wrote_question == 0)
          {
             fprintf(STDERR,
@@ -885,8 +908,8 @@
 
 /* input and output filenames */
 #ifdef RISCOS
-PNG_CONST char *inname = "pngtest/png";
-PNG_CONST char *outname = "pngout/png";
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
 #else
 static PNG_CONST char *inname = "pngtest.png";
 static PNG_CONST char *outname = "pngout.png";
@@ -973,7 +996,7 @@
 #endif
       for (i=2; i<argc; ++i)
       {
-         int kerror;
+         int k, kerror;
          fprintf(STDERR, "Testing %s:",argv[i]);
          kerror = test_one_file(argv[i], outname);
          if (kerror == 0)
@@ -983,6 +1006,12 @@
 #else
             fprintf(STDERR, " PASS\n");
 #endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+            for (k=0; k<256; k++)
+               if(filters_used[k])
+                  fprintf(STDERR, " Filter %d was used %lu times\n",
+                     k,filters_used[k]);
+#endif
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
          if(tIME_chunk_present != 0)
             fprintf(STDERR, " tIME = %s\n",tIME_string);
@@ -1032,14 +1061,21 @@
          {
             if(verbose == 1 || i == 2)
             {
+                int k;
 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
                 fprintf(STDERR, " PASS (%lu zero samples)\n",zero_samples);
 #else
                 fprintf(STDERR, " PASS\n");
 #endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+                for (k=0; k<256; k++)
+                   if(filters_used[k])
+                      fprintf(STDERR, " Filter %d was used %lu times\n",
+                         k,filters_used[k]);
+#endif
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
-         if(tIME_chunk_present != 0)
-            fprintf(STDERR, " tIME = %s\n",tIME_string);
+             if(tIME_chunk_present != 0)
+                fprintf(STDERR, " tIME = %s\n",tIME_string);
 #endif /* PNG_TIME_RFC1123_SUPPORTED */
             }
          }
diff --git a/pngtrans.c b/pngtrans.c
index 397c988..998d363 100644
--- a/pngtrans.c
+++ b/pngtrans.c
@@ -1,7 +1,7 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -570,3 +570,26 @@
 }
 #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
 
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+    defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+   user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+   png_debug(1, "in png_set_user_transform_info\n");
+   png_ptr->user_transform_ptr = user_transform_ptr;
+   png_ptr->user_transform_depth = user_transform_depth;
+   png_ptr->user_transform_channels = user_transform_channels;
+}
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions.  The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+   return ((png_voidp)png_ptr->user_transform_ptr);
+}
+#endif
diff --git a/pngvcrd.c b/pngvcrd.c
new file mode 100644
index 0000000..57d3b1a
--- /dev/null
+++ b/pngvcrd.c
@@ -0,0 +1,3888 @@
+/* pngvcrd.c - assembler version of utilities to read a PNG file
+ *
+ * For Intel CPU and Microsoft Visual C++ compiler
+ *
+ * libpng 1.0.4 - September 17, 1999
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998, Intel Corporation
+ * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ *
+ * Contributed by Nirav Chhatrapati, INTEL Corporation, 1998
+ * Interface to libpng contributed by Gilles Vollant, 1999
+ *
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+
+static int mmx_supported=2;
+
+void
+png_read_filter_row_c(png_structp png_ptr, png_row_infop row_info,
+   png_bytep row, png_bytep prev_row, int filter);
+
+static int mmxsupport()
+{
+  int mmx_supported_local = 0;
+
+  _asm {
+    pushfd            //Save Eflag to stack
+    pop eax           //Get Eflag from stack into eax
+    mov ecx, eax      //Make another copy of Eflag in ecx
+    xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)]
+    push eax          //Save modified Eflag back to stack
+
+    popfd             //Restored modified value back to Eflag reg
+    pushfd            //Save Eflag to stack
+    pop eax           //Get Eflag from stack
+    xor eax, ecx      //Compare the new Eflag with the original Eflag
+    jz NOT_SUPPORTED  //If the same, CPUID instruction is not supported,
+                      //skip following instructions and jump to
+                      //NOT_SUPPORTED label
+
+    xor eax, eax      //Set eax to zero
+
+    _asm _emit 0x0f   //CPUID instruction  (two bytes opcode)
+    _asm _emit 0xa2
+
+    cmp eax, 1        //make sure eax return non-zero value
+    jl NOT_SUPPORTED  //If eax is zero, mmx not supported
+
+    xor eax, eax      //set eax to zero
+    inc eax           //Now increment eax to 1.  This instruction is
+                      //faster than the instruction "mov eax, 1"
+
+    _asm _emit 0x0f   //CPUID instruction
+    _asm _emit 0xa2
+
+    and edx, 0x00800000  //mask out all bits but mmx bit(24)
+    cmp edx, 0        // 0 = mmx not supported
+    jz  NOT_SUPPORTED // non-zero = Yes, mmx IS supported
+
+    mov  mmx_supported_local, 1  //set return value to 1
+
+NOT_SUPPORTED:
+    mov  eax, mmx_supported_local  //move return value to eax
+
+  }
+
+//mmx_supported_local=0; // test code for force don't support MMX
+    //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local);
+
+  return mmx_supported_local;
+}
+
+/* Combines the row recently read in with the previous row.
+   This routine takes care of alpha and transparency if requested.
+   This routine also handles the two methods of progressive display
+   of interlaced images, depending on the mask value.
+   The mask value describes which pixels are to be combined with
+   the row.  The pattern always repeats every 8 pixels, so just 8
+   bits are needed.  A one indicates the pixels is to be combined,
+   a zero indicates the pixel is to be skipped.  This is in addition
+   to any alpha or transparency value associated with the pixel.  If
+   you want all pixels to be combined, pass 0xff (255) in mask.  */
+
+/* Use this routine for X86 platform - uses faster MMX routine if machine
+supports MMX */
+
+void
+png_combine_row(png_structp png_ptr, png_bytep row,
+   int mask)
+{
+   //int mmx_supported=0; // another test code for remove MMX in this routine
+   png_debug(1,"in png_combine_row_asm\n");
+   //if (mmx_supported==2)
+   //    mmx_supported=mmxsupport();
+
+   if (mask == 0xff)
+   {
+      png_memcpy(row, png_ptr->row_buf + 1,
+   (png_size_t)((png_ptr->width *
+   png_ptr->row_info.pixel_depth + 7) >> 3));
+   }
+   else
+   {
+    switch (png_ptr->row_info.pixel_depth)
+      {
+   case 1:
+   {
+      png_bytep sp;
+      png_bytep dp;
+      int s_inc, s_start, s_end;
+      int m;
+      int shift;
+      png_uint_32 i;
+
+      sp = png_ptr->row_buf + 1;
+      dp = row;
+      m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (png_ptr->transformations & PNG_PACKSWAP)
+      {
+    s_start = 0;
+    s_end = 7;
+    s_inc = 1;
+      }
+      else
+#endif
+      {
+    s_start = 7;
+    s_end = 0;
+    s_inc = -1;
+      }
+
+      shift = s_start;
+
+      for (i = 0; i < png_ptr->width; i++)
+      {
+         if (m & mask)
+         {
+      int value;
+
+      value = (*sp >> shift) & 0x1;
+      *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+      *dp |= (png_byte)(value << shift);
+         }
+
+         if (shift == s_end)
+         {
+      shift = s_start;
+      sp++;
+      dp++;
+         }
+         else
+      shift += s_inc;
+
+         if (m == 1)
+      m = 0x80;
+         else
+      m >>= 1;
+      }
+      break;
+   }
+   case 2:
+   {
+      png_bytep sp;
+      png_bytep dp;
+      int s_start, s_end, s_inc;
+      int m;
+      int shift;
+      png_uint_32 i;
+      int value;
+
+      sp = png_ptr->row_buf + 1;
+      dp = row;
+      m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (png_ptr->transformations & PNG_PACKSWAP)
+      {
+         s_start = 0;
+         s_end = 6;
+         s_inc = 2;
+      }
+      else
+#endif
+      {
+         s_start = 6;
+         s_end = 0;
+         s_inc = -2;
+      }
+
+      shift = s_start;
+
+      for (i = 0; i < png_ptr->width; i++)
+      {
+         if (m & mask)
+         {
+      value = (*sp >> shift) & 0x3;
+      *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+      *dp |= (png_byte)(value << shift);
+         }
+
+         if (shift == s_end)
+         {
+      shift = s_start;
+      sp++;
+      dp++;
+         }
+         else
+      shift += s_inc;
+         if (m == 1)
+      m = 0x80;
+         else
+      m >>= 1;
+      }
+      break;
+   }
+   case 4:
+   {
+      png_bytep sp;
+      png_bytep dp;
+      int s_start, s_end, s_inc;
+      int m;
+      int shift;
+      png_uint_32 i;
+      int value;
+
+      sp = png_ptr->row_buf + 1;
+      dp = row;
+      m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (png_ptr->transformations & PNG_PACKSWAP)
+      {
+         s_start = 0;
+         s_end = 4;
+         s_inc = 4;
+      }
+      else
+#endif
+      {
+         s_start = 4;
+         s_end = 0;
+         s_inc = -4;
+      }
+      shift = s_start;
+
+      for (i = 0; i < png_ptr->width; i++)
+      {
+         if (m & mask)
+         {
+      value = (*sp >> shift) & 0xf;
+      *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+      *dp |= (png_byte)(value << shift);
+         }
+
+         if (shift == s_end)
+         {
+      shift = s_start;
+      sp++;
+      dp++;
+         }
+         else
+      shift += s_inc;
+         if (m == 1)
+      m = 0x80;
+         else
+      m >>= 1;
+      }
+      break;
+   }
+     case 8:
+        {
+        png_bytep srcptr;
+        png_bytep dstptr;
+        png_uint_32 len;
+        int m;
+        int diff, unmask;
+
+        __int64 mask0=0x0102040810204080;
+
+        if (mmx_supported)
+        {
+        srcptr = png_ptr->row_buf + 1;
+        dstptr = row;
+        m = 0x80;
+        unmask = ~mask;
+        len  = png_ptr->width &~7;  //reduce to multiple of 8
+        diff = png_ptr->width & 7;  //amount lost
+        _asm {
+          movd    mm7, unmask        //load bit pattern
+          psubb   mm6,mm6            //zero mm6
+          punpcklbw mm7,mm7
+          punpcklwd mm7,mm7
+          punpckldq mm7,mm7          //fill register with 8 masks
+
+          movq    mm0,mask0
+
+          pand    mm0,mm7            //nonzero if keep byte
+          pcmpeqb mm0,mm6            //zeros->1s, v versa
+
+          mov             ecx,len    //load length of line
+          mov             esi,srcptr //load source
+          mov             ebx,dstptr //load dest
+               cmp   ecx,0 //lcr
+               je    mainloop8end
+
+mainloop8:
+          movq    mm4,[esi]
+          pand    mm4,mm0
+          movq    mm6,mm0
+          pandn   mm6,[ebx]
+          por             mm4,mm6
+          movq    [ebx],mm4
+
+          add             esi,8       //inc by 8 bytes processed
+          add             ebx,8
+          sub             ecx,8       //dec by 8 pixels processed
+
+          ja              mainloop8
+mainloop8end:
+
+          mov             ecx,diff
+          cmp             ecx,0
+          jz              end8
+
+          mov             edx,mask
+          sal             edx,24      //make low byte the high byte
+
+secondloop8:
+          sal             edx,1       //move high bit to CF
+          jnc             skip8       //if CF = 0
+          mov             al,[esi]
+          mov             [ebx],al
+skip8:
+          inc             esi
+          inc             ebx
+
+          dec             ecx
+          jnz secondloop8
+end8:
+          emms
+          }
+        }
+        else /* mmx _not supported - Use modified C routine*/
+        {
+          register unsigned int incr1, initial_val, final_val;
+          png_size_t pixel_bytes;
+          png_uint_32 i;
+          //if ((mask != 0x0f) && (mask != 0x33))
+          register int disp = png_pass_inc[png_ptr->pass];
+          int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+          pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+          srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+             pixel_bytes;
+          dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+          initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+          final_val = png_ptr->width*pixel_bytes;
+          incr1 = (disp)*pixel_bytes;
+          for (i = initial_val; i < final_val; i += incr1)
+          {
+          png_memcpy(dstptr, srcptr, pixel_bytes);
+          srcptr += incr1;
+          dstptr += incr1;
+          }
+        } /* end of else */
+
+        break;
+        }       //end 8bpp
+
+        case 16:
+        {
+        png_bytep srcptr;
+          png_bytep dstptr;
+          png_uint_32 len;
+        int unmask, diff;
+
+        __int64 mask1=0x0101020204040808,
+            mask0=0x1010202040408080;
+
+        if (mmx_supported)
+        {
+          srcptr = png_ptr->row_buf + 1;
+          dstptr = row;
+
+        unmask = ~mask;
+        len     = (png_ptr->width)&~7;
+        diff = (png_ptr->width)&7;
+        _asm {
+          movd    mm7, unmask       //load bit pattern
+          psubb   mm6,mm6           //zero mm6
+          punpcklbw mm7,mm7
+          punpcklwd mm7,mm7
+          punpckldq mm7,mm7         //fill register with 8 masks
+
+          movq    mm0,mask0
+          movq    mm1,mask1
+
+          pand    mm0,mm7
+          pand    mm1,mm7
+
+          pcmpeqb mm0,mm6
+          pcmpeqb mm1,mm6
+
+          mov             ecx,len    //load length of line
+          mov             esi,srcptr //load source
+          mov             ebx,dstptr //load dest
+               cmp   ecx,0 //lcr
+               jz    mainloop16end
+
+mainloop16:
+          movq    mm4,[esi]
+          pand    mm4,mm0
+          movq    mm6,mm0
+          movq    mm7,[ebx]
+          pandn   mm6,mm7
+          por             mm4,mm6
+          movq    [ebx],mm4
+
+          movq    mm5,[esi+8]
+          pand    mm5,mm1
+          movq    mm7,mm1
+          movq    mm6,[ebx+8]
+          pandn   mm7,mm6
+          por             mm5,mm7
+          movq    [ebx+8],mm5
+
+          add             esi,16      //inc by 16 bytes processed
+          add             ebx,16
+          sub             ecx,8       //dec by 8 pixels processed
+
+          ja              mainloop16
+mainloop16end:
+
+          mov             ecx,diff
+          cmp             ecx,0
+          jz              end16
+
+          mov             edx,mask
+          sal             edx,24      //make low byte the high byte
+
+secondloop16:
+          sal             edx,1       //move high bit to CF
+          jnc             skip16      //if CF = 0
+          mov             ax,[esi]
+          mov             [ebx],ax
+skip16:
+          add             esi,2
+          add             ebx,2
+
+          dec             ecx
+          jnz secondloop16
+
+end16:
+          emms
+          }
+        }
+        else /* mmx _not supported - Use modified C routine */
+        {
+          register unsigned int incr1, initial_val, final_val;
+          png_size_t pixel_bytes;
+          png_uint_32 i;
+          register int disp = png_pass_inc[png_ptr->pass];
+          int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+          pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+          srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+             pixel_bytes;
+          dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+          initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+          final_val = png_ptr->width*pixel_bytes;
+          incr1 = (disp)*pixel_bytes;
+          for (i = initial_val; i < final_val; i += incr1)
+          {
+          png_memcpy(dstptr, srcptr, pixel_bytes);
+          srcptr += incr1;
+          dstptr += incr1;
+          }
+        } /* end of else */
+
+        break;
+        }
+      case 24:
+        {
+        png_bytep srcptr;
+          png_bytep dstptr;
+          png_uint_32 len;
+        int unmask, diff;
+
+        __int64 mask2=0x0101010202020404, //24bpp
+            mask1=0x0408080810101020,
+            mask0=0x2020404040808080;
+
+          srcptr = png_ptr->row_buf + 1;
+          dstptr = row;
+
+        unmask = ~mask;
+        len     = (png_ptr->width)&~7;
+        diff = (png_ptr->width)&7;
+
+        if (mmx_supported)
+        {
+        _asm {
+          movd    mm7, unmask         //load bit pattern
+          psubb   mm6,mm6             //zero mm6
+          punpcklbw mm7,mm7
+          punpcklwd mm7,mm7
+          punpckldq mm7,mm7           //fill register with 8 masks
+
+          movq    mm0,mask0
+          movq    mm1,mask1
+          movq    mm2,mask2
+
+
+          pand    mm0,mm7
+          pand    mm1,mm7
+          pand    mm2,mm7
+
+          pcmpeqb mm0,mm6
+          pcmpeqb mm1,mm6
+          pcmpeqb mm2,mm6
+
+          mov             ecx,len     //load length of line
+          mov             esi,srcptr  //load source
+          mov             ebx,dstptr  //load dest
+               cmp   ecx,0
+               jz    mainloop24end
+
+mainloop24:
+          movq    mm4,[esi]
+          pand    mm4,mm0
+          movq    mm6,mm0
+          movq    mm7,[ebx]
+          pandn   mm6,mm7
+          por             mm4,mm6
+          movq    [ebx],mm4
+
+
+          movq    mm5,[esi+8]
+          pand    mm5,mm1
+          movq    mm7,mm1
+          movq    mm6,[ebx+8]
+          pandn   mm7,mm6
+          por             mm5,mm7
+          movq    [ebx+8],mm5
+
+          movq    mm6,[esi+16]
+          pand    mm6,mm2
+          movq    mm4,mm2
+          movq    mm7,[ebx+16]
+          pandn   mm4,mm7
+          por             mm6,mm4
+          movq    [ebx+16],mm6
+
+          add             esi,24      //inc by 24 bytes processed
+          add             ebx,24
+          sub             ecx,8       //dec by 8 pixels processed
+
+          ja              mainloop24
+mainloop24end:
+
+          mov             ecx,diff
+          cmp             ecx,0
+          jz              end24
+
+          mov             edx,mask
+          sal             edx,24      //make low byte the high byte
+
+secondloop24:
+          sal             edx,1       //move high bit to CF
+          jnc             skip24      //if CF = 0
+          mov             ax,[esi]
+          mov             [ebx],ax
+          xor             eax,eax
+          mov             al,[esi+2]
+          mov             [ebx+2],al
+skip24:
+          add             esi,3
+          add             ebx,3
+
+          dec             ecx
+          jnz secondloop24
+
+end24:
+          emms
+
+          }
+        }
+        else /* mmx _not supported - Use modified C routine */
+        {
+          register unsigned int incr1, initial_val, final_val;
+          png_size_t pixel_bytes;
+          png_uint_32 i;
+          register int disp = png_pass_inc[png_ptr->pass];
+          int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+          pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+          srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]
+             *pixel_bytes;
+          dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+          initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+          final_val = png_ptr->width*pixel_bytes;
+          incr1 = (disp)*pixel_bytes;
+          for (i = initial_val; i < final_val; i += incr1)
+          {
+          png_memcpy(dstptr, srcptr, pixel_bytes);
+          srcptr += incr1;
+          dstptr += incr1;
+          }
+        } /* end of else */
+
+        break;
+      }       //end 24bpp
+    case 32:
+      {
+      png_bytep srcptr;
+      png_bytep dstptr;
+      png_uint_32 len;
+      int unmask, diff;
+
+
+
+      __int64 mask3=0x0101010102020202,       //32bpp
+          mask2=0x0404040408080808,
+          mask1=0x1010101020202020,
+          mask0=0x4040404080808080;
+
+      srcptr = png_ptr->row_buf + 1;
+      dstptr = row;
+
+      unmask = ~mask;
+      len     = (png_ptr->width)&~7;
+      diff = (png_ptr->width)&7;
+
+      if (mmx_supported)
+      {
+      _asm {
+        movd    mm7, unmask           //load bit pattern
+        psubb   mm6,mm6               //zero mm6
+        punpcklbw mm7,mm7
+        punpcklwd mm7,mm7
+        punpckldq mm7,mm7             //fill register with 8 masks
+
+        movq    mm0,mask0
+        movq    mm1,mask1
+        movq    mm2,mask2
+        movq    mm3,mask3
+
+
+        pand    mm0,mm7
+        pand    mm1,mm7
+        pand    mm2,mm7
+        pand    mm3,mm7
+
+        pcmpeqb mm0,mm6
+        pcmpeqb mm1,mm6
+        pcmpeqb mm2,mm6
+        pcmpeqb mm3,mm6
+
+        mov             ecx,len       //load length of line
+        mov             esi,srcptr    //load source
+        mov             ebx,dstptr    //load dest
+
+            cmp   ecx,0 //lcr
+            jz    mainloop32end
+
+mainloop32:
+        movq    mm4,[esi]
+        pand    mm4,mm0
+        movq    mm6,mm0
+        movq    mm7,[ebx]
+        pandn   mm6,mm7
+        por             mm4,mm6
+        movq    [ebx],mm4
+
+
+        movq    mm5,[esi+8]
+        pand    mm5,mm1
+        movq    mm7,mm1
+        movq    mm6,[ebx+8]
+        pandn   mm7,mm6
+        por             mm5,mm7
+        movq    [ebx+8],mm5
+
+        movq    mm6,[esi+16]
+        pand    mm6,mm2
+        movq    mm4,mm2
+        movq    mm7,[ebx+16]
+        pandn   mm4,mm7
+        por             mm6,mm4
+        movq    [ebx+16],mm6
+
+        movq    mm7,[esi+24]
+        pand    mm7,mm3
+        movq    mm5,mm3
+        movq    mm4,[ebx+24]
+        pandn   mm5,mm4
+        por             mm7,mm5
+        movq    [ebx+24],mm7
+
+
+        add             esi,32        //inc by 32 bytes processed
+        add             ebx,32
+        sub             ecx,8         //dec by 8 pixels processed
+
+        ja              mainloop32
+mainloop32end:
+
+        mov             ecx,diff
+        cmp             ecx,0
+        jz              end32
+
+        mov             edx,mask
+        sal             edx,24        //make low byte the high byte
+
+secondloop32:
+        sal             edx,1         //move high bit to CF
+        jnc             skip32        //if CF = 0
+        mov             eax,[esi]
+        mov             [ebx],eax
+skip32:
+        add             esi,4
+        add             ebx,4
+
+        dec             ecx
+        jnz secondloop32
+
+end32:
+        emms
+
+         }
+      }
+      else /* mmx _not supported - Use modified C routine */
+        {
+          register unsigned int incr1, initial_val, final_val;
+          png_size_t pixel_bytes;
+          png_uint_32 i;
+          register int disp = png_pass_inc[png_ptr->pass];
+          int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+          pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+          srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+             pixel_bytes;
+          dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+          initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+          final_val = png_ptr->width*pixel_bytes;
+          incr1 = (disp)*pixel_bytes;
+          for (i = initial_val; i < final_val; i += incr1)
+          {
+          png_memcpy(dstptr, srcptr, pixel_bytes);
+          srcptr += incr1;
+          dstptr += incr1;
+          }
+        } /* end of else */
+
+      break;
+      }       //end 32bpp
+
+
+      case 48:
+      {
+      png_bytep srcptr;
+      png_bytep dstptr;
+      png_uint_32 len;
+      int unmask, diff;
+
+      __int64 mask5=0x0101010101010202,
+          mask4=0x0202020204040404,
+          mask3=0x0404080808080808,
+          mask2=0x1010101010102020,
+          mask1=0x2020202040404040,
+          mask0=0x4040808080808080;
+
+      if (mmx_supported)
+      {
+
+      srcptr = png_ptr->row_buf + 1;
+      dstptr = row;
+
+      unmask = ~mask;
+      len     = (png_ptr->width)&~7;
+      diff = (png_ptr->width)&7;
+      _asm {
+        movd    mm7, unmask   //load bit pattern
+        psubb   mm6,mm6       //zero mm6
+        punpcklbw mm7,mm7
+        punpcklwd mm7,mm7
+        punpckldq mm7,mm7     //fill register with 8 masks
+
+        movq    mm0,mask0
+        movq    mm1,mask1
+        movq    mm2,mask2
+        movq    mm3,mask3
+        movq    mm4,mask4
+        movq    mm5,mask5
+
+        pand    mm0,mm7
+        pand    mm1,mm7
+        pand    mm2,mm7
+        pand    mm3,mm7
+        pand    mm4,mm7
+        pand    mm5,mm7
+
+        pcmpeqb mm0,mm6
+        pcmpeqb mm1,mm6
+        pcmpeqb mm2,mm6
+        pcmpeqb mm3,mm6
+        pcmpeqb mm4,mm6
+        pcmpeqb mm5,mm6
+
+        mov             ecx,len       //load length of line
+        mov             esi,srcptr    //load source
+        mov             ebx,dstptr    //load dest
+
+            cmp   ecx,0
+            jz    mainloop48end
+
+mainloop48:
+        movq    mm7,[esi]
+        pand    mm7,mm0
+        movq    mm6,mm0
+        pandn   mm6,[ebx]
+        por             mm7,mm6
+        movq    [ebx],mm7
+
+
+        movq    mm6,[esi+8]
+        pand    mm6,mm1
+        movq    mm7,mm1
+        pandn   mm7,[ebx+8]
+        por             mm6,mm7
+        movq    [ebx+8],mm6
+
+        movq    mm6,[esi+16]
+        pand    mm6,mm2
+        movq    mm7,mm2
+        pandn   mm7,[ebx+16]
+        por             mm6,mm7
+        movq    [ebx+16],mm6
+
+        movq    mm7,[esi+24]
+        pand    mm7,mm3
+        movq    mm6,mm3
+        pandn   mm6,[ebx+24]
+        por             mm7,mm6
+        movq    [ebx+24],mm7
+
+        movq    mm6,[esi+32]
+        pand    mm6,mm4
+        movq    mm7,mm4
+        pandn   mm7,[ebx+32]
+        por             mm6,mm7
+        movq    [ebx+32],mm6
+
+        movq    mm7,[esi+40]
+        pand    mm7,mm5
+        movq    mm6,mm5
+        pandn   mm6,[ebx+40]
+        por             mm7,mm6
+        movq    [ebx+40],mm7
+
+        add             esi,48   //inc by 32 bytes processed
+        add             ebx,48
+        sub             ecx,8    //dec by 8 pixels processed
+
+        ja              mainloop48
+mainloop48end:
+
+        mov             ecx,diff
+        cmp             ecx,0
+        jz              end48
+
+        mov             edx,mask
+        sal             edx,24   //make low byte the high byte
+
+secondloop48:
+        sal             edx,1    //move high bit to CF
+        jnc             skip48   //if CF = 0
+        mov             eax,[esi]
+        mov             [ebx],eax
+skip48:
+        add             esi,4
+        add             ebx,4
+
+        dec             ecx
+        jnz secondloop48
+
+end48:
+        emms
+        }
+        }
+        else /* mmx _not supported - Use modified C routine */
+        {
+          register unsigned int incr1, initial_val, final_val;
+          png_size_t pixel_bytes;
+          png_uint_32 i;
+          register int disp = png_pass_inc[png_ptr->pass];
+          int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+          pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+          srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+             pixel_bytes;
+          dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+          initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+          final_val = png_ptr->width*pixel_bytes;
+          incr1 = (disp)*pixel_bytes;
+          for (i = initial_val; i < final_val; i += incr1)
+          {
+          png_memcpy(dstptr, srcptr, pixel_bytes);
+          srcptr += incr1;
+          dstptr += incr1;
+          }
+        } /* end of else */
+      break;  // end 48 bpp
+      }
+  default:
+      {
+      png_bytep sptr;
+      png_bytep dp;
+      png_size_t pixel_bytes;
+      int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+      unsigned int i;
+      register int disp = png_pass_inc[png_ptr->pass];   // get the offset
+      register unsigned int incr1, initial_val, final_val;
+      pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+      sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*pixel_bytes;
+      dp = row + offset_table[png_ptr->pass]*pixel_bytes;
+      initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+      final_val = png_ptr->width*pixel_bytes;
+      incr1 = (disp)*pixel_bytes;
+      for (i = initial_val; i < final_val; i += incr1)
+      {
+        png_memcpy(dp, sptr, pixel_bytes);
+        sptr += incr1;
+        dp += incr1;
+      }
+
+      break;
+      }
+    }
+  }
+}
+
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+
+void
+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+   png_uint_32 transformations)
+{
+
+   png_debug(1,"in png_do_read_interlace\n");
+   if (mmx_supported==2)
+       mmx_supported=mmxsupport();
+
+   if (row != NULL && row_info != NULL)
+   {
+      png_uint_32 final_width;
+
+      final_width = row_info->width * png_pass_inc[pass];
+
+      switch (row_info->pixel_depth)
+      {
+   case 1:
+   {
+      png_bytep sp, dp;
+      int sshift, dshift;
+      int s_start, s_end, s_inc;
+      png_byte v;
+      png_uint_32 i;
+      int j;
+
+      sp = row + (png_size_t)((row_info->width - 1) >> 3);
+      dp = row + (png_size_t)((final_width - 1) >> 3);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (transformations & PNG_PACKSWAP)
+      {
+    sshift = (int)((row_info->width + 7) & 7);
+    dshift = (int)((final_width + 7) & 7);
+    s_start = 7;
+    s_end = 0;
+    s_inc = -1;
+      }
+      else
+#endif
+      {
+    sshift = 7 - (int)((row_info->width + 7) & 7);
+    dshift = 7 - (int)((final_width + 7) & 7);
+    s_start = 0;
+    s_end = 7;
+    s_inc = 1;
+      }
+
+      for (i = row_info->width; i; i--)
+      {
+         v = (png_byte)((*sp >> sshift) & 0x1);
+         for (j = 0; j < png_pass_inc[pass]; j++)
+         {
+      *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+      *dp |= (png_byte)(v << dshift);
+      if (dshift == s_end)
+      {
+         dshift = s_start;
+         dp--;
+      }
+      else
+         dshift += s_inc;
+         }
+         if (sshift == s_end)
+         {
+      sshift = s_start;
+      sp--;
+         }
+         else
+      sshift += s_inc;
+      }
+      break;
+   }
+   case 2:
+   {
+      png_bytep sp, dp;
+      int sshift, dshift;
+      int s_start, s_end, s_inc;
+      png_uint_32 i;
+
+      sp = row + (png_size_t)((row_info->width - 1) >> 2);
+      dp = row + (png_size_t)((final_width - 1) >> 2);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (transformations & PNG_PACKSWAP)
+      {
+         sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
+         dshift = (png_size_t)(((final_width + 3) & 3) << 1);
+         s_start = 6;
+         s_end = 0;
+         s_inc = -2;
+      }
+      else
+#endif
+      {
+         sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
+         dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
+         s_start = 0;
+         s_end = 6;
+         s_inc = 2;
+      }
+
+      for (i = row_info->width; i; i--)
+      {
+         png_byte v;
+         int j;
+
+         v = (png_byte)((*sp >> sshift) & 0x3);
+         for (j = 0; j < png_pass_inc[pass]; j++)
+         {
+      *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+      *dp |= (png_byte)(v << dshift);
+      if (dshift == s_end)
+      {
+         dshift = s_start;
+         dp--;
+      }
+      else
+         dshift += s_inc;
+         }
+         if (sshift == s_end)
+         {
+      sshift = s_start;
+      sp--;
+         }
+         else
+      sshift += s_inc;
+      }
+      break;
+   }
+   case 4:
+   {
+      png_bytep sp, dp;
+      int sshift, dshift;
+      int s_start, s_end, s_inc;
+      png_uint_32 i;
+
+      sp = row + (png_size_t)((row_info->width - 1) >> 1);
+      dp = row + (png_size_t)((final_width - 1) >> 1);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+      if (transformations & PNG_PACKSWAP)
+      {
+         sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
+         dshift = (png_size_t)(((final_width + 1) & 1) << 2);
+         s_start = 4;
+         s_end = 0;
+         s_inc = -4;
+      }
+      else
+#endif
+      {
+         sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
+         dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
+         s_start = 0;
+         s_end = 4;
+         s_inc = 4;
+      }
+
+      for (i = row_info->width; i; i--)
+      {
+         png_byte v;
+         int j;
+
+         v = (png_byte)((*sp >> sshift) & 0xf);
+         for (j = 0; j < png_pass_inc[pass]; j++)
+         {
+      *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+      *dp |= (png_byte)(v << dshift);
+      if (dshift == s_end)
+      {
+         dshift = s_start;
+         dp--;
+      }
+      else
+         dshift += s_inc;
+         }
+         if (sshift == s_end)
+         {
+      sshift = s_start;
+      sp--;
+         }
+         else
+      sshift += s_inc;
+      }
+      break;
+   }
+   default:         // This is the place where the routine is modified
+   {
+      __int64 const4 = 0x0000000000FFFFFF;
+      __int64 const5 = 0x000000FFFFFF0000;
+      __int64 const6 = 0x00000000000000FF;
+      //int mmx_supported = 1;
+
+      png_bytep sptr, dp;
+      png_uint_32 i;
+      png_size_t pixel_bytes;
+
+      int width = row_info->width;
+
+      pixel_bytes = (row_info->pixel_depth >> 3);
+
+      sptr = row + (row_info->width - 1) * pixel_bytes;
+      dp = row + (final_width - 1) * pixel_bytes;
+      // New code by Nirav Chhatrapati - Intel Corporation
+
+      if (mmx_supported) // If machine supports MMX technology use MMX routine
+      {
+      if (pixel_bytes == 3)
+      {
+        if ((pass == 0) || (pass == 1))
+        {
+          _asm
+          {
+            mov esi, sptr
+
+            mov edi, dp
+
+            mov ecx, width
+
+            sub edi, 21   // (png_pass_inc[pass] - 1)*pixel_bytes
+
+loop_pass0:
+
+            movd mm0, [esi]     ; X X X X X val2 val1 val0
+
+            pand mm0, const4    ; 0 0 0 0 0 val2 val1 val0
+
+            movq mm1, mm0       ; 0 0 0 0 0 val2 val1 val0
+
+            psllq mm0, 16       ; 0 0 0 val2 val1 val0 0 0
+
+            movq mm2, mm0       ; 0 0 0 val2 val1 val0 0 0
+
+            psllq mm0, 24       ; val2 val1 val0 0 0 0 0 0
+
+            psrlq mm1, 8        ; 0 0 0 0 0 0 val2 val1
+
+            por mm0, mm2        ; val2 val1 val0 val2 val1 val0 0 0
+
+            por mm0, mm1        ; val2 val1 val0 val2 val1 val0 val2 val1
+
+            movq mm3, mm0       ; val2 val1 val0 val2 val1 val0 val2 val1
+
+            psllq mm0, 16       ; val0 val2 val1 val0 val2 val1 0 0
+
+            movq mm4, mm3       ; val2 val1 val0 val2 val1 val0 val2 val1
+
+            punpckhdq mm3, mm0  ; val0 val2 val1 val0 val2 val1 val0 val2
+
+            movq [edi+16] , mm4
+
+            psrlq mm0, 32       ; 0 0 0 0 val0 val2 val1 val0
+
+            movq [edi+8] , mm3
+
+            punpckldq mm0, mm4  ; val1 val0 val2 val1 val0 val2 val1 val0
+
+            sub esi, 3
+
+            movq [edi], mm0
+
+            sub edi, 24
+
+            //sub esi, 3
+
+            dec ecx
+
+            jnz loop_pass0
+
+            EMMS
+          }
+
+        }
+
+        else if ((pass == 2) || (pass == 3))
+        {
+          _asm
+          {
+            mov esi, sptr
+
+            mov edi, dp
+
+            mov ecx, width
+
+            sub edi, 9   // (png_pass_inc[pass] - 1)*pixel_bytes
+
+loop_pass2:
+
+            movd mm0, [esi]     ; X X X X X val2 val1 val0
+
+            pand mm0, const4    ; 0 0 0 0 0 val2 val1 val0
+
+            movq mm1, mm0       ; 0 0 0 0 0 val2 val1 val0
+
+            psllq mm0, 16       ; 0 0 0 val2 val1 val0 0 0
+
+            movq mm2, mm0       ; 0 0 0 val2 val1 val0 0 0
+
+            psllq mm0, 24       ; val2 val1 val0 0 0 0 0 0
+
+            psrlq mm1, 8        ; 0 0 0 0 0 0 val2 val1
+
+            por mm0, mm2        ; val2 val1 val0 val2 val1 val0 0 0
+
+            por mm0, mm1        ; val2 val1 val0 val2 val1 val0 val2 val1
+
+            movq [edi+4], mm0   ; move to memory
+
+            psrlq mm0, 16       ; 0 0 val2 val1 val0 val2 val1 val0
+
+            movd [edi], mm0     ; move to memory
+
+            sub esi, 3
+
+            sub edi, 12
+
+            dec ecx
+
+            jnz loop_pass2
+
+            EMMS
+          }
+        }
+
+        else /*if ((pass == 4) || (pass == 5)) */
+        {
+
+          int width_mmx = ((width >> 1) << 1) - 8;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+
+            mov edi, dp
+
+            mov ecx, width_mmx
+
+            sub esi, 3
+
+            sub edi, 9
+
+loop_pass4:
+
+            movq mm0, [esi]     ; X X v2 v1 v0 v5 v4 v3
+
+            movq mm7, mm0       ; X X v2 v1 v0 v5 v4 v3
+
+            movq mm6, mm0       ; X X v2 v1 v0 v5 v4 v3
+
+            psllq mm0, 24       ; v1 v0 v5 v4 v3 0 0 0
+
+            pand mm7, const4    ; 0 0 0 0 0 v5 v4 v3
+
+            psrlq mm6, 24       ; 0 0 0 X X v2 v1 v0
+
+            por mm0, mm7        ; v1 v0 v5 v4 v3 v5 v4 v3
+
+            movq mm5, mm6       ; 0 0 0 X X v2 v1 v0
+
+            psllq mm6, 8        ; 0 0 X X v2 v1 v0 0
+
+            movq [edi], mm0     ; move quad to memory
+
+            psrlq mm5, 16       ; 0 0 0 0 0 X X v2
+
+            pand mm5, const6    ; 0 0 0 0 0 0 0 v2
+
+            por mm6, mm5        ; 0 0 X X v2 v1 v0 v2
+
+            movd [edi+8], mm6   ; move double to memory
+
+            sub esi, 6
+
+            sub edi, 12
+
+            sub ecx, 2
+
+            jnz loop_pass4
+
+            EMMS
+          }
+
+          sptr -= width_mmx*3;
+          dp -= width_mmx*6;
+          for (i = width; i; i--)
+          {
+            png_byte v[8];
+            int j;
+
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              png_memcpy(dp, v, pixel_bytes);
+              dp -= pixel_bytes;
+            }
+           sptr -= pixel_bytes;
+           }
+
+        }
+
+      }  /* end of pixel_bytes == 3 */
+
+      else if (pixel_bytes == 1)
+      {
+
+        if ((pass == 0) || (pass == 1))
+        {
+          int width_mmx = ((width >> 2) << 2);
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+
+            mov esi, sptr
+
+            mov edi, dp
+
+            mov ecx, width_mmx
+
+            sub edi, 31
+
+            sub esi, 3
+
+loop1_pass0:
+
+            movd mm0, [esi]     ; X X X X v0 v1 v2 v3
+
+            movq mm1, mm0       ; X X X X v0 v1 v2 v3
+
+            punpcklbw mm0, mm0  ; v0 v0 v1 v1 v2 v2 v3 v3
+
+            movq mm2, mm0       ; v0 v0 v1 v1 v2 v2 v3 v3
+
+            punpcklwd mm0, mm0  ; v2 v2 v2 v2 v3 v3 v3 v3
+
+            movq mm3, mm0       ; v2 v2 v2 v2 v3 v3 v3 v3
+
+            punpckldq mm0, mm0  ; v3 v3 v3 v3 v3 v3 v3 v3
+
+            punpckhdq mm3, mm3  ; v2 v2 v2 v2 v2 v2 v2 v2
+
+            movq [edi], mm0     ; move to memory v3
+
+            punpckhwd mm2, mm2  ; v0 v0 v0 v0 v1 v1 v1 v1
+
+            movq [edi+8], mm3   ; move to memory v2
+
+            movq mm4, mm2       ; v0 v0 v0 v0 v1 v1 v1 v1
+
+            punpckldq mm2, mm2  ; v1 v1 v1 v1 v1 v1 v1 v1
+
+            punpckhdq mm4, mm4  ; v0 v0 v0 v0 v0 v0 v0 v0
+
+            movq [edi+16], mm2  ; move to memory v1
+
+            movq [edi+24], mm4  ; move to memory v0
+
+            sub esi, 4
+
+            sub edi, 32
+
+            sub ecx, 4
+
+            jnz loop1_pass0
+
+            EMMS
+          }
+
+          sptr -= width_mmx;
+          dp -= width_mmx*8;
+          for (i = width; i; i--)
+          {
+            png_byte v[8];
+            int j;
+
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              png_memcpy(dp, v, pixel_bytes);
+              dp -= pixel_bytes;
+            }
+           sptr -= pixel_bytes;
+          }
+
+        }
+
+
+        else if ((pass == 2) || (pass == 3))
+        {
+          int width_mmx = ((width >> 2) << 2);
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+
+            mov esi, sptr
+
+            mov edi, dp
+
+            mov ecx, width_mmx
+
+            sub edi, 15
+
+            sub esi, 3
+
+loop1_pass2:
+
+            movd mm0, [esi]     ; X X X X v0 v1 v2 v3
+
+            punpcklbw mm0, mm0  ; v0 v0 v1 v1 v2 v2 v3 v3
+
+            movq mm1, mm0       ; v0 v0 v1 v1 v2 v2 v3 v3
+
+            punpcklwd mm0, mm0  ; v2 v2 v2 v2 v3 v3 v3 v3
+
+            punpckhwd mm1, mm1  ; v0 v0 v0 v0 v1 v1 v1 v1
+
+            movq [edi], mm0     ; move to memory v2 and v3
+
+            sub esi, 4
+
+            movq [edi+8], mm1   ; move to memory v1     and v0
+
+            sub edi, 16
+
+            sub ecx, 4
+
+            jnz loop1_pass2
+
+            EMMS
+          }
+
+          sptr -= width_mmx;
+          dp -= width_mmx*4;
+          for (i = width; i; i--)
+          {
+            png_byte v[8];
+            int j;
+
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              png_memcpy(dp, v, pixel_bytes);
+              dp -= pixel_bytes;
+            }
+           sptr -= pixel_bytes;
+          }
+
+        }
+
+        else //if ((pass == 4) || (pass == 5))
+        {
+          int width_mmx = ((width >> 3) << 3);
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub edi, 15
+            sub esi, 7
+
+loop1_pass4:
+
+            movq mm0, [esi]     ; v0 v1 v2 v3 v4 v5 v6 v7
+            movq mm1, mm0       ; v0 v1 v2 v3 v4 v5 v6 v7
+            punpcklbw mm0, mm0  ; v4 v4 v5 v5 v6 v6 v7 v7
+            //movq mm1, mm0     ; v0 v0 v1 v1 v2 v2 v3 v3
+            punpckhbw mm1, mm1  ;v0 v0 v1 v1 v2 v2 v3 v3
+            movq [edi+8], mm1   ; move to memory v0 v1 v2 and v3
+            sub esi, 8
+            movq [edi], mm0     ; move to memory v4 v5 v6 and v7
+            //sub esi, 4
+            sub edi, 16
+            sub ecx, 8
+            jnz loop1_pass4
+
+            EMMS
+          }
+
+          sptr -= width_mmx;
+          dp -= width_mmx*2;
+          for (i = width; i; i--)
+          {
+            png_byte v[8];
+            int j;
+
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              png_memcpy(dp, v, pixel_bytes);
+              dp -= pixel_bytes;
+            }
+           sptr -= pixel_bytes;
+          }
+
+        }
+
+      }       /* end of pixel_bytes == 1 */
+
+      else if (pixel_bytes == 2)
+      {
+
+        if ((pass == 0) || (pass == 1))
+        {
+          int width_mmx = ((width >> 1) << 1);
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 2
+            sub edi, 30
+
+loop2_pass0:
+            movd mm0, [esi]        ; X X X X v1 v0 v3 v2
+            punpcklwd mm0, mm0     ; v1 v0 v1 v0 v3 v2 v3 v2
+            movq mm1, mm0          ; v1 v0 v1 v0 v3 v2 v3 v2
+            punpckldq mm0, mm0     ; v3 v2 v3 v2 v3 v2 v3 v2
+            punpckhdq mm1, mm1     ; v1 v0 v1 v0 v1 v0 v1 v0
+            movq [edi], mm0
+            movq [edi + 8], mm0
+            movq [edi + 16], mm1
+            movq [edi + 24], mm1
+            sub esi, 4
+            sub edi, 32
+            sub ecx, 2
+            jnz loop2_pass0
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*2 + 2);
+          dp -= (width_mmx*16 + 2);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+        else if ((pass == 2) || (pass == 3))
+        {
+          int width_mmx = ((width >> 1) << 1) ;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 2
+            sub edi, 14
+
+loop2_pass2:
+            movd mm0, [esi]        ; X X X X v1 v0 v3 v2
+            punpcklwd mm0, mm0     ; v1 v0 v1 v0 v3 v2 v3 v2
+            movq mm1, mm0          ; v1 v0 v1 v0 v3 v2 v3 v2
+            punpckldq mm0, mm0     ; v3 v2 v3 v2 v3 v2 v3 v2
+            punpckhdq mm1, mm1     ; v1 v0 v1 v0 v1 v0 v1 v0
+            movq [edi], mm0
+            sub esi, 4
+            movq [edi + 8], mm1
+            //sub esi, 4
+            sub edi, 16
+            sub ecx, 2
+            jnz loop2_pass2
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*2 + 2);
+          dp -= (width_mmx*8 + 2);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+        else // pass == 4 or 5
+        {
+          int width_mmx = ((width >> 1) << 1) ;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 2
+            sub edi, 6
+
+loop2_pass4:
+            movd mm0, [esi]        ; X X X X v1 v0 v3 v2
+            punpcklwd mm0, mm0     ; v1 v0 v1 v0 v3 v2 v3 v2
+            sub esi, 4
+            movq [edi], mm0
+            sub edi, 8
+            sub ecx, 2
+            jnz loop2_pass4
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*2 + 2);
+          dp -= (width_mmx*4 + 2);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+      } /* end of pixel_bytes == 2 */
+
+      else if (pixel_bytes == 4)
+      {
+        if ((pass == 0) || (pass == 1))
+        {
+          int width_mmx = ((width >> 1) << 1) ;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 4
+            sub edi, 60
+
+loop4_pass0:
+            movq mm0, [esi]        ; v3 v2 v1 v0 v7 v6 v5 v4
+            movq mm1, mm0          ; v3 v2 v1 v0 v7 v6 v5 v4
+            punpckldq mm0, mm0     ; v7 v6 v5 v4 v7 v6 v5 v4
+            punpckhdq mm1, mm1     ; v3 v2 v1 v0 v3 v2 v1 v0
+            movq [edi], mm0
+            movq [edi + 8], mm0
+            movq [edi + 16], mm0
+            movq [edi + 24], mm0
+            movq [edi+32], mm1
+            movq [edi + 40], mm1
+            movq [edi+ 48], mm1
+            sub esi, 8
+            movq [edi + 56], mm1
+            sub edi, 64
+            sub ecx, 2
+            jnz loop4_pass0
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*4 + 4);
+          dp -= (width_mmx*32 + 4);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+        else if ((pass == 2) || (pass == 3))
+        {
+          int width_mmx = ((width >> 1) << 1) ;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 4
+            sub edi, 28
+
+loop4_pass2:
+            movq mm0, [esi]      ; v3 v2 v1 v0 v7 v6 v5 v4
+            movq mm1, mm0        ; v3 v2 v1 v0 v7 v6 v5 v4
+            punpckldq mm0, mm0   ; v7 v6 v5 v4 v7 v6 v5 v4
+            punpckhdq mm1, mm1   ; v3 v2 v1 v0 v3 v2 v1 v0
+            movq [edi], mm0
+            movq [edi + 8], mm0
+            movq [edi+16], mm1
+            movq [edi + 24], mm1
+            sub esi, 8
+            sub edi, 32
+            sub ecx, 2
+            jnz loop4_pass2
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*4 + 4);
+          dp -= (width_mmx*16 + 4);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+        else // pass == 4 or 5
+        {
+          int width_mmx = ((width >> 1) << 1) ;
+          width -= width_mmx;
+               if(width_mmx)
+          _asm
+          {
+            mov esi, sptr
+            mov edi, dp
+            mov ecx, width_mmx
+            sub esi, 4
+            sub edi, 12
+
+loop4_pass4:
+            movq mm0, [esi]      ; v3 v2 v1 v0 v7 v6 v5 v4
+            movq mm1, mm0        ; v3 v2 v1 v0 v7 v6 v5 v4
+            punpckldq mm0, mm0   ; v7 v6 v5 v4 v7 v6 v5 v4
+            punpckhdq mm1, mm1   ; v3 v2 v1 v0 v3 v2 v1 v0
+            movq [edi], mm0
+            sub esi, 8
+            movq [edi + 8], mm1
+            sub edi, 16
+            sub ecx, 2
+            jnz loop4_pass4
+
+            EMMS
+          }
+
+          sptr -= (width_mmx*4 + 4);
+          dp -= (width_mmx*8 + 4);
+
+          for (i = width; i; i--)
+          {
+
+            png_byte v[8];
+            int j;
+            sptr -= pixel_bytes;
+            png_memcpy(v, sptr, pixel_bytes);
+            for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+              dp -= pixel_bytes;
+              png_memcpy(dp, v, pixel_bytes);
+              //dp -= pixel_bytes;
+            }
+            //sptr -= pixel_bytes;
+          }
+        }
+
+      } /* end of pixel_bytes == 4 */
+
+      else if (pixel_bytes == 6)
+      {
+        for (i = row_info->width; i; i--)
+        {
+
+          png_byte v[8];
+          int j;
+          png_memcpy(v, sptr, pixel_bytes);
+          for (j = 0; j < png_pass_inc[pass]; j++)
+          {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+          }
+          sptr -= pixel_bytes;
+        }
+      } /* end of pixel_bytes == 6 */
+
+      else
+      {
+      for (i = row_info->width; i; i--)
+        {
+
+          png_byte v[8];
+          int j;
+          png_memcpy(v, sptr, pixel_bytes);
+          for (j = 0; j < png_pass_inc[pass]; j++)
+          {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+          }
+          sptr-= pixel_bytes;
+        }
+      }
+      }       /* end of mmx_supported */
+
+      else   /* MMX not supported */
+      /* use modified C code - takes advantage of inlining of memcpy for
+         a constant */
+      {
+        if (pixel_bytes == 1)
+        {
+        for (i = row_info->width; i; i--)
+          {
+          png_byte v[8];
+          int j;
+
+          png_memcpy(v, sptr, pixel_bytes);
+          for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+        else if (pixel_bytes == 3)
+        {
+        for (i = row_info->width; i; i--)
+        {
+          png_byte v[8];
+          int j;
+      png_memcpy(v, sptr, pixel_bytes);
+         for (j = 0; j < png_pass_inc[pass]; j++)
+            {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+        else if (pixel_bytes == 2)
+        {
+        for (i = row_info->width; i; i--)
+          {
+          png_byte v[8];
+          int j;
+      png_memcpy(v, sptr, pixel_bytes);
+        for (j = 0; j < png_pass_inc[pass]; j++)
+             {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+        else if (pixel_bytes == 4)
+        {
+        for (i = row_info->width; i; i--)
+          {
+          png_byte v[8];
+          int j;
+      png_memcpy(v, sptr, pixel_bytes);
+        for (j = 0; j < png_pass_inc[pass]; j++)
+             {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+        else if (pixel_bytes == 6)
+        {
+        for (i = row_info->width; i; i--)
+          {
+          png_byte v[8];
+          int j;
+      png_memcpy(v, sptr, pixel_bytes);
+        for (j = 0; j < png_pass_inc[pass]; j++)
+             {
+            png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+        else
+        {
+        for (i = row_info->width; i; i--)
+          {
+          png_byte v[8];
+          int j;
+           png_memcpy(v, sptr, pixel_bytes);
+         for (j = 0; j < png_pass_inc[pass]; j++)
+               {
+              png_memcpy(dp, v, pixel_bytes);
+            dp -= pixel_bytes;
+            }
+          sptr -= pixel_bytes;
+          }
+        }
+
+      } /* end of MMX not supported */
+      break;
+   }
+      }
+    row_info->width = final_width;
+      row_info->rowbytes = ((final_width *
+   (png_uint_32)row_info->pixel_depth + 7) >> 3);
+   }
+}
+
+#endif
+
+
+
+// These variables are utilized in the functions below.  They are declared
+// globally here to ensure alignment on 8-byte boundaries.
+union uAll {
+   __int64 use;
+   double  align;
+}  LBCarryMask = {0x0101010101010101}, HBClearMask = {0x7f7f7f7f7f7f7f7f},
+   ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem;
+
+// Optimized code for PNG Average filter decoder
+void
+png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row
+                            , png_bytep prev_row)
+{
+      int bpp;
+      png_uint_32 FullLength;
+      png_uint_32 MMXLength;
+      //png_uint_32 len;
+      int diff;
+      bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+    FullLength  = row_info->rowbytes; // # of bytes to filter
+      _asm {
+         // Init address pointers and offset
+         mov edi, row          // edi ==> Avg(x)
+         xor ebx, ebx          // ebx ==> x
+         mov edx, edi
+   mov esi, prev_row           // esi ==> Prior(x)
+         sub edx, bpp          // edx ==> Raw(x-bpp)
+
+         xor eax, eax
+         // Compute the Raw value for the first bpp bytes
+         //    Raw(x) = Avg(x) + (Prior(x)/2)
+davgrlp:
+         mov al, [esi + ebx]   // Load al with Prior(x)
+   inc ebx
+         shr al, 1             // divide by 2
+         add al, [edi+ebx-1]   // Add Avg(x); -1 to offset inc ebx
+         cmp ebx, bpp
+   mov [edi+ebx-1], al    // Write back Raw(x);
+                          // mov does not affect flags; -1 to offset inc ebx
+         jb davgrlp
+         // get # of bytes to alignment
+         mov diff, edi         // take start of row
+         add diff, ebx         // add bpp
+         add diff, 0xf         // add 7 + 8 to incr past alignment boundary
+         and diff, 0xfffffff8  // mask to alignment boundary
+         sub diff, edi         // subtract from start ==> value ebx at alignment
+         jz davggo
+         // fix alignment
+         // Compute the Raw value for the bytes upto the alignment boundary
+         //    Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+         xor ecx, ecx
+davglp1:
+         xor eax, eax
+   mov cl, [esi + ebx]        // load cl with Prior(x)
+         mov al, [edx + ebx]  // load al with Raw(x-bpp)
+         add ax, cx
+   inc ebx
+         shr ax, 1            // divide by 2
+         add al, [edi+ebx-1]  // Add Avg(x); -1 to offset inc ebx
+   cmp ebx, diff              // Check if at alignment boundary
+   mov [edi+ebx-1], al        // Write back Raw(x);
+                            // mov does not affect flags; -1 to offset inc ebx
+   jb davglp1               // Repeat until at alignment boundary
+davggo:
+   mov eax, FullLength
+         mov ecx, eax
+         sub eax, ebx          // subtract alignment fix
+         and eax, 0x00000007   // calc bytes over mult of 8
+         sub ecx, eax          // drop over bytes from original length
+         mov MMXLength, ecx
+      } // end _asm block
+      // Now do the math for the rest of the row
+      switch ( bpp )
+      {
+      case 3:
+      {
+         ActiveMask.use  = 0x0000000000ffffff;
+         ShiftBpp.use = 24;    // == 3 * 8
+         ShiftRem.use = 40;    // == 64 - 24
+         _asm {
+            // Re-init address pointers and offset
+            movq mm7, ActiveMask
+            mov ebx, diff      // ebx ==> x = offset to alignment boundary
+            movq mm5, LBCarryMask
+            mov edi, row       // edi ==> Avg(x)
+            movq mm4, HBClearMask
+      mov esi, prev_row        // esi ==> Prior(x)
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm2, [edi + ebx - 8]  // Load previous aligned 8 bytes
+                               // (we correct position in loop below)
+davg3lp:
+      movq mm0, [edi + ebx]      // Load mm0 with Avg(x)
+            // Add (Prev_row/2) to Average
+            movq mm3, mm5
+            psrlq mm2, ShiftRem      // Correct position Raw(x-bpp) data
+      movq mm1, [esi + ebx]    // Load mm1 with Prior(x)
+            movq mm6, mm7
+            pand mm3, mm1      // get lsb for each prev_row byte
+            psrlq mm1, 1       // divide prev_row bytes by 2
+            pand  mm1, mm4     // clear invalid bit 7 of each byte
+      paddb mm0, mm1           // add (Prev_row/2) to Avg for each byte
+            // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+            movq mm1, mm3      // now use mm1 for getting LBCarrys
+            pand mm1, mm2      // get LBCarrys for each byte where both
+                               // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1       // divide raw bytes by 2
+            pand  mm2, mm4     // clear invalid bit 7 of each byte
+            paddb mm2, mm1     // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6      // Leave only Active Group 1 bytes to add to Avg
+      paddb mm0, mm2      // add (Raw/2) + LBCarrys to Avg for each Active byte
+            // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+            psllq mm6, ShiftBpp  // shift the mm6 mask to cover bytes 3-5
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      paddb mm0, mm2     // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+            // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry
+            psllq mm6, ShiftBpp  // shift the mm6 mask to cover the last two bytes
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+                                 // Data only needs to be shifted once here to
+                                 // get the correct x-bpp offset.
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      add ebx, 8
+      paddb mm0, mm2     // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+            // Now ready to write back to memory
+      movq [edi + ebx - 8], mm0
+            // Move updated Raw(x) to use as Raw(x-bpp) for next loop
+      cmp ebx, MMXLength
+            movq mm2, mm0     // mov updated Raw(x) to mm2
+      jb davg3lp
+   } // end _asm block
+      }
+      break;
+      case 6:
+      case 4:
+      case 7:
+      case 5:
+      {
+         ActiveMask.use  = 0xffffffffffffffff;  // use shift below to clear
+                                               // appropriate inactive bytes
+         ShiftBpp.use = bpp << 3;
+         ShiftRem.use = 64 - ShiftBpp.use;
+   _asm {
+            movq mm4, HBClearMask
+            // Re-init address pointers and offset
+            mov ebx, diff       // ebx ==> x = offset to alignment boundary
+            // Load ActiveMask and clear all bytes except for 1st active group
+            movq mm7, ActiveMask
+            mov edi, row                  // edi ==> Avg(x)
+            psrlq mm7, ShiftRem
+      mov esi, prev_row             // esi ==> Prior(x)
+            movq mm6, mm7
+            movq mm5, LBCarryMask
+            psllq mm6, ShiftBpp    // Create mask for 2nd active group
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm2, [edi + ebx - 8]  // Load previous aligned 8 bytes
+                                 // (we correct position in loop below)
+davg4lp:
+      movq mm0, [edi + ebx]
+            psrlq mm2, ShiftRem  // shift data to position correctly
+      movq mm1, [esi + ebx]
+            // Add (Prev_row/2) to Average
+            movq mm3, mm5
+            pand mm3, mm1        // get lsb for each prev_row byte
+            psrlq mm1, 1         // divide prev_row bytes by 2
+            pand  mm1, mm4       // clear invalid bit 7 of each byte
+      paddb mm0, mm1             // add (Prev_row/2) to Avg for each byte
+            // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm7        // Leave only Active Group 1 bytes to add to Avg
+      paddb mm0, mm2    // add (Raw/2) + LBCarrys to Avg for each Active byte
+            // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+      add ebx, 8
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      paddb mm0, mm2    // add (Raw/2) + LBCarrys to Avg for each Active byte
+      cmp ebx, MMXLength
+            // Now ready to write back to memory
+      movq [edi + ebx - 8], mm0
+            // Prep Raw(x-bpp) for next loop
+            movq mm2, mm0        // mov updated Raws to mm2
+      jb davg4lp
+   } // end _asm block
+      }
+      break;
+      case 2:
+      {
+         ActiveMask.use  = 0x000000000000ffff;
+         ShiftBpp.use = 24;      // == 3 * 8
+         ShiftRem.use = 40;      // == 64 - 24
+   _asm {
+            // Load ActiveMask
+            movq mm7, ActiveMask
+            // Re-init address pointers and offset
+            mov ebx, diff        // ebx ==> x = offset to alignment boundary
+            movq mm5, LBCarryMask
+            mov edi, row         // edi ==> Avg(x)
+            movq mm4, HBClearMask
+      mov esi, prev_row          // esi ==> Prior(x)
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm2, [edi + ebx - 8]  // Load previous aligned 8 bytes
+                                 // (we correct position in loop below)
+davg2lp:
+      movq mm0, [edi + ebx]
+            psllq mm2, ShiftRem  // shift data to position correctly
+      movq mm1, [esi + ebx]
+            // Add (Prev_row/2) to Average
+            movq mm3, mm5
+            pand mm3, mm1        // get lsb for each prev_row byte
+            psrlq mm1, 1         // divide prev_row bytes by 2
+            pand  mm1, mm4       // clear invalid bit 7 of each byte
+            movq mm6, mm7
+      paddb mm0, mm1             // add (Prev_row/2) to Avg for each byte
+            // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 1 bytes to add to Avg
+      paddb mm0, mm2    // add (Raw/2) + LBCarrys to Avg for each Active byte
+            // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+            psllq mm6, ShiftBpp  // shift the mm6 mask to cover bytes 2 & 3
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      paddb mm0, mm2    // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+            // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry
+            psllq mm6, ShiftBpp  // shift the mm6 mask to cover bytes 4 & 5
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+                                 // Data only needs to be shifted once here to
+                                 // get the correct x-bpp offset.
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      paddb mm0, mm2    // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+            // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry
+            psllq mm6, ShiftBpp  // shift the mm6 mask to cover bytes 6 & 7
+            movq mm2, mm0        // mov updated Raws to mm2
+            psllq mm2, ShiftBpp  // shift data to position correctly
+                                 // Data only needs to be shifted once here to
+                                 // get the correct x-bpp offset.
+            add ebx, 8
+            movq mm1, mm3        // now use mm1 for getting LBCarrys
+            pand mm1, mm2        // get LBCarrys for each byte where both
+                                 // lsb's were == 1 (Only valid for active group)
+            psrlq mm2, 1         // divide raw bytes by 2
+            pand  mm2, mm4       // clear invalid bit 7 of each byte
+            paddb mm2, mm1       // add LBCarrys to (Raw(x-bpp)/2) for each byte
+            pand mm2, mm6        // Leave only Active Group 2 bytes to add to Avg
+      paddb mm0, mm2      // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+      cmp ebx, MMXLength
+            // Now ready to write back to memory
+      movq [edi + ebx - 8], mm0
+            // Prep Raw(x-bpp) for next loop
+            movq mm2, mm0        // mov updated Raws to mm2
+      jb davg2lp
+  } // end _asm block
+      }
+      break;
+      case 1:                    // bpp == 1
+      {
+         _asm {
+            // Re-init address pointers and offset
+            mov ebx, diff        // ebx ==> x = offset to alignment boundary
+            mov edi, row         // edi ==> Avg(x)
+            cmp ebx, FullLength  // Test if offset at end of array
+      jnb davg1end
+            // Do Paeth decode for remaining bytes
+        mov esi, prev_row        // esi ==> Prior(x)
+            mov edx, edi
+            xor ecx, ecx         // zero ecx before using cl & cx in loop below
+            sub edx, bpp         // edx ==> Raw(x-bpp)
+davg1lp:
+            // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+            xor eax, eax
+      mov cl, [esi + ebx]        // load cl with Prior(x)
+            mov al, [edx + ebx]  // load al with Raw(x-bpp)
+            add ax, cx
+      inc ebx
+            shr ax, 1            // divide by 2
+            add al, [edi+ebx-1]  // Add Avg(x); -1 to offset inc ebx
+      cmp ebx, FullLength        // Check if at end of array
+      mov [edi+ebx-1], al        // Write back Raw(x);
+                         // mov does not affect flags; -1 to offset inc ebx
+      jb davg1lp
+davg1end:
+   } // end _asm block
+      }
+      return;
+
+      case 8:             // bpp == 8
+      {
+   _asm {
+            // Re-init address pointers and offset
+            mov ebx, diff           // ebx ==> x = offset to alignment boundary
+            movq mm5, LBCarryMask
+            mov edi, row            // edi ==> Avg(x)
+            movq mm4, HBClearMask
+      mov esi, prev_row             // esi ==> Prior(x)
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm2, [edi + ebx - 8]  // Load previous aligned 8 bytes
+                                // (NO NEED to correct position in loop below)
+davg8lp:
+      movq mm0, [edi + ebx]
+            movq mm3, mm5
+      movq mm1, [esi + ebx]
+      add ebx, 8
+            pand mm3, mm1       // get lsb for each prev_row byte
+            psrlq mm1, 1        // divide prev_row bytes by 2
+            pand mm3, mm2       // get LBCarrys for each byte where both
+                                // lsb's were == 1
+            psrlq mm2, 1        // divide raw bytes by 2
+            pand  mm1, mm4      // clear invalid bit 7 of each byte
+            paddb mm0, mm3      // add LBCarrys to Avg for each byte
+            pand  mm2, mm4      // clear invalid bit 7 of each byte
+            paddb mm0, mm1      // add (Prev_row/2) to Avg for each byte
+      paddb mm0, mm2            // add (Raw/2) to Avg for each byte
+      cmp ebx, MMXLength
+      movq [edi + ebx - 8], mm0
+            movq mm2, mm0       // reuse as Raw(x-bpp)
+      jb davg8lp
+  } // end _asm block
+      }
+      break;
+      default:                  // bpp greater than 8
+      {
+  _asm {
+            movq mm5, LBCarryMask
+            // Re-init address pointers and offset
+            mov ebx, diff       // ebx ==> x = offset to alignment boundary
+            mov edi, row        // edi ==> Avg(x)
+            movq mm4, HBClearMask
+            mov edx, edi
+      mov esi, prev_row         // esi ==> Prior(x)
+            sub edx, bpp        // edx ==> Raw(x-bpp)
+davgAlp:
+      movq mm0, [edi + ebx]
+            movq mm3, mm5
+      movq mm1, [esi + ebx]
+            pand mm3, mm1       // get lsb for each prev_row byte
+      movq mm2, [edx + ebx]
+            psrlq mm1, 1        // divide prev_row bytes by 2
+            pand mm3, mm2       // get LBCarrys for each byte where both
+                                // lsb's were == 1
+            psrlq mm2, 1        // divide raw bytes by 2
+            pand  mm1, mm4      // clear invalid bit 7 of each byte
+            paddb mm0, mm3      // add LBCarrys to Avg for each byte
+            pand  mm2, mm4      // clear invalid bit 7 of each byte
+            paddb mm0, mm1      // add (Prev_row/2) to Avg for each byte
+      add ebx, 8
+      paddb mm0, mm2             // add (Raw/2) to Avg for each byte
+      cmp ebx, MMXLength
+      movq [edi + ebx - 8], mm0
+      jb davgAlp
+  } // end _asm block
+      }
+      break;
+      }                         // end switch ( bpp )
+
+      _asm {
+         // MMX acceleration complete now do clean-up
+         // Check if any remaining bytes left to decode
+   mov ebx, MMXLength           // ebx ==> x = offset bytes remaining after MMX
+     mov edi, row               // edi ==> Avg(x)
+   cmp ebx, FullLength          // Test if offset at end of array
+   jnb davgend
+         // Do Paeth decode for remaining bytes
+     mov esi, prev_row          // esi ==> Prior(x)
+         mov edx, edi
+         xor ecx, ecx           // zero ecx before using cl & cx in loop below
+         sub edx, bpp           // edx ==> Raw(x-bpp)
+davglp2:
+         // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+         xor eax, eax
+   mov cl, [esi + ebx]        // load cl with Prior(x)
+         mov al, [edx + ebx]    // load al with Raw(x-bpp)
+         add ax, cx
+   inc ebx
+         shr ax, 1              // divide by 2
+         add al, [edi+ebx-1]    // Add Avg(x); -1 to offset inc ebx
+   cmp ebx, FullLength        // Check if at end of array
+   mov [edi+ebx-1], al        // Write back Raw(x);
+                          // mov does not affect flags; -1 to offset inc ebx
+   jb davglp2
+davgend:
+   emms                   // End MMX instructions; prep for possible FP instrs.
+   } // end _asm block
+}
+
+// Optimized code for PNG Paeth filter decoder
+void
+png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row
+                            , png_bytep prev_row)
+{
+      png_uint_32 FullLength;
+      png_uint_32 MMXLength;
+      //png_uint_32 len;
+      int bpp;
+      int diff;
+      //int ptemp;
+      int patemp, pbtemp, pctemp;
+      bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+      FullLength  = row_info->rowbytes; // # of bytes to filter
+      _asm {
+         xor ebx, ebx                  // ebx ==> x offset
+   mov edi, row
+         xor edx, edx                  // edx ==> x-bpp offset
+   mov esi, prev_row
+         xor eax, eax
+
+     // Compute the Raw value for the first bpp bytes
+     // Note: the formula works out to always be Paeth(x) = Raw(x) + Prior(x)
+     //        where x < bpp
+dpthrlp:
+         mov al, [edi + ebx]
+         add al, [esi + ebx]
+         inc ebx
+         cmp ebx, bpp
+         mov [edi + ebx - 1], al
+         jb dpthrlp
+         // get # of bytes to alignment
+         mov diff, edi         // take start of row
+         add diff, ebx         // add bpp
+   xor ecx, ecx
+         add diff, 0xf         // add 7 + 8 to incr past alignment boundary
+         and diff, 0xfffffff8  // mask to alignment boundary
+         sub diff, edi         // subtract from start ==> value ebx at alignment
+         jz dpthgo
+         // fix alignment
+dpthlp1:
+         xor eax, eax
+         // pav = p - a = (a + b - c) - a = b - c
+         mov al, [esi + ebx]   // load Prior(x) into al
+         mov cl, [esi + edx]   // load Prior(x-bpp) into cl
+         sub eax, ecx          // subtract Prior(x-bpp)
+         mov patemp, eax       // Save pav for later use
+         xor eax, eax
+         // pbv = p - b = (a + b - c) - b = a - c
+         mov al, [edi + edx]   // load Raw(x-bpp) into al
+         sub eax, ecx          // subtract Prior(x-bpp)
+         mov ecx, eax
+         // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+         add eax, patemp       // pcv = pav + pbv
+         // pc = abs(pcv)
+         test eax, 0x80000000
+         jz dpthpca
+         neg eax               // reverse sign of neg values
+dpthpca:
+         mov pctemp, eax       // save pc for later use
+         // pb = abs(pbv)
+         test ecx, 0x80000000
+         jz dpthpba
+         neg ecx               // reverse sign of neg values
+dpthpba:
+         mov pbtemp, ecx       // save pb for later use
+         // pa = abs(pav)
+         mov eax, patemp
+         test eax, 0x80000000
+         jz dpthpaa
+         neg eax               // reverse sign of neg values
+dpthpaa:
+         mov patemp, eax       // save pa for later use
+         // test if pa <= pb
+         cmp eax, ecx
+         jna dpthabb
+         // pa > pb; now test if pb <= pc
+         cmp ecx, pctemp
+         jna dpthbbc
+         // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+         mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+         jmp dpthpaeth
+dpthbbc:
+         // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+         mov cl, [esi + ebx]   // load Prior(x) into cl
+         jmp dpthpaeth
+dpthabb:
+         // pa <= pb; now test if pa <= pc
+         cmp eax, pctemp
+         jna dpthabc
+         // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+         mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+         jmp dpthpaeth
+dpthabc:
+         // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+         mov cl, [edi + edx]  // load Raw(x-bpp) into cl
+dpthpaeth:
+   inc ebx
+   inc edx
+         // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+         add [edi + ebx - 1], cl
+   cmp ebx, diff
+   jb dpthlp1
+dpthgo:
+    mov ecx, FullLength
+         mov eax, ecx
+         sub eax, ebx          // subtract alignment fix
+         and eax, 0x00000007   // calc bytes over mult of 8
+         sub ecx, eax          // drop over bytes from original length
+         mov MMXLength, ecx
+     } // end _asm block
+      // Now do the math for the rest of the row
+      switch ( bpp )
+      {
+      case 3:
+      {
+         ActiveMask.use = 0x0000000000ffffff;
+         ActiveMaskEnd.use = 0xffff000000000000;
+         ShiftBpp.use = 24;    // == bpp(3) * 8
+         ShiftRem.use = 40;    // == 64 - 24
+      _asm {
+            mov ebx, diff
+         mov edi, row
+         mov esi, prev_row
+            pxor mm0, mm0
+            // PRIME the pump (load the first Raw(x-bpp) data set
+            movq mm1, [edi+ebx-8]
+dpth3lp:
+            psrlq mm1, ShiftRem     // shift last 3 bytes to 1st 3 bytes
+            movq mm2, [esi + ebx]   // load b=Prior(x)
+            punpcklbw mm1, mm0      // Unpack High bytes of a
+            movq mm3, [esi+ebx-8]   // Prep c=Prior(x-bpp) bytes
+            punpcklbw mm2, mm0      // Unpack High bytes of b
+            psrlq mm3, ShiftRem     // shift last 3 bytes to 1st 3 bytes
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            punpcklbw mm3, mm0      // Unpack High bytes of c
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4        // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4           // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5        // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5           // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6        // Create mask pcv bytes < 0
+            pand mm0, mm6           // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5        // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            paddw mm7, mm3
+            pxor mm0, mm0
+            packuswb mm7, mm1
+            movq mm3, [esi + ebx]   // load c=Prior(x-bpp)
+            pand mm7, ActiveMask
+            movq mm2, mm3           // load b=Prior(x) step 1
+            paddb mm7, [edi + ebx]  // add Paeth predictor with Raw(x)
+            punpcklbw mm3, mm0      // Unpack High bytes of c
+            movq [edi + ebx], mm7   // write back updated value
+            movq mm1, mm7           // Now mm1 will be used as Raw(x-bpp)
+            // Now do Paeth for 2nd set of bytes (3-5)
+            psrlq mm2, ShiftBpp     // load b=Prior(x) step 2
+            punpcklbw mm1, mm0      // Unpack High bytes of a
+            pxor mm7, mm7
+            punpcklbw mm2, mm0      // Unpack High bytes of b
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            psubw mm5, mm3
+            psubw mm4, mm3
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) =
+            //       pav + pbv = pbv + pav
+            movq mm6, mm5
+            paddw mm6, mm4
+
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm5           // Create mask pbv bytes < 0
+            pcmpgtw mm7, mm4           // Create mask pav bytes < 0
+            pand mm0, mm5              // Only pbv bytes < 0 in mm0
+            pand mm7, mm4              // Only pav bytes < 0 in mm7
+            psubw mm5, mm0
+            psubw mm4, mm7
+            psubw mm5, mm0
+            psubw mm4, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            movq mm2, [esi + ebx]      // load b=Prior(x)
+            pand mm3, mm7
+            pandn mm7, mm0
+            pxor mm1, mm1
+            paddw mm7, mm3
+            pxor mm0, mm0
+            packuswb mm7, mm1
+            movq mm3, mm2           // load c=Prior(x-bpp) step 1
+            pand mm7, ActiveMask
+            punpckhbw mm2, mm0      // Unpack High bytes of b
+            psllq mm7, ShiftBpp     // Shift bytes to 2nd group of 3 bytes
+             // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            paddb mm7, [edi + ebx]  // add Paeth predictor with Raw(x)
+            psllq mm3, ShiftBpp     // load c=Prior(x-bpp) step 2
+            movq [edi + ebx], mm7   // write back updated value
+            movq mm1, mm7
+            punpckhbw mm3, mm0      // Unpack High bytes of c
+            psllq mm1, ShiftBpp     // Shift bytes
+                                    // Now mm1 will be used as Raw(x-bpp)
+            // Now do Paeth for 3rd, and final, set of bytes (6-7)
+            pxor mm7, mm7
+            punpckhbw mm1, mm0      // Unpack High bytes of a
+            psubw mm4, mm3
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            pxor mm0, mm0
+            paddw mm6, mm5
+
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4        // Create mask pav bytes < 0
+            pcmpgtw mm7, mm5        // Create mask pbv bytes < 0
+            pand mm0, mm4           // Only pav bytes < 0 in mm7
+            pand mm7, mm5           // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6        // Create mask pcv bytes < 0
+            pand mm0, mm6           // Only pav bytes < 0 in mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5        // pa > pb?
+            movq mm0, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            pandn mm0, mm1
+            pandn mm7, mm4
+            paddw mm0, mm2
+            paddw mm7, mm5
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6        // pab > pc?
+            pand mm3, mm7
+            pandn mm7, mm0
+            paddw mm7, mm3
+            pxor mm1, mm1
+            packuswb mm1, mm7
+            // Step ebx to next set of 8 bytes and repeat loop til done
+      add ebx, 8
+            pand mm1, ActiveMaskEnd
+            paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
+
+      cmp ebx, MMXLength
+            pxor mm0, mm0              // pxor does not affect flags
+            movq [edi + ebx - 8], mm1  // write back updated value
+                                 // mm1 will be used as Raw(x-bpp) next loop
+                           // mm3 ready to be used as Prior(x-bpp) next loop
+      jb dpth3lp
+  } // end _asm block
+      }
+      break;
+      case 6:
+      case 7:
+      case 5:
+      {
+         ActiveMask.use  = 0x00000000ffffffff;
+         ActiveMask2.use = 0xffffffff00000000;
+         ShiftBpp.use = bpp << 3;    // == bpp * 8
+         ShiftRem.use = 64 - ShiftBpp.use;
+    _asm {
+            mov ebx, diff
+         mov edi, row               //
+         mov esi, prev_row
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm1, [edi+ebx-8]
+            pxor mm0, mm0
+dpth6lp:
+            // Must shift to position Raw(x-bpp) data
+            psrlq mm1, ShiftRem
+            // Do first set of 4 bytes
+      movq mm3, [esi+ebx-8]      // read c=Prior(x-bpp) bytes
+            punpcklbw mm1, mm0      // Unpack Low bytes of a
+            movq mm2, [esi + ebx]   // load b=Prior(x)
+            punpcklbw mm2, mm0      // Unpack Low bytes of b
+            // Must shift to position Prior(x-bpp) data
+            psrlq mm3, ShiftRem
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            punpcklbw mm3, mm0      // Unpack Low bytes of c
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4        // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4           // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5        // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5           // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6        // Create mask pcv bytes < 0
+            pand mm0, mm6           // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5        // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6        // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            paddw mm7, mm3
+            pxor mm0, mm0
+            packuswb mm7, mm1
+            movq mm3, [esi + ebx - 8]  // load c=Prior(x-bpp)
+            pand mm7, ActiveMask
+            psrlq mm3, ShiftRem
+            movq mm2, [esi + ebx]      // load b=Prior(x) step 1
+            paddb mm7, [edi + ebx]     // add Paeth predictor with Raw(x)
+            movq mm6, mm2
+            movq [edi + ebx], mm7      // write back updated value
+        movq mm1, [edi+ebx-8]
+            psllq mm6, ShiftBpp
+            movq mm5, mm7
+            psrlq mm1, ShiftRem
+            por mm3, mm6
+            psllq mm5, ShiftBpp
+            punpckhbw mm3, mm0         // Unpack High bytes of c
+            por mm1, mm5
+            // Do second set of 4 bytes
+            punpckhbw mm2, mm0         // Unpack High bytes of b
+            punpckhbw mm1, mm0         // Unpack High bytes of a
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4           // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4              // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5           // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5              // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            pxor mm1, mm1
+            paddw mm7, mm3
+            pxor mm0, mm0
+            // Step ex to next set of 8 bytes and repeat loop til done
+      add ebx, 8
+            packuswb mm1, mm7
+            paddb mm1, [edi + ebx - 8]     // add Paeth predictor with Raw(x)
+      cmp ebx, MMXLength
+            movq [edi + ebx - 8], mm1      // write back updated value
+                                // mm1 will be used as Raw(x-bpp) next loop
+      jb dpth6lp
+  } // end _asm block
+      }
+      break;
+      case 4:
+      {
+         ActiveMask.use  = 0x00000000ffffffff;
+  _asm {
+            mov ebx, diff
+         mov edi, row               //
+         mov esi, prev_row
+            pxor mm0, mm0
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm1, [edi+ebx-8] // Only time should need to read a=Raw(x-bpp) bytes
+dpth4lp:
+            // Do first set of 4 bytes
+          movq mm3, [esi+ebx-8]      // read c=Prior(x-bpp) bytes
+            punpckhbw mm1, mm0       // Unpack Low bytes of a
+            movq mm2, [esi + ebx]    // load b=Prior(x)
+            punpcklbw mm2, mm0       // Unpack High bytes of b
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            punpckhbw mm3, mm0       // Unpack High bytes of c
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4           // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4              // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5           // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5              // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            paddw mm7, mm3
+            pxor mm0, mm0
+            packuswb mm7, mm1
+            movq mm3, [esi + ebx]      // load c=Prior(x-bpp)
+            pand mm7, ActiveMask
+            movq mm2, mm3              // load b=Prior(x) step 1
+            paddb mm7, [edi + ebx]     // add Paeth predictor with Raw(x)
+            punpcklbw mm3, mm0         // Unpack High bytes of c
+            movq [edi + ebx], mm7      // write back updated value
+            movq mm1, mm7              // Now mm1 will be used as Raw(x-bpp)
+            // Do second set of 4 bytes
+            punpckhbw mm2, mm0         // Unpack Low bytes of b
+            punpcklbw mm1, mm0         // Unpack Low bytes of a
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4           // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4              // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5           // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5              // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            pxor mm1, mm1
+            paddw mm7, mm3
+            pxor mm0, mm0
+            // Step ex to next set of 8 bytes and repeat loop til done
+        add ebx, 8
+            packuswb mm1, mm7
+            paddb mm1, [edi + ebx - 8]     // add Paeth predictor with Raw(x)
+      cmp ebx, MMXLength
+            movq [edi + ebx - 8], mm1      // write back updated value
+                                // mm1 will be used as Raw(x-bpp) next loop
+      jb dpth4lp
+  } // end _asm block
+      }
+      break;
+      case 8:                          // bpp == 8
+      {
+         ActiveMask.use  = 0x00000000ffffffff;
+   _asm {
+            mov ebx, diff
+         mov edi, row               //
+         mov esi, prev_row
+            pxor mm0, mm0
+            // PRIME the pump (load the first Raw(x-bpp) data set
+      movq mm1, [edi+ebx-8] // Only time should need to read a=Raw(x-bpp) bytes
+dpth8lp:
+            // Do first set of 4 bytes
+      movq mm3, [esi+ebx-8]      // read c=Prior(x-bpp) bytes
+            punpcklbw mm1, mm0         // Unpack Low bytes of a
+            movq mm2, [esi + ebx]      // load b=Prior(x)
+            punpcklbw mm2, mm0         // Unpack Low bytes of b
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            punpcklbw mm3, mm0         // Unpack Low bytes of c
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4           // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4              // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5           // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5              // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            paddw mm7, mm3
+            pxor mm0, mm0
+            packuswb mm7, mm1
+        movq mm3, [esi+ebx-8]    // read c=Prior(x-bpp) bytes
+            pand mm7, ActiveMask
+            movq mm2, [esi + ebx]      // load b=Prior(x)
+            paddb mm7, [edi + ebx]     // add Paeth predictor with Raw(x)
+            punpckhbw mm3, mm0         // Unpack High bytes of c
+            movq [edi + ebx], mm7      // write back updated value
+        movq mm1, [edi+ebx-8]    // read a=Raw(x-bpp) bytes
+
+            // Do second set of 4 bytes
+            punpckhbw mm2, mm0         // Unpack High bytes of b
+            punpckhbw mm1, mm0         // Unpack High bytes of a
+            // pav = p - a = (a + b - c) - a = b - c
+            movq mm4, mm2
+            // pbv = p - b = (a + b - c) - b = a - c
+            movq mm5, mm1
+            psubw mm4, mm3
+            pxor mm7, mm7
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            movq mm6, mm4
+            psubw mm5, mm3
+            // pa = abs(p-a) = abs(pav)
+            // pb = abs(p-b) = abs(pbv)
+            // pc = abs(p-c) = abs(pcv)
+            pcmpgtw mm0, mm4           // Create mask pav bytes < 0
+            paddw mm6, mm5
+            pand mm0, mm4              // Only pav bytes < 0 in mm7
+            pcmpgtw mm7, mm5           // Create mask pbv bytes < 0
+            psubw mm4, mm0
+            pand mm7, mm5              // Only pbv bytes < 0 in mm0
+            psubw mm4, mm0
+            psubw mm5, mm7
+            pxor mm0, mm0
+            pcmpgtw mm0, mm6           // Create mask pcv bytes < 0
+            pand mm0, mm6              // Only pav bytes < 0 in mm7
+            psubw mm5, mm7
+            psubw mm6, mm0
+            //  test pa <= pb
+            movq mm7, mm4
+            psubw mm6, mm0
+            pcmpgtw mm7, mm5           // pa > pb?
+            movq mm0, mm7
+            // use mm7 mask to merge pa & pb
+            pand mm5, mm7
+            // use mm0 mask copy to merge a & b
+            pand mm2, mm0
+            pandn mm7, mm4
+            pandn mm0, mm1
+            paddw mm7, mm5
+            paddw mm0, mm2
+            //  test  ((pa <= pb)? pa:pb) <= pc
+            pcmpgtw mm7, mm6           // pab > pc?
+            pxor mm1, mm1
+            pand mm3, mm7
+            pandn mm7, mm0
+            pxor mm1, mm1
+            paddw mm7, mm3
+            pxor mm0, mm0
+            // Step ex to next set of 8 bytes and repeat loop til done
+        add ebx, 8
+            packuswb mm1, mm7
+            paddb mm1, [edi + ebx - 8]     // add Paeth predictor with Raw(x)
+        cmp ebx, MMXLength
+            movq [edi + ebx - 8], mm1      // write back updated value
+                            // mm1 will be used as Raw(x-bpp) next loop
+        jb dpth8lp
+      } // end _asm block
+      }
+      break;
+      case 1:                          // bpp = 1
+      case 2:                          // bpp = 2
+      default:                         // bpp > 8
+      {
+   _asm {
+      mov ebx, diff
+      cmp ebx, FullLength
+      jnb dpthdend
+        mov edi, row               //
+        mov esi, prev_row
+            // Do Paeth decode for remaining bytes
+            mov edx, ebx
+            xor ecx, ecx        // zero ecx before using cl & cx in loop below
+            sub edx, bpp        // Set edx = ebx - bpp
+dpthdlp:
+            xor eax, eax
+            // pav = p - a = (a + b - c) - a = b - c
+            mov al, [esi + ebx]        // load Prior(x) into al
+            mov cl, [esi + edx]        // load Prior(x-bpp) into cl
+            sub eax, ecx                 // subtract Prior(x-bpp)
+            mov patemp, eax                 // Save pav for later use
+            xor eax, eax
+            // pbv = p - b = (a + b - c) - b = a - c
+            mov al, [edi + edx]        // load Raw(x-bpp) into al
+            sub eax, ecx                 // subtract Prior(x-bpp)
+            mov ecx, eax
+            // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+            add eax, patemp                 // pcv = pav + pbv
+            // pc = abs(pcv)
+            test eax, 0x80000000
+            jz dpthdpca
+            neg eax                     // reverse sign of neg values
+dpthdpca:
+            mov pctemp, eax             // save pc for later use
+            // pb = abs(pbv)
+            test ecx, 0x80000000
+            jz dpthdpba
+            neg ecx                     // reverse sign of neg values
+dpthdpba:
+            mov pbtemp, ecx             // save pb for later use
+            // pa = abs(pav)
+            mov eax, patemp
+            test eax, 0x80000000
+            jz dpthdpaa
+            neg eax                     // reverse sign of neg values
+dpthdpaa:
+            mov patemp, eax             // save pa for later use
+            // test if pa <= pb
+            cmp eax, ecx
+            jna dpthdabb
+            // pa > pb; now test if pb <= pc
+            cmp ecx, pctemp
+            jna dpthdbbc
+            // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+            mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+            jmp dpthdpaeth
+dpthdbbc:
+            // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+            mov cl, [esi + ebx]        // load Prior(x) into cl
+            jmp dpthdpaeth
+dpthdabb:
+            // pa <= pb; now test if pa <= pc
+            cmp eax, pctemp
+            jna dpthdabc
+            // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+            mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+            jmp dpthdpaeth
+dpthdabc:
+            // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+            mov cl, [edi + edx]  // load Raw(x-bpp) into cl
+dpthdpaeth:
+      inc ebx
+      inc edx
+            // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+            add [edi + ebx - 1], cl
+      cmp ebx, FullLength
+      jb dpthdlp
+dpthdend:
+        } // end _asm block
+      }
+      return;                   // No need to go further with this one
+      }                         // end switch ( bpp )
+      _asm {
+         // MMX acceleration complete now do clean-up
+         // Check if any remaining bytes left to decode
+   mov ebx, MMXLength
+   cmp ebx, FullLength
+   jnb dpthend
+     mov edi, row
+     mov esi, prev_row
+         // Do Paeth decode for remaining bytes
+         mov edx, ebx
+         xor ecx, ecx         // zero ecx before using cl & cx in loop below
+         sub edx, bpp         // Set edx = ebx - bpp
+dpthlp2:
+         xor eax, eax
+         // pav = p - a = (a + b - c) - a = b - c
+         mov al, [esi + ebx]  // load Prior(x) into al
+         mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+         sub eax, ecx         // subtract Prior(x-bpp)
+         mov patemp, eax      // Save pav for later use
+         xor eax, eax
+         // pbv = p - b = (a + b - c) - b = a - c
+         mov al, [edi + edx]  // load Raw(x-bpp) into al
+         sub eax, ecx         // subtract Prior(x-bpp)
+         mov ecx, eax
+         // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+         add eax, patemp      // pcv = pav + pbv
+         // pc = abs(pcv)
+         test eax, 0x80000000
+         jz dpthpca2
+         neg eax              // reverse sign of neg values
+dpthpca2:
+         mov pctemp, eax      // save pc for later use
+         // pb = abs(pbv)
+         test ecx, 0x80000000
+         jz dpthpba2
+         neg ecx              // reverse sign of neg values
+dpthpba2:
+         mov pbtemp, ecx      // save pb for later use
+         // pa = abs(pav)
+         mov eax, patemp
+         test eax, 0x80000000
+         jz dpthpaa2
+         neg eax              // reverse sign of neg values
+dpthpaa2:
+         mov patemp, eax      // save pa for later use
+         // test if pa <= pb
+         cmp eax, ecx
+         jna dpthabb2
+         // pa > pb; now test if pb <= pc
+         cmp ecx, pctemp
+         jna dpthbbc2
+         // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+         mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+         jmp dpthpaeth2
+dpthbbc2:
+         // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+         mov cl, [esi + ebx]        // load Prior(x) into cl
+         jmp dpthpaeth2
+dpthabb2:
+         // pa <= pb; now test if pa <= pc
+         cmp eax, pctemp
+         jna dpthabc2
+         // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+         mov cl, [esi + edx]  // load Prior(x-bpp) into cl
+         jmp dpthpaeth2
+dpthabc2:
+         // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+         mov cl, [edi + edx]  // load Raw(x-bpp) into cl
+dpthpaeth2:
+      inc ebx
+      inc edx
+         // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+         add [edi + ebx - 1], cl
+      cmp ebx, FullLength
+      jb dpthlp2
+dpthend:
+      emms             // End MMX instructions; prep for possible FP instrs.
+     } // end _asm block
+}
+
+// Optimized code for PNG Sub filter decoder
+void
+png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
+{
+    //int test;
+      int bpp;
+    png_uint_32 FullLength;
+    png_uint_32 MMXLength;
+    int diff;
+      bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+    FullLength  = row_info->rowbytes - bpp; // # of bytes to filter
+    _asm {
+        mov edi, row
+        mov esi, edi               // lp = row
+            add edi, bpp               // rp = row + bpp
+            xor eax, eax
+            // get # of bytes to alignment
+            mov diff, edi               // take start of row
+            add diff, 0xf               // add 7 + 8 to incr past
+                                        // alignment boundary
+            xor ebx, ebx
+            and diff, 0xfffffff8        // mask to alignment boundary
+            sub diff, edi               // subtract from start ==> value
+                                        //  ebx at alignment
+            jz dsubgo
+            // fix alignment
+dsublp1:
+         mov al, [esi+ebx]
+         add [edi+ebx], al
+          inc ebx
+          cmp ebx, diff
+         jb dsublp1
+dsubgo:
+         mov ecx, FullLength
+            mov edx, ecx
+            sub edx, ebx                  // subtract alignment fix
+            and edx, 0x00000007           // calc bytes over mult of 8
+            sub ecx, edx                  // drop over bytes from length
+            mov MMXLength, ecx
+     } // end _asm block
+      // Now do the math for the rest of the row
+      switch ( bpp )
+      {
+      case 3:
+    {
+         ActiveMask.use  = 0x0000ffffff000000;
+         ShiftBpp.use = 24;       // == 3 * 8
+         ShiftRem.use  = 40;      // == 64 - 24
+      _asm {
+            mov edi, row
+            movq mm7, ActiveMask  // Load ActiveMask for 2nd active byte group
+        mov esi, edi              // lp = row
+            add edi, bpp          // rp = row + bpp
+            movq mm6, mm7
+            mov ebx, diff
+            psllq mm6, ShiftBpp   // Move mask in mm6 to cover 3rd active
+                                  // byte group
+            // PRIME the pump (load the first Raw(x-bpp) data set
+            movq mm1, [edi+ebx-8]
+dsub3lp:
+            psrlq mm1, ShiftRem   // Shift data for adding 1st bpp bytes
+                          // no need for mask; shift clears inactive bytes
+            // Add 1st active group
+            movq mm0, [edi+ebx]
+        paddb mm0, mm1
+            // Add 2nd active group
+            movq mm1, mm0         // mov updated Raws to mm1
+            psllq mm1, ShiftBpp   // shift data to position correctly
+            pand mm1, mm7         // mask to use only 2nd active group
+        paddb mm0, mm1
+            // Add 3rd active group
+            movq mm1, mm0         // mov updated Raws to mm1
+            psllq mm1, ShiftBpp   // shift data to position correctly
+            pand mm1, mm6         // mask to use only 3rd active group
+        add ebx, 8
+        paddb mm0, mm1
+        cmp ebx, MMXLength
+        movq [edi+ebx-8], mm0     // Write updated Raws back to array
+            // Prep for doing 1st add at top of loop
+            movq mm1, mm0
+        jb dsub3lp
+      } // end _asm block
+      }
+      break;
+      case 1:
+    {
+      /* Placed here just in case this is a duplicate of the
+      non-MMX code for the SUB filter in png_read_filter_row
+                        above
+      */
+//         png_bytep rp;
+//         png_bytep lp;
+//         png_uint_32 i;
+//         bpp = (row_info->pixel_depth + 7) >> 3;
+//         for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
+//            i < row_info->rowbytes; i++, rp++, lp++)
+//      {
+//            *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
+//      }
+      _asm {
+            mov ebx, diff
+            mov edi, row
+        cmp ebx, FullLength
+        jnb dsub1end
+        mov esi, edi          // lp = row
+        xor eax, eax
+            add edi, bpp      // rp = row + bpp
+dsub1lp:
+        mov al, [esi+ebx]
+        add [edi+ebx], al
+          inc ebx
+          cmp ebx, FullLength
+        jb dsub1lp
+dsub1end:
+      } // end _asm block
+    }
+      return;
+      case 6:
+      case 7:
+      case 4:
+      case 5:
+    {
+         ShiftBpp.use = bpp << 3;
+         ShiftRem.use = 64 - ShiftBpp.use;
+      _asm {
+            mov edi, row
+            mov ebx, diff
+        mov esi, edi               // lp = row
+            add edi, bpp           // rp = row + bpp
+            // PRIME the pump (load the first Raw(x-bpp) data set
+            movq mm1, [edi+ebx-8]
+dsub4lp:
+            psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
+                          // no need for mask; shift clears inactive bytes
+        movq mm0, [edi+ebx]
+        paddb mm0, mm1
+            // Add 2nd active group
+            movq mm1, mm0          // mov updated Raws to mm1
+            psllq mm1, ShiftBpp    // shift data to position correctly
+                                   // there is no need for any mask
+                                   // since shift clears inactive bits/bytes
+        add ebx, 8
+        paddb mm0, mm1
+        cmp ebx, MMXLength
+        movq [edi+ebx-8], mm0
+            movq mm1, mm0          // Prep for doing 1st add at top of loop
+        jb dsub4lp
+      } // end _asm block
+      }
+      break;
+      case 2:
+    {
+         ActiveMask.use  = 0x00000000ffff0000;
+         ShiftBpp.use = 16;       // == 2 * 8
+         ShiftRem.use = 48;       // == 64 - 16
+      _asm {
+            movq mm7, ActiveMask  // Load ActiveMask for 2nd active byte group
+            mov ebx, diff
+            movq mm6, mm7
+        mov edi, row
+            psllq mm6, ShiftBpp // Move mask in mm6 to cover 3rd active byte group
+        mov esi, edi            // lp = row
+            movq mm5, mm6
+            add edi, bpp        // rp = row + bpp
+            psllq mm5, ShiftBpp // Move mask in mm5 to cover 4th active byte group
+            // PRIME the pump (load the first Raw(x-bpp) data set
+            movq mm1, [edi+ebx-8]
+dsub2lp:
+            // Add 1st active group
+            psrlq mm1, ShiftRem    // Shift data for adding 1st bpp bytes
+                                 // no need for mask; shift clears inactive bytes
+            movq mm0, [edi+ebx]
+        paddb mm0, mm1
+            // Add 2nd active group
+            movq mm1, mm0              // mov updated Raws to mm1
+            psllq mm1, ShiftBpp      // shift data to position correctly
+            pand mm1, mm7              // mask to use only 2nd active group
+        paddb mm0, mm1
+            // Add 3rd active group
+            movq mm1, mm0              // mov updated Raws to mm1
+            psllq mm1, ShiftBpp      // shift data to position correctly
+            pand mm1, mm6              // mask to use only 3rd active group
+        paddb mm0, mm1
+            // Add 4th active group
+            movq mm1, mm0              // mov updated Raws to mm1
+            psllq mm1, ShiftBpp      // shift data to position correctly
+            pand mm1, mm5              // mask to use only 4th active group
+        add ebx, 8
+        paddb mm0, mm1
+        cmp ebx, MMXLength
+        movq [edi+ebx-8], mm0        // Write updated Raws back to array
+            movq mm1, mm0            // Prep for doing 1st add at top of loop
+        jb dsub2lp
+      } // end _asm block
+      }
+      break;
+      case 8:
+    {
+      _asm {
+        mov edi, row
+            mov ebx, diff
+        mov esi, edi               // lp = row
+            add edi, bpp             // rp = row + bpp
+         mov ecx, MMXLength
+            movq mm7, [edi+ebx-8]   // PRIME the pump (load the first
+                                    // Raw(x-bpp) data set
+            and ecx, 0x0000003f     // calc bytes over mult of 64
+dsub8lp:
+        movq mm0, [edi+ebx]         // Load Sub(x) for 1st 8 bytes
+        paddb mm0, mm7
+               movq mm1, [edi+ebx+8]   // Load Sub(x) for 2nd 8 bytes
+        movq [edi+ebx], mm0        // Write Raw(x) for 1st 8 bytes
+                                   // Now mm0 will be used as Raw(x-bpp) for
+                                   // the 2nd group of 8 bytes.  This will be
+                                   // repeated for each group of 8 bytes with
+                                   // the 8th group being used as the Raw(x-bpp)
+                                   // for the 1st group of the next loop.
+        paddb mm1, mm0
+        movq mm2, [edi+ebx+16]      // Load Sub(x) for 3rd 8 bytes
+        movq [edi+ebx+8], mm1      // Write Raw(x) for 2nd 8 bytes
+        paddb mm2, mm1
+        movq mm3, [edi+ebx+24]      // Load Sub(x) for 4th 8 bytes
+        movq [edi+ebx+16], mm2      // Write Raw(x) for 3rd 8 bytes
+        paddb mm3, mm2
+        movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes
+        movq [edi+ebx+24], mm3      // Write Raw(x) for 4th 8 bytes
+        paddb mm4, mm3
+        movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes
+        movq [edi+ebx+32], mm4      // Write Raw(x) for 5th 8 bytes
+        paddb mm5, mm4
+        movq mm6, [edi+ebx+48]  // Load Sub(x) for 7th 8 bytes
+        movq [edi+ebx+40], mm5      // Write Raw(x) for 6th 8 bytes
+        paddb mm6, mm5
+        movq mm7, [edi+ebx+56]      // Load Sub(x) for 8th 8 bytes
+        movq [edi+ebx+48], mm6      // Write Raw(x) for 7th 8 bytes
+        add ebx, 64
+        paddb mm7, mm6
+        cmp ebx, ecx
+        movq [edi+ebx-8], mm7      // Write Raw(x) for 8th 8 bytes
+        jb dsub8lp
+        cmp ebx, MMXLength
+        jnb dsub8lt8
+dsub8lpA:
+            movq mm0, [edi+ebx]
+        add ebx, 8
+        paddb mm0, mm7
+        cmp ebx, MMXLength
+        movq [edi+ebx-8], mm0   // use -8 to offset early add to ebx
+            movq mm7, mm0       // Move calculated Raw(x) data to mm1 to
+                                // be the new Raw(x-bpp) for the next loop
+        jb dsub8lpA
+dsub8lt8:
+      } // end _asm block
+      }
+      break;
+      default:                // bpp greater than 8 bytes
+    {
+      _asm {
+            mov ebx, diff
+        mov edi, row
+        mov esi, edi               // lp = row
+            add edi, bpp           // rp = row + bpp
+dsubAlp:
+        movq mm0, [edi+ebx]
+        movq mm1, [esi+ebx]
+        add ebx, 8
+        paddb mm0, mm1
+        cmp ebx, MMXLength
+        movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset add ebx
+        jb dsubAlp
+      } // end _asm block
+      }
+      break;
+      }                                // end switch ( bpp )
+
+      _asm {
+            mov ebx, MMXLength
+            mov edi, row
+        cmp ebx, FullLength
+        jnb dsubend
+        mov esi, edi               // lp = row
+        xor eax, eax
+            add edi, bpp           // rp = row + bpp
+dsublp2:
+        mov al, [esi+ebx]
+        add [edi+ebx], al
+          inc ebx
+          cmp ebx, FullLength
+        jb dsublp2
+dsubend:
+         emms             // End MMX instructions; prep for possible FP instrs.
+    } // end _asm block
+}
+
+// Optimized code for PNG Up filter decoder
+void
+png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
+   png_bytep prev_row)
+{
+      png_uint_32 len;
+    len  = row_info->rowbytes;       // # of bytes to filter
+    _asm {
+      mov edi, row
+         // get # of bytes to alignment
+         mov ecx, edi
+       xor ebx, ebx
+         add ecx, 0x7
+         xor eax, eax
+         and ecx, 0xfffffff8
+      mov esi, prev_row
+         sub ecx, edi
+         jz dupgo
+         // fix alignment
+duplp1:
+      mov al, [edi+ebx]
+      add al, [esi+ebx]
+      inc ebx
+      cmp ebx, ecx
+      mov [edi + ebx-1], al  // mov does not affect flags; -1 to offset inc ebx
+      jb duplp1
+dupgo:
+      mov ecx, len
+         mov edx, ecx
+         sub edx, ebx                  // subtract alignment fix
+         and edx, 0x0000003f           // calc bytes over mult of 64
+         sub ecx, edx                  // drop over bytes from length
+         // Unrolled loop - use all MMX registers and interleave to reduce
+         // number of branch instructions (loops) and reduce partial stalls
+duploop:
+      movq mm1, [esi+ebx]
+      movq mm0, [edi+ebx]
+          movq mm3, [esi+ebx+8]
+      paddb mm0, mm1
+          movq mm2, [edi+ebx+8]
+      movq [edi+ebx], mm0
+          paddb mm2, mm3
+            movq mm5, [esi+ebx+16]
+          movq [edi+ebx+8], mm2
+            movq mm4, [edi+ebx+16]
+               movq mm7, [esi+ebx+24]
+            paddb mm4, mm5
+               movq mm6, [edi+ebx+24]
+            movq [edi+ebx+16], mm4
+               paddb mm6, mm7
+      movq mm1, [esi+ebx+32]
+               movq [edi+ebx+24], mm6
+      movq mm0, [edi+ebx+32]
+         movq mm3, [esi+ebx+40]
+      paddb mm0, mm1
+         movq mm2, [edi+ebx+40]
+      movq [edi+ebx+32], mm0
+         paddb mm2, mm3
+            movq mm5, [esi+ebx+48]
+         movq [edi+ebx+40], mm2
+            movq mm4, [edi+ebx+48]
+               movq mm7, [esi+ebx+56]
+            paddb mm4, mm5
+               movq mm6, [edi+ebx+56]
+            movq [edi+ebx+48], mm4
+         add ebx, 64
+               paddb mm6, mm7
+      cmp ebx, ecx
+               movq [edi+ebx-8], mm6 // (+56)movq does not affect flags;
+                                     // -8 to offset add ebx
+      jb duploop
+
+      cmp edx, 0                     // Test for bytes over mult of 64
+      jz dupend
+
+
+         // 2 lines added by lcreeve@netins.net
+         // (mail 11 Jul 98 in png-implement list)
+         cmp edx, 8 //test for less than 8 bytes
+         jb duplt8
+
+
+         add ecx, edx
+         and edx, 0x00000007           // calc bytes over mult of 8
+         sub ecx, edx                  // drop over bytes from length
+      jz duplt8
+         // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously
+duplpA:
+      movq mm1, [esi+ebx]
+      movq mm0, [edi+ebx]
+      add ebx, 8
+      paddb mm0, mm1
+      cmp ebx, ecx
+      movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx
+      jb duplpA
+      cmp edx, 0            // Test for bytes over mult of 8
+      jz dupend
+duplt8:
+         xor eax, eax
+      add ecx, edx          // move over byte count into counter
+         // Loop using x86 registers to update remaining bytes
+duplp2:
+      mov al, [edi + ebx]
+      add al, [esi + ebx]
+      inc ebx
+      cmp ebx, ecx
+      mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx
+      jb duplp2
+dupend:
+         // Conversion of filtered row completed
+      emms          // End MMX instructions; prep for possible FP instrs.
+    } // end _asm block
+}
+
+
+
+// Optimized png_read_filter_row routines
+void
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
+   row, png_bytep prev_row, int filter)
+{
+   char filnm[6];
+   #define UseMMX (1)
+
+
+   if (mmx_supported==2)
+       mmx_supported=mmxsupport();
+   //if (!mmx_supported)
+   {
+       png_read_filter_row_c(png_ptr, row_info, row, prev_row, filter);
+       return ;
+   }
+
+
+   png_debug(1, "in png_read_filter_row\n");
+   png_debug1(0,"%s, ", (UseMMX?"MMX":"x86"));
+   switch (filter)
+   {
+   case 0: sprintf(filnm, "None ");
+      break;
+   case 1: sprintf(filnm, "Sub  ");
+      break;
+   case 2: sprintf(filnm, "Up   ");
+      break;
+   case 3: sprintf(filnm, "Avg  ");
+      break;
+   case 4: sprintf(filnm, "Paeth");
+      break;
+   default: sprintf(filnm, "Unknw");
+      break;
+   }
+   png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm);
+   png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth,
+      (int)((row_info->pixel_depth + 7) >> 3));
+   png_debug1(0,"len=%8d, ", row_info->rowbytes);
+
+   switch (filter)
+   {
+      case PNG_FILTER_VALUE_NONE:
+         break;
+      case PNG_FILTER_VALUE_SUB:
+      {
+         if ( UseMMX && (row_info->pixel_depth > 8) &&
+            (row_info->rowbytes >= 128) )
+         {
+            png_read_filter_row_mmx_sub(row_info, row);
+         }  //end if UseMMX
+         else
+         {
+            int bpp;
+            png_bytep rp;
+            png_bytep lp;
+            png_uint_32 i;
+            bpp = (row_info->pixel_depth + 7) >> 3;
+            for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
+               i < row_info->rowbytes; i++, rp++, lp++)
+            {
+               *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
+         }
+         }  //end !UseMMX
+         break;
+      }
+      case PNG_FILTER_VALUE_UP:
+      {
+         if ( UseMMX && (row_info->pixel_depth > 8) &&
+             (row_info->rowbytes >= 128) )
+         {
+            png_read_filter_row_mmx_up(row_info, row, prev_row);
+         }  //end if UseMMX
+         else
+         {
+            png_bytep rp;
+            png_bytep pp;
+            png_uint_32 i;
+            for (i = 0, rp = row, pp = prev_row;
+               i < row_info->rowbytes; i++, rp++, pp++)
+            {
+                  *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
+            }
+         }  //end !UseMMX
+         break;
+      }
+      case PNG_FILTER_VALUE_AVG:
+      {
+         if ( UseMMX && (row_info->pixel_depth > 8) &&
+             (row_info->rowbytes >= 128) )
+         {
+            png_read_filter_row_mmx_avg(row_info, row, prev_row);
+         }  //end if UseMMX
+         else
+         {
+      png_uint_32 i;
+      int bpp;
+      png_bytep rp;
+      png_bytep pp;
+      png_bytep lp;
+            bpp = (row_info->pixel_depth + 7) >> 3;
+            for (i = 0, rp = row, pp = prev_row;
+               i < (png_uint_32)bpp; i++, rp++, pp++)
+      {
+               *rp = (png_byte)(((int)(*rp) +
+                  ((int)(*pp) / 2)) & 0xff);
+      }
+            for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
+      {
+               *rp = (png_byte)(((int)(*rp) +
+                  (int)(*pp + *lp) / 2) & 0xff);
+      }
+         }  //end !UseMMX
+         break;
+      }
+      case PNG_FILTER_VALUE_PAETH:
+      {
+         if ( UseMMX && (row_info->pixel_depth > 8) &&
+             (row_info->rowbytes >= 128) )
+         {
+            png_read_filter_row_mmx_paeth(row_info, row, prev_row);
+         }  //end if UseMMX
+         else
+         {
+            int bpp;
+            png_uint_32 i;
+            png_bytep rp;
+            png_bytep pp;
+            png_bytep lp;
+            png_bytep cp;
+            bpp = (row_info->pixel_depth + 7) >> 3;
+            for (i = 0, rp = row, pp = prev_row;
+               i < (png_uint_32)bpp; i++, rp++, pp++)
+            {
+               *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
+            }
+            for (lp = rp - bpp, cp = pp - bpp;
+               i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
+            {
+               int a, b, c, pa, pb, pc, p;
+               b = *pp;
+               c = *cp;
+               a = *lp;
+               p = a + b - c;
+               pa = abs(p - a);
+               pb = abs(p - b);
+               pc = abs(p - c);
+               if (pa <= pb && pa <= pc)
+                  p = a;
+               else if (pb <= pc)
+                  p = b;
+               else
+                  p = c;
+               *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+            }
+         }  //end !UseMMX
+         break;
+      }
+      default:
+         png_error(png_ptr, "Bad adaptive filter type");
+         break;
+   }
+}
+#endif
diff --git a/pngwio.c b/pngwio.c
index 84b5b28..4228df3 100644
--- a/pngwio.c
+++ b/pngwio.c
@@ -1,7 +1,7 @@
 
 /* pngwio.c - functions for data output
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
diff --git a/pngwrite.c b/pngwrite.c
index 3b533e5..8809123 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1,7 +1,7 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -971,6 +971,8 @@
 {
    if (window_bits > 15)
       png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+   else if (window_bits < 8)
+      png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
    png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
    png_ptr->zlib_window_bits = window_bits;
 }
@@ -1001,4 +1003,3 @@
    png_ptr->write_user_transform_fn = write_user_transform_fn;
 }
 #endif
-
diff --git a/pngwtran.c b/pngwtran.c
index 76cf3a3..7fed233 100644
--- a/pngwtran.c
+++ b/pngwtran.c
@@ -1,7 +1,7 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
diff --git a/pngwutil.c b/pngwutil.c
index 4736361..e7a6a3c 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -1,7 +1,7 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * libpng 1.0.3 - January 14, 1999
+ * libpng 1.0.4 - September 17, 1999
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
@@ -284,17 +284,21 @@
    png_byte buf[3];
 
    png_debug(1, "in png_write_PLTE\n");
-   if (num_pal == 0 || num_pal > 256)
-   {
-      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
-      {
-         png_error(png_ptr, "Invalid number of colors in palette");
-      }
-      else
-      {
-         png_warning(png_ptr, "Invalid number of colors in palette");
-         return;
-      }
+   if ((
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+        !png_ptr->empty_plte_permitted &&
+#endif
+        num_pal == 0) || num_pal > 256)
+     {
+       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+         {
+           png_error(png_ptr, "Invalid number of colors in palette");
+         }
+       else
+         {
+           png_warning(png_ptr, "Invalid number of colors in palette");
+           return;
+         }
    }
 
    png_ptr->num_palette = (png_uint_16)num_pal;
@@ -524,7 +528,12 @@
    png_debug(1, "in png_write_bKGD\n");
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
-      if (back->index > png_ptr->num_palette)
+      if (
+#ifdef PNG_WRITE_EMPTY_PLTE_SUPPORTED
+          (!png_ptr->empty_plte_permitted ||
+          (png_ptr->empty_plte_permitted && png_ptr->num_palette)) &&
+#endif
+         back->index > png_ptr->num_palette)
       {
          png_warning(png_ptr, "Invalid background palette index");
          return;
@@ -713,6 +722,11 @@
 
    /* make sure we include the 0 after the key */
    png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1);
+   /*
+    * We leave it to the application to meet PNG-1.0 requirements on the
+    * contents of the text.  PNG-1.0 through PNG-1.2 discourage the use of
+    * any non-Latin-1 characters except for NEWLINE.  ISO PNG will forbid them.
+    */
    png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
    if (text_len)
       png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
diff --git a/scripts/makefile.aco b/scripts/makefile.aco
index 7fa6974..504a17f 100644
--- a/scripts/makefile.aco
+++ b/scripts/makefile.aco
@@ -13,36 +13,36 @@
 
 # Final targets:
 @.libpng-lib:   @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \
-        @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \
-        @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil 
-        LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \
-        @.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \
-        @.o.pngrutil @.o.pngtrans  @.o.pngwrite @.o.pngwtran @.o.pngwutil 
+	@.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \
+	@.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil 
+	LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \
+	@.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \
+	@.o.pngrutil @.o.pngtrans  @.o.pngwrite @.o.pngwtran @.o.pngwutil 
 @.mm-libpng-lib:   @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \
-        @.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \
-        @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil 
-        LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \
-        @.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \
-        @.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \
-        @.mm.pngwtran @.mm.pngwutil 
+	@.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \
+	@.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil 
+	LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \
+	@.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \
+	@.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \
+	@.mm.pngwtran @.mm.pngwutil 
 
 
 # User-editable dependencies:
 # (C) Copyright 1997 Tom Tanner
 Test: @.pngtest 
-        <Prefix$Dir>.pngtest
-        @remove <Prefix$Dir>.pngtest
+	<Prefix$Dir>.pngtest
+	@remove <Prefix$Dir>.pngtest
 
 #It would be nice if you could stop "make" listing from here on!
 @.pngtest:   @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib 
-        Link $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib 
+	Link $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib 
 
 .SUFFIXES: .o .mm .c
 
 .c.mm:
-        MemCheck.CC cc $(ccflags) -o $@ LibPng:$<
+	MemCheck.CC cc $(ccflags) -o $@ LibPng:$<
 .c.o:
-        cc $(ccflags) -o $@ $<
+	cc $(ccflags) -o $@ $<
 
 
 # Static dependencies:
diff --git a/scripts/makefile.ama b/scripts/makefile.ama
index 366524d..4a45604 100644
--- a/scripts/makefile.ama
+++ b/scripts/makefile.ama
@@ -8,7 +8,7 @@
 # WARNING: a bug in V6.51 causes bad code with OPTGO
 #          So use V6.55 or set NOOPTGO!!!!!!!!!
 CFLAGS= NOSTKCHK PARMS=REG OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL\
-        OPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 DEFINE=PNG_INTERNAL
+	OPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 DEFINE=PNG_INTERNAL
 #linker flags
 LDFLAGS= SD ND BATCH
 #link libs
diff --git a/scripts/makefile.beo b/scripts/makefile.beo
new file mode 100644
index 0000000..8265012
--- /dev/null
+++ b/scripts/makefile.beo
@@ -0,0 +1,104 @@
+# makefile for libpng on BeOS x86 ELF with gcc
+# modified from makefile.lnx by Sander Stoks
+# Copyright (C) 1996, 1997 Andreas Dilger
+# Copyright (C) 1999 Greg Roelofs
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+
+# Where the zlib library and include files are located
+ZLIBLIB=/usr/local/lib
+ZLIBINC=/usr/local/include
+
+ALIGN=
+# For I-386:
+# ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+	-Wmissing-declarations -Wtraditional -Wcast-align \
+	-Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# On BeOS, -O1 is actually better than -O3.  This is a known bug but it's
+# still here in R4.5
+CFLAGS=-I$(ZLIBINC) -Wall -O1 -funroll-loops \
+	$(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+# LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz -lm
+LDFLAGS=-L. -Wl,-soname=libpng.so.$(PNGMAJ) -L$(ZLIBLIB) -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
+# have to change it.
+PNGMAJ = 2
+PNGMIN = 1.0.3
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+# where make install puts libpng.a, libpng.so*, and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS)
+
+.SUFFIXES:      .c .o
+
+all: libpng.a libpng.so pngtest
+
+libpng.a: $(OBJS)
+	ar rc $@ $(OBJS)
+	$(RANLIB) $@
+
+libpng.so: libpng.so.$(PNGMAJ)
+	ln -sf libpng.so.$(PNGMAJ) libpng.so
+	cp libpng.so* /boot/home/config/lib
+
+libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
+	ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+
+libpng.so.$(PNGVER): $(OBJSDLL)
+	$(CC) -L$(ZLIBLIB) -lz -nostart -Wl,-soname,libpng.so.$(PNGMAJ) -o
+libpng.so.$(PNGVER) \
+	 $(OBJSDLL)
+
+pngtest: pngtest.o libpng.so
+	$(CC) -L$(ZLIBLIB) -lz -lpng -o pngtest pngtest.o
+
+test: pngtest
+	./pngtest
+
+install: libpng.a libpng.so.$(PNGVER)
+	-@mkdir $(INCPATH) $(LIBPATH)
+	cp png.h pngconf.h $(INCPATH)
+	chmod 644 $(INCPATH)/png.h $(INCPATH)/pngconf.h
+	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
+	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
+	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
+	(cd $(LIBPATH); ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -sf libpng.so.$(PNGMAJ) libpng.so)
+
+clean:
+	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
diff --git a/scripts/makefile.bor b/scripts/makefile.bor
index 13432c1..57f374f 100644
--- a/scripts/makefile.bor
+++ b/scripts/makefile.bor
@@ -70,38 +70,38 @@
 
 ## variables
 OBJS = \
- png.$(O) \
- pngerror.$(O) \
- pngmem.$(O) \
- pngpread.$(O) \
- pngset.$(O) \
- pngget.$(O) \
- pngread.$(O) \
- pngrio.$(O) \
- pngrtran.$(O) \
- pngrutil.$(O) \
- pngtrans.$(O) \
- pngwrite.$(O) \
- pngwtran.$(O) \
- pngwio.$(O) \
- pngwutil.$(O)
+	png.$(O) \
+	pngerror.$(O) \
+	pngmem.$(O) \
+	pngpread.$(O) \
+	pngset.$(O) \
+	pngget.$(O) \
+	pngread.$(O) \
+	pngrio.$(O) \
+	pngrtran.$(O) \
+	pngrutil.$(O) \
+	pngtrans.$(O) \
+	pngwrite.$(O) \
+	pngwtran.$(O) \
+	pngwio.$(O) \
+	pngwutil.$(O)
 
 LIBOBJS = \
- +png.$(O) \
- +pngerror.$(O) \
- +pngmem.$(O) \
- +pngpread.$(O) \
- +pngread.$(O) \
- +pngset.$(O) \
- +pngget.$(O) \
- +pngrio.$(O) \
- +pngrtran.$(O) \
- +pngrutil.$(O) \
- +pngtrans.$(O) \
- +pngwrite.$(O) \
- +pngwtran.$(O) \
- +pngwio.$(O) \
- +pngwutil.$(O)
+	+png.$(O) \
+	+pngerror.$(O) \
+	+pngmem.$(O) \
+	+pngpread.$(O) \
+	+pngread.$(O) \
+	+pngset.$(O) \
+	+pngget.$(O) \
+	+pngrio.$(O) \
+	+pngrtran.$(O) \
+	+pngrutil.$(O) \
+	+pngtrans.$(O) \
+	+pngwrite.$(O) \
+	+pngwtran.$(O) \
+	+pngwio.$(O) \
+	+pngwutil.$(O)
 
 LIBNAME=libpng$(MODEL).lib
 
@@ -146,7 +146,7 @@
 
 $(LIBNAME): $(OBJS)
 	-del $(LIBNAME)
-        $(LIB) $(LIBNAME) @&&|
+	$(LIB) $(LIBNAME) @&&|
 $(LIBOBJS), libpng$(MODEL)
 |
 
diff --git a/scripts/makefile.dec b/scripts/makefile.dec
index 9db3a4f..6f252e4 100644
--- a/scripts/makefile.dec
+++ b/scripts/makefile.dec
@@ -14,7 +14,7 @@
 # read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
 # have to change it.
 PNGMAJ = 2
-PNGMIN = 1.0.3
+PNGMIN = 1.0.4
 PNGVER = $(PNGMAJ).$(PNGMIN)
 
 CC=cc
@@ -36,10 +36,10 @@
 	$(RANLIB) $@
 
 libpng.so: libpng.so.$(PNGMAJ)
-	ln -s -f libpng.so.$(PNGMAJ) libpng.so
+	ln -f -s libpng.so.$(PNGMAJ) libpng.so
 
 libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
-	ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+	ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
 
 libpng.so.$(PNGVER): $(OBJS)
 	$(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB) -lz -lm
@@ -62,8 +62,8 @@
 	chmod 644 $(prefix)/lib/libpng.a
 	chmod 644 $(prefix)/lib/libpng.so.$(PNGVER)
 	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
-	(cd $(LIBPATH); ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
-	 ln -s -f libpng.so.$(PNGMAJ) libpng.so)
+	(cd $(LIBPATH); ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -f -s libpng.so.$(PNGMAJ) libpng.so)
 
 clean:
 	rm -f *.o libpng.a pngtest pngout.png libpng.so*
diff --git a/scripts/makefile.hux b/scripts/makefile.hux
index 0ae187b..780bfe5 100644
--- a/scripts/makefile.hux
+++ b/scripts/makefile.hux
@@ -1,4 +1,3 @@
-===========================================================================
 # makefile for libpng, HPUX (10.20 and 11.00)
 # Copyright (C) 1995 Guy Eric Schalnat, Group 42
 # Copyright (C) 1999 Glenn Randers-Pehrson
@@ -17,36 +16,36 @@
 RANLIB=ranlib
 
 # where make install puts libpng.a and png.h
-prefix=/opt/libpng/
+prefix=/opt/libpng
 
 OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-        pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-        pngwtran.o pngmem.o pngerror.o pngpread.o
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
 
 all: libpng.a pngtest
 
 libpng.a: $(OBJS)
-        ar rc $@  $(OBJS)
-        $(RANLIB) $@
+	ar rc $@  $(OBJS)
+	$(RANLIB) $@
 
 pngtest: pngtest.o libpng.a
-        $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
+	$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
 
 test: pngtest
-        ./pngtest
+	./pngtest
 
 install: libpng.a
-        -@mkdir $(prefix)/include
-        -@mkdir $(prefix)/lib
-        cp png.h $(prefix)/include
-        cp pngconf.h $(prefix)/include
-        chmod 644 $(prefix)/include/png.h
-        chmod 644 $(prefix)/include/pngconf.h
-        cp libpng.a $(prefix)/lib
-        chmod 644 $(prefix)/lib/libpng.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp png.h $(prefix)/include
+	cp pngconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/png.h
+	chmod 644 $(prefix)/include/pngconf.h
+	cp libpng.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libpng.a
 
 clean:
-        rm -f *.o libpng.a pngtest pngout.png
+	rm -f *.o libpng.a pngtest pngout.png
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
diff --git a/scripts/makefile.knr b/scripts/makefile.knr
index 8300422..b85f435 100644
--- a/scripts/makefile.knr
+++ b/scripts/makefile.knr
@@ -2,6 +2,11 @@
 # Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
 # For conditions of distribution and use, see copyright notice in png.h
 
+# This makefile requires file file ansi2knr.c, which you can get
+# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/
+# If you have libjpeg, you probably already have ansi2knr.c in the jpeg
+# source distribution.
+
 # where make install puts libpng.a and png.h
 prefix=/usr/local
 
diff --git a/scripts/makefile.lnx b/scripts/makefile.lnx
index 33b896b..95564b6 100644
--- a/scripts/makefile.lnx
+++ b/scripts/makefile.lnx
@@ -19,11 +19,11 @@
 #ALIGN=-malign-loops=2 -malign-functions=2
 
 WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
-         -Wmissing-declarations -Wtraditional -Wcast-align \
-         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+	-Wmissing-declarations -Wtraditional -Wcast-align \
+	-Wstrict-prototypes -Wmissing-prototypes #-Wconversion
 
 CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \
-     $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+	$(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
 LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz -lm
 
 RANLIB=ranlib
@@ -32,15 +32,15 @@
 # read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
 # have to change it.
 PNGMAJ = 2
-PNGMIN = 1.0.3
+PNGMIN = 1.0.4
 PNGVER = $(PNGMAJ).$(PNGMIN)
 
 INCPATH=$(prefix)/include
 LIBPATH=$(prefix)/lib
 
 OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
 
 OBJSDLL = $(OBJS:.o=.pic.o)
 
@@ -56,10 +56,10 @@
 	$(RANLIB) $@
 
 libpng.so: libpng.so.$(PNGMAJ)
-	ln -s -f libpng.so.$(PNGMAJ) libpng.so
+	ln -f -s libpng.so.$(PNGMAJ) libpng.so
 
 libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
-	ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+	ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
 
 libpng.so.$(PNGVER): $(OBJSDLL)
 	$(CC) -shared -Wl,-soname,libpng.so.$(PNGMAJ) -o libpng.so.$(PNGVER) \
@@ -78,8 +78,8 @@
 	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
 	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
 	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
-	(cd $(LIBPATH); ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
-	 ln -s -f libpng.so.$(PNGMAJ) libpng.so)
+	(cd $(LIBPATH); ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -f -s libpng.so.$(PNGMAJ) libpng.so)
 
 clean:
 	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
diff --git a/scripts/makefile.msc b/scripts/makefile.msc
index 742de4e..6356218 100644
--- a/scripts/makefile.msc
+++ b/scripts/makefile.msc
@@ -26,52 +26,52 @@
 		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngset$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngget$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngread$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngpread$(O): png.h pngconf.h
 		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngrtran$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngrutil$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngerror$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngmem$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngrio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngtest$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngtrans$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwrite$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwtran$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwutil$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
-        del libpng.lib
+	del libpng.lib
 	lib libpng $(OBJS1);
 	lib libpng $(OBJS2);
 	lib libpng $(OBJS3);
diff --git a/scripts/makefile.os2 b/scripts/makefile.os2
index a3ff2dc..588067d 100644
--- a/scripts/makefile.os2
+++ b/scripts/makefile.os2
@@ -10,10 +10,10 @@
 ZLIBINC=../zlib
 
 WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
-         -Wmissing-declarations -Wtraditional -Wcast-align \
-         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+	-Wmissing-declarations -Wtraditional -Wcast-align \
+	-Wstrict-prototypes -Wmissing-prototypes #-Wconversion
 CFLAGS=-I$(ZLIBINC) -Wall -O6 -funroll-loops -malign-loops=2 \
-       -malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5
+	-malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5
 LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lzdll -Zcrtdll
 AR=emxomfar
 
@@ -23,8 +23,8 @@
 SHAREDLIBIMP=pngdll.lib
 
 OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
 
 .SUFFIXES:      .c .o
 
diff --git a/scripts/makefile.s2x b/scripts/makefile.s2x
index e874a5a..5f3a412 100644
--- a/scripts/makefile.s2x
+++ b/scripts/makefile.s2x
@@ -6,7 +6,12 @@
 
 CC=gcc
 
-# where make install puts libpng.a, libpng.so*, and png.h
+# The commands "CC" and "LD" must NOT refer to /usr/ucb/cc and /usr/ucb/ld.
+# If they do, you need to adjust your PATH environment variable.
+# The environment variable LD_LIBRARY_PATH should not be set at all.  If
+# it is, things are likely to break.
+
+# Where make install puts libpng.a, libpng.so*, and png.h
 prefix=/usr/local
 
 # Where the zlib library and include files are located
@@ -19,10 +24,10 @@
 ZLIBINC=/usr/local/include
 
 WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
-         -Wmissing-declarations -Wtraditional -Wcast-align \
-         -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+	-Wmissing-declarations -Wtraditional -Wcast-align \
+	-Wstrict-prototypes -Wmissing-prototypes #-Wconversion
 CFLAGS=-I$(ZLIBINC) -Wall -O3 \
-      # $(WARNMORE) -g -DPNG_DEBUG=5
+	# $(WARNMORE) -g -DPNG_DEBUG=5
 LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng -lz -lm
 
 #RANLIB=ranlib
@@ -31,15 +36,15 @@
 # read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
 # have to change it.
 PNGMAJ = 2
-PNGMIN = 1.0.3
+PNGMIN = 1.0.4
 PNGVER = $(PNGMAJ).$(PNGMIN)
 
 INCPATH=$(prefix)/include
 LIBPATH=$(prefix)/lib
 
 OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
 
 OBJSDLL = $(OBJS:.o=.pic.o)
 
@@ -55,10 +60,10 @@
 	$(RANLIB) $@
 
 libpng.so: libpng.so.$(PNGMAJ)
-	ln -s -f libpng.so.$(PNGMAJ) libpng.so
+	ln -f -s libpng.so.$(PNGMAJ) libpng.so
 
 libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
-	ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+	ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
 
 libpng.so.$(PNGVER): $(OBJSDLL)
 	$(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h libpng.so.$(PNGMAJ) \
@@ -77,8 +82,8 @@
 	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
 	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
 	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
-	(cd $(LIBPATH); ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
-	 ln -s -f libpng.so.$(PNGMAJ) libpng.so)
+	(cd $(LIBPATH); ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -f -s libpng.so.$(PNGMAJ) libpng.so)
 
 clean:
 	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
diff --git a/scripts/makefile.sco b/scripts/makefile.sco
index f97b8b6..9eee4a2 100644
--- a/scripts/makefile.sco
+++ b/scripts/makefile.sco
@@ -25,15 +25,15 @@
 # read libpng.txt or png.h to see why PNGMAJ is 2.  You should not
 # have to change it.
 PNGMAJ = 2
-PNGMIN = 1.0.3
+PNGMIN = 1.0.4
 PNGVER = $(PNGMAJ).$(PNGMIN)
 
 INCPATH=$(prefix)/include
 LIBPATH=$(prefix)/lib
 
 OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
-       pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
-       pngwtran.o pngmem.o pngerror.o pngpread.o
+	pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+	pngwtran.o pngmem.o pngerror.o pngpread.o
 
 OBJSDLL = $(OBJS:.o=.pic.o)
 
@@ -49,10 +49,10 @@
 	$(RANLIB) $@
 
 libpng.so: libpng.so.$(PNGMAJ)
-	ln -s -f libpng.so.$(PNGMAJ) libpng.so
+	ln -f -s libpng.so.$(PNGMAJ) libpng.so
 
 libpng.so.$(PNGMAJ): libpng.so.$(PNGVER)
-	ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
+	ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ)
 
 libpng.so.$(PNGVER): $(OBJSDLL)
 	$(CC) -G  -Wl,-h,libpng.so.$(PNGMAJ) -o libpng.so.$(PNGVER) \
@@ -71,8 +71,8 @@
 	cp libpng.a libpng.so.$(PNGVER) $(LIBPATH)
 	chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
 	-@/bin/rm -f $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
-	(cd $(LIBPATH); ln -s -f libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
-	 ln -s -f libpng.so.$(PNGMAJ) libpng.so)
+	(cd $(LIBPATH); ln -f -s libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
+	 ln -f -s libpng.so.$(PNGMAJ) libpng.so)
 
 clean:
 	/bin/rm -f *.o libpng.a libpng.so* pngtest pngout.png
diff --git a/scripts/makefile.sgi b/scripts/makefile.sgi
index 715624b..e3739b5 100644
--- a/scripts/makefile.sgi
+++ b/scripts/makefile.sgi
@@ -14,6 +14,7 @@
 CC=cc
 
 WARNMORE=-fullwarn
+# You can add the -n32 option; then zlib must also be compiled with -n32
 CFLAGS=-I$(ZLIBINC) -O $(WARNMORE) # -g -DPNG_DEBUG=5
 LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
 
diff --git a/scripts/makefile.sun b/scripts/makefile.sun
index db91d21..f2ce329 100644
--- a/scripts/makefile.sun
+++ b/scripts/makefile.sun
@@ -13,8 +13,8 @@
 
 
 WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \
-         -Wmissing-declarations -Wtraditional -Wcast-align \
-         -Wstrict-prototypes -Wmissing-prototypes
+	-Wmissing-declarations -Wtraditional -Wcast-align \
+	-Wstrict-prototypes -Wmissing-prototypes
 CC=gcc
 CFLAGS=-I$(ZLIBINC) -O # $(WARNMORE) -DPNG_DEBUG=5
 LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
diff --git a/scripts/makefile.tc3 b/scripts/makefile.tc3
index 6f8f366..c925831 100644
--- a/scripts/makefile.tc3
+++ b/scripts/makefile.tc3
@@ -45,38 +45,38 @@
 		  $(CC) -c $(CFLAGS) $*.c
 
 pngerror$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngmem$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngrio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngwio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngtest$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngtrans$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngwrite$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngwtran$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 pngwutil$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c
+	$(CC) -c $(CFLAGS) $*.c
 
 libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
-        $(LIB) libpng +$(OBJSL1)
-        $(LIB) libpng +$(OBJSL2)
-        $(LIB) libpng +$(OBJSL3)
+	$(LIB) libpng +$(OBJSL1)
+	$(LIB) libpng +$(OBJSL2)
+	$(LIB) libpng +$(OBJSL3)
 
 pngtest$(E): pngtest$(O) libpng.lib
-        $(CC) $(LDFLAGS) pngtest.obj libpng.lib zlib.lib
+	$(CC) $(LDFLAGS) pngtest.obj libpng.lib zlib.lib
 
 # End of makefile for libpng
diff --git a/scripts/makefile.w32 b/scripts/makefile.w32
index 109f3a3..52934c3 100644
--- a/scripts/makefile.w32
+++ b/scripts/makefile.w32
@@ -6,7 +6,7 @@
 
 # ------------- Microsoft Visual C++ 4.0 and later -------------
 MODEL=- 
-CFLAGS=-Ox -GA3s -nologo -W3 -I..\zlib
+CFLAGS=-DPNG_USE_PNGVCRD -Ox -GA3s -nologo -W3 -I..\zlib
 
 CC=cl
 LD=link
@@ -19,7 +19,7 @@
 # variables
 OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
 OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
-OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) pngvcrd$(O)
 
 all: libpng.lib
 
@@ -27,52 +27,55 @@
 		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngset$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngget$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngread$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngpread$(O): png.h pngconf.h
-		  $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngrtran$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
-pngrutil$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+pngrutil$(O): png.h pngconf.h pngasmrd.h
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngvcrd$(O): png.h pngconf.h pngasmrd.h
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngerror$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngmem$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngrio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwio$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngtest$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngtrans$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwrite$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwtran$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 pngwutil$(O): png.h pngconf.h
-        $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+	$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
 
 libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
-        del libpng.lib
+	del libpng.lib
 	lib /OUT:libpng.lib $(OBJS1) $(OBJS2) $(OBJS3)
 
 pngtest.exe: pngtest.obj libpng.lib 
diff --git a/scripts/makefile.wat b/scripts/makefile.wat
index cf004db..a7d99c2 100644
--- a/scripts/makefile.wat
+++ b/scripts/makefile.wat
@@ -1,15 +1,15 @@
 # Makefile for libpng
-# Watcom 10.0a and later 32-bit protected mode flat memory model
+# Watcom 10.0 and later 32-bit protected mode flat memory model
 
 # Adapted by Pawel Mrochen, based on makefile.msc
 # For conditions of distribution and use, see copyright notice in png.h
 # Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
 
-# To use, do "wmake -f makefile.wat"
+# To use, do "wmake /f scripts\makefile.wat"
 
-# ------------- Watcom 10.0a and later -------------
+# ------------- Watcom 10.0 and later -------------
 MODEL=-mf
-CFLAGS= $(MODEL) -5r -fp5 -fpi87 -oneatx -zp8 -i=..\zlib
+CFLAGS= $(MODEL) -5r -fp5 -fpi87 -oneatx -i=..\zlib
 CC=wcc386
 LD=wcl386
 LIB=wlib -b -c
@@ -82,7 +82,7 @@
 pngtest.exe: pngtest.obj libpng.lib
 	$(LD) $(LDFLAGS) pngtest.obj libpng.lib ..\zlib\zlib.lib
 
-test: pngtest.exe
+test: pngtest.exe .symbolic
 	pngtest
 
 # End of makefile for libpng
diff --git a/scripts/makevms.com b/scripts/makevms.com
index 15f305a..a570546 100644
--- a/scripts/makevms.com
+++ b/scripts/makevms.com
@@ -35,45 +35,45 @@
 $  then
 $   dele pngtest.obj;*
 $   CALL MAKE png.OBJ "cc ''CCOPT' png" -
-                png.c png.h pngconf.h   
+	png.c png.h pngconf.h   
 $   CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
 					 pngpread.c png.h pngconf.h
 $   CALL MAKE pngset.OBJ "cc ''CCOPT' pngset" -
-                pngset.c png.h pngconf.h
+	pngset.c png.h pngconf.h
 $   CALL MAKE pngget.OBJ "cc ''CCOPT' pngget" -
-                pngget.c png.h pngconf.h
+	pngget.c png.h pngconf.h
 $   CALL MAKE pngread.OBJ "cc ''CCOPT' pngread" -
-                pngread.c png.h pngconf.h
+	pngread.c png.h pngconf.h
 $   CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
 					 pngpread.c png.h pngconf.h
 $   CALL MAKE pngrtran.OBJ "cc ''CCOPT' pngrtran" -
-                pngrtran.c png.h pngconf.h
+	pngrtran.c png.h pngconf.h
 $   CALL MAKE pngrutil.OBJ "cc ''CCOPT' pngrutil" -
-                pngrutil.c png.h pngconf.h
+	pngrutil.c png.h pngconf.h
 $   CALL MAKE pngerror.OBJ "cc ''CCOPT' pngerror" -
-                pngerror.c png.h pngconf.h
+	pngerror.c png.h pngconf.h
 $   CALL MAKE pngmem.OBJ "cc ''CCOPT' pngmem" -
-                pngmem.c png.h pngconf.h
+	pngmem.c png.h pngconf.h
 $   CALL MAKE pngrio.OBJ "cc ''CCOPT' pngrio" -
-                pngrio.c png.h pngconf.h
+	pngrio.c png.h pngconf.h
 $   CALL MAKE pngwio.OBJ "cc ''CCOPT' pngwio" -
-                pngwio.c png.h pngconf.h
+	pngwio.c png.h pngconf.h
 $   CALL MAKE pngtrans.OBJ "cc ''CCOPT' pngtrans" -
-                pngtrans.c png.h pngconf.h
+	pngtrans.c png.h pngconf.h
 $   CALL MAKE pngwrite.OBJ "cc ''CCOPT' pngwrite" -
-                pngwrite.c png.h pngconf.h
+	pngwrite.c png.h pngconf.h
 $   CALL MAKE pngwtran.OBJ "cc ''CCOPT' pngwtran" -
-                pngwtran.c png.h pngconf.h
+	pngwtran.c png.h pngconf.h
 $   CALL MAKE pngwutil.OBJ "cc ''CCOPT' pngwutil" -
-                pngwutil.c png.h pngconf.h
+	pngwutil.c png.h pngconf.h
 $   write sys$output "Building Libpng ..."
 $   CALL MAKE libpng.OLB "lib/crea libpng.olb *.obj" *.OBJ
 $   write sys$output "Building pngtest..."
 $   CALL MAKE pngtest.OBJ "cc ''CCOPT' pngtest" -
-                pngtest.c png.h pngconf.h
+	pngtest.c png.h pngconf.h
 $   call make pngtest.exe - 
-                "LINK pngtest,libpng.olb/lib,''zlibsrc'libgz.olb/lib" - 
-                pngtest.obj libpng.olb
+	"LINK pngtest,libpng.olb/lib,''zlibsrc'libgz.olb/lib" - 
+	pngtest.obj libpng.olb
 $   write sys$output "Testing Libpng..."
 $   run pngtest
 $  else
diff --git a/scripts/pngdef.pas b/scripts/pngdef.pas
index 787f43c..2c8eaa4 100644
--- a/scripts/pngdef.pas
+++ b/scripts/pngdef.pas
@@ -3,7 +3,7 @@
 interface
 
 const
-  PNG_LIBPNG_VER_STRING = '1.0.3';
+  PNG_LIBPNG_VER_STRING = '1.0.3b';
   PNG_LIBPNG_VER        =  10001;
 
 type
@@ -475,6 +475,8 @@
 procedure png_set_gamma(png_ptr: png_structp; screen_gamma,
              default_file_gamma: double);
              stdcall;
+procedure png_set_gray_1_2_4_to_8(png_ptr: png_structp);
+             stdcall;
 procedure png_set_gray_to_rgb(png_ptr: png_structp);
              stdcall;
 procedure png_set_hIST(png_ptr: png_structp; info_ptr: png_infop;
@@ -489,6 +491,8 @@
 procedure png_set_oFFs(png_ptr: png_structp; info_ptr: png_infop;
              offset_x, offset_y: png_uint_32; unit_type: int);
              stdcall;
+procedure png_set_palette_to_rgb(png_ptr: png_structp);
+             stdcall;
 procedure png_set_pCAL(png_ptr: png_structp; info_ptr: png_infop;
              purpose: png_charp; X0, X1: png_int_32;
              typ, nparams: int; units: png_charp;
@@ -546,6 +550,8 @@
              trans: png_bytep; num_trans: int;
              trans_values: png_color_16p);
              stdcall;
+procedure png_set_tRNS_to_alpha(png_ptr: png_structp);
+             stdcall;
 procedure png_set_text(png_ptr: png_structp; info_ptr: png_infop;
              text_ptr: png_textp; num_text: int);
              stdcall;
diff --git a/scripts/pngos2.def b/scripts/pngos2.def
index d12d498..e557b09 100644
--- a/scripts/pngos2.def
+++ b/scripts/pngos2.def
@@ -149,6 +149,9 @@
   png_set_tIME
   png_get_tRNS
   png_set_tRNS
+  png_set_gray_1_2_4_to_8
+  png_set_tRNS_to_alpha
+  png_set_palette_to_rgb
 
   png_create_struct
   png_destroy_struct
diff --git a/scripts/zlibdef.pas b/scripts/zlibdef.pas
deleted file mode 100644
index 49664d6..0000000
--- a/scripts/zlibdef.pas
+++ /dev/null
@@ -1,169 +0,0 @@
-unit zlibdef;
-
-interface
-
-uses
-  Windows;
-
-const
-  ZLIB_VERSION = '1.1.2';
-
-type
-  voidpf = Pointer;
-  int    = Integer;
-  uInt   = Cardinal;
-  pBytef = PChar;
-  uLong  = Cardinal;
-
-  alloc_func = function(opaque: voidpf; items, size: uInt): voidpf;
-                    stdcall;
-  free_func  = procedure(opaque, address: voidpf);
-                    stdcall;
-
-  internal_state = Pointer;
-
-  z_streamp = ^z_stream;
-  z_stream = packed record
-    next_in: pBytef;          // next input byte
-    avail_in: uInt;           // number of bytes available at next_in
-    total_in: uLong;          // total nb of input bytes read so far
-
-    next_out: pBytef;         // next output byte should be put there
-    avail_out: uInt;          // remaining free space at next_out
-    total_out: uLong;         // total nb of bytes output so far
-
-    msg: PChar;               // last error message, NULL if no error
-    state: internal_state;    // not visible by applications
-
-    zalloc: alloc_func;       // used to allocate the internal state
-    zfree: free_func;         // used to free the internal state
-    opaque: voidpf;           // private data object passed to zalloc and zfree
-
-    data_type: int;           // best guess about the data type: ascii or binary
-    adler: uLong;             // adler32 value of the uncompressed data
-    reserved: uLong;          // reserved for future use
-    end;
-
-const
-  Z_NO_FLUSH      = 0;
-  Z_SYNC_FLUSH    = 2;
-  Z_FULL_FLUSH    = 3;
-  Z_FINISH        = 4;
-
-  Z_OK            = 0;
-  Z_STREAM_END    = 1;
-
-  Z_NO_COMPRESSION         =  0;
-  Z_BEST_SPEED             =  1;
-  Z_BEST_COMPRESSION       =  9;
-  Z_DEFAULT_COMPRESSION    = -1;
-
-  Z_FILTERED            = 1;
-  Z_HUFFMAN_ONLY        = 2;
-  Z_DEFAULT_STRATEGY    = 0;
-
-  Z_BINARY   = 0;
-  Z_ASCII    = 1;
-  Z_UNKNOWN  = 2;
-
-  Z_DEFLATED    = 8;
-
-  MAX_MEM_LEVEL = 9;
-
-function adler32(adler: uLong; const buf: pBytef; len: uInt): uLong;
-             stdcall;
-function crc32(crc: uLong; const buf: pBytef; len: uInt): uLong;
-             stdcall;
-function deflate(strm: z_streamp; flush: int): int;
-             stdcall;
-function deflateCopy(dest, source: z_streamp): int;
-             stdcall;
-function deflateEnd(strm: z_streamp): int;
-             stdcall;
-function deflateInit2_(strm: z_streamp; level, method,
-                       windowBits, memLevel, strategy: int;
-                       const version: PChar; stream_size: int): int;
-             stdcall;
-function deflateInit_(strm: z_streamp; level: int;
-                      const version: PChar; stream_size: int): int;
-             stdcall;
-function deflateParams(strm: z_streamp; level, strategy: int): int;
-             stdcall;
-function deflateReset(strm: z_streamp): int;
-             stdcall;
-function deflateSetDictionary(strm: z_streamp;
-                              const dictionary: pBytef;
-                              dictLength: uInt): int;
-             stdcall;
-function inflate(strm: z_streamp; flush: int): int;
-             stdcall;
-function inflateEnd(strm: z_streamp): int;
-             stdcall;
-function inflateInit2_(strm: z_streamp; windowBits: int;
-                       const version: PChar; stream_size: int): int;
-             stdcall;
-function inflateInit_(strm: z_streamp; const version: PChar;
-                      stream_size: int): int;
-             stdcall;
-function inflateReset(strm: z_streamp): int;
-             stdcall;
-function inflateSetDictionary(strm: z_streamp;
-                              const dictionary: pBytef;
-                              dictLength: uInt): int;
-             stdcall;
-function inflateSync(strm: z_streamp): int;
-             stdcall;
-
-function deflateInit(strm: z_streamp; level: int): int;
-function deflateInit2(strm: z_streamp; level, method, windowBits,
-                      memLevel, strategy: int): int;
-function inflateInit(strm: z_streamp): int;
-function inflateInit2(strm: z_streamp; windowBits: int): int;
-
-implementation
-
-function deflateInit(strm: z_streamp; level: int): int;
-begin
-  Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function deflateInit2(strm: z_streamp; level, method, windowBits,
-                      memLevel, strategy: int): int;
-begin
-  Result := deflateInit2_(strm, level, method, windowBits, memLevel,
-                          strategy, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit(strm: z_streamp): int;
-begin
-  Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
-end;
-
-function inflateInit2(strm: z_streamp; windowBits: int): int;
-begin
-  Result := inflateInit2_(strm, windowBits, ZLIB_VERSION,
-                          sizeof(z_stream));
-end;
-
-const
-  zlibDLL = 'png32bd.dll';
-
-function adler32; external zlibDLL;
-function crc32; external zlibDLL;
-function deflate; external zlibDLL;
-function deflateCopy; external zlibDLL;
-function deflateEnd; external zlibDLL;
-function deflateInit2_; external zlibDLL;
-function deflateInit_; external zlibDLL;
-function deflateParams; external zlibDLL;
-function deflateReset; external zlibDLL;
-function deflateSetDictionary; external zlibDLL;
-function inflate; external zlibDLL;
-function inflateEnd; external zlibDLL;
-function inflateInit2_; external zlibDLL;
-function inflateInit_; external zlibDLL;
-function inflateReset; external zlibDLL;
-function inflateSetDictionary; external zlibDLL;
-function inflateSync; external zlibDLL;
-
-end.
diff --git a/scripts/zlibdll.mak b/scripts/zlibdll.mak
deleted file mode 100644
index ba557e2..0000000
--- a/scripts/zlibdll.mak
+++ /dev/null
@@ -1,36 +0,0 @@
-# Makefile for zlib32bd.lib
-# ------------- Borland C++ 4.5 -------------
-
-# The (32-bit) zlib32bd.lib made with this makefile is intended for use 
-# in making the (32-bit) DLL, png32bd.dll. It uses the "stdcall" calling 
-# convention.
-
-CFLAGS= -ps -O2 -C -K -N- -k- -d -3 -r- -w-par -w-aus -WDE
-CC=f:\bc45\bin\bcc32
-LIBFLAGS= /C
-LIB=f:\bc45\bin\tlib
-ZLIB=zlib32bd.lib
-
-.autodepend
-.c.obj:
-        $(CC) -c $(CFLAGS) $<
-
-OBJ1=adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infblock.obj 
-OBJ2=infcodes.obj inflate.obj inftrees.obj infutil.obj inffast.obj 
-OBJ3=trees.obj uncompr.obj zutil.obj
-pOBJ1=+adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infblock.obj 
-pOBJ2=+infcodes.obj+inflate.obj+inftrees.obj+infutil.obj+inffast.obj 
-pOBJ3=+trees.obj+uncompr.obj+zutil.obj
-
-all: $(ZLIB)
-
-$(ZLIB): $(OBJ1) $(OBJ2) $(OBJ3)
-        @if exist $@ del $@
-        $(LIB) @&&|
-$@ $(LIBFLAGS) &
-$(pOBJ1) &
-$(pOBJ2) &
-$(pOBJ3)
-|
-
-# End of makefile for zlib32bd.lib