Imported from pngcrush-1.2.1.tar
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..021dd38
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,23 @@
+
+There's no makefile or "configure" for pngcrush.
+
+All you should need to do is enter the pngcrush-1.2.l
+directory and type
+
+    cc -O -o pngcrush *.c -lm
+    cp pngcrush /usr/local/bin  # or wherever you want
+
+You might want to create a makefile if you are planning to do
+something more complicated, like loading with your own shared
+libraries for libpng and zlib.
+
+Here's the command for compiling on SGI IRIX:
+
+    cc -n32 -fullwarn -O2 -IPA:plimit=256 -OPT:Olimit=0 -o pngcrush *.c -lm
+    cp pngcrush /usr/local/bin
+
+On a PC with DJGCC, you can type
+
+    gcc -O3 -Wall -funroll-loops -o pngcrush *.c
+    copy /B pmodstub.exe + pngcrush pngcrush.exe
+    then put pngcrush.exe wherever you want.
diff --git a/README.txt b/README.txt
index 1bb3451..534ade4 100644
--- a/README.txt
+++ b/README.txt
@@ -1,8 +1,8 @@
 
- | pngcrush 1.2.0, Copyright (C) 1998, 1999, Glenn Randers-Pehrson
+ | pngcrush 1.2.1, Copyright (C) 1998, 1999, Glenn Randers-Pehrson
  | This is a free, open-source program.  Permission is
  | granted to everyone to use pngcrush without fee.
- | This program was built with libpng version 1.0.5a,
+ | This program was built with libpng version 1.0.5f,
  |    Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc.,
  |    Copyright (C) 1996, 1997 Andreas Dilger,
  |    Copyright (C) 1998, 1999, Glenn Randers-Pehrson,
@@ -13,6 +13,31 @@
 usage: pngcrush [options] infile.png outfile.png
        pngcrush -e ext [other options] files.png ...
        pngcrush -d dir [other options] files.png ...
+options:
+        -brute (Use brute-force, try 114 different methods)
+            -c color_type of output file [0, 2, 4, or 6]
+            -d directory_name (where output files will go)
+ -double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files)
+            -e extension  (used for creating output filename)
+            -f user_filter [0-5]
+        -force (Write a new output file even if larger than input)
+            -g gamma_value (float, e.g., 0.45455)
+            -l zlib_compression_level [0-9]
+            -m method [0 through 200]
+          -max maximum_IDAT_size [1 through 524288]
+            -n (no save; does not do compression or write output PNG)
+            -plte_len n (truncate PLTE)
+            -q (quiet)
+          -rem chunkname (or "alla" or "allb")
+-replace_gamma gamma_value (float) even when file has a gAMA chunk.
+          -res dpi
+         -srgb [0, 1, 2, or 3]
+         -text b[efore_IDAT]|a[fter_IDAT] "keyword" "text"
+         -trns index red green blue gray
+      -verbose (write more detailed information)
+            -w compression_window_size [32, 16, 8, 4, 2, 1, 512, 256]
+            -h (help)
+            -p (pause)
 
 options:
         -brute (Use brute-force, try 114 different methods)
@@ -89,6 +114,11 @@
 
                Useful in conjunction with -v option to get info.
 
+            -plte_len n (truncate PLTE)
+
+               Truncates the PLTE.  Be sure not to truncate it to
+
+               less than the greatest index present in IDAT.
             -q (quiet)
 
 
@@ -146,7 +176,7 @@
             -z zlib_strategy [0, 1, or 2]
 
                zlib compression strategy to use with the preceding
-               preceding '-m method' argument.
+               '-m method' argument.
 
             -h (help)
 
diff --git a/png.c b/png.c
index 563d0b6..340d261 100644
--- a/png.c
+++ b/png.c
@@ -1,7 +1,7 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * libpng version 1.0.5a - October 23, 1999
+ * libpng version 1.0.5f - December 6, 1999
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
  * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
@@ -12,38 +12,40 @@
 #define PNG_NO_EXTERN
 #include "png.h"
 
-PNG_GET_HEADER
-
 /* Version information for C files.  This had better match the version
  * string defined in png.h.
  */
 
-char png_libpng_ver[12] = "1.0.5a";
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+char png_libpng_ver[12] = "1.0.5f";
 
+/* png_sig was changed to a function in version 1.0.5c */
 /* Place to hold the signature string for a PNG file. */
 png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-
-/* Constant strings for known chunk types.  If you need to add a chunk,
- * add a string holding the name here.  If you want to make the code
- * portable to EBCDIC machines, use ASCII numbers, not characters.
- */
-png_byte FARDATA png_IHDR[5] = { 73,  72,  68,  82, '\0'};
-png_byte FARDATA png_IDAT[5] = { 73,  68,  65,  84, '\0'};
-png_byte FARDATA png_IEND[5] = { 73,  69,  78,  68, '\0'};
-png_byte FARDATA png_PLTE[5] = { 80,  76,  84,  69, '\0'};
-png_byte FARDATA png_bKGD[5] = { 98,  75,  71,  68, '\0'};
-png_byte FARDATA png_cHRM[5] = { 99,  72,  82,  77, '\0'};
-png_byte FARDATA png_gAMA[5] = {103,  65,  77,  65, '\0'};
-png_byte FARDATA png_hIST[5] = {104,  73,  83,  84, '\0'};
-png_byte FARDATA png_oFFs[5] = {111,  70,  70, 115, '\0'};
-png_byte FARDATA png_pCAL[5] = {112,  67,  65,  76, '\0'};
-png_byte FARDATA png_pHYs[5] = {112,  72,  89, 115, '\0'};
-png_byte FARDATA png_sBIT[5] = {115,  66,  73,  84, '\0'};
-png_byte FARDATA png_sRGB[5] = {115,  82,  71,  66, '\0'};
-png_byte FARDATA png_tEXt[5] = {116,  69,  88, 116, '\0'};
-png_byte FARDATA png_tIME[5] = {116,  73,  77,  69, '\0'};
-png_byte FARDATA png_tRNS[5] = {116,  82,  78,  83, '\0'};
-png_byte FARDATA png_zTXt[5] = {122,  84,  88, 116, '\0'};
+ 
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
 
 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
@@ -75,6 +77,8 @@
 /* Mask to determine which pixels to overwrite while displaying */
 int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
 
+#endif
+
 /* Tells libpng that we have already handled the first "num_bytes" bytes
  * of the PNG file signature.  If the PNG data is embedded into another
  * stream we can set num_bytes = 8 so that libpng will not attempt to read
@@ -102,6 +106,7 @@
 int
 png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
 {
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    if (num_to_check > 8)
       num_to_check = 8;
    else if (num_to_check < 1)
@@ -113,7 +118,7 @@
    if (start + num_to_check > 8)
       num_to_check = 8 - start;
 
-   return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check)));
+   return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
 }
 
 /* (Obsolete) function to check signature bytes.  It does not allow one
@@ -253,6 +258,108 @@
    png_memset(info_ptr, 0, sizeof (png_info));
 }
 
+#if defined(PNG_TEXT_SUPPORTED)
+/* free text item num or (if num == -1) all text items */
+void
+png_free_text(png_structp png_ptr, png_infop info_ptr, int num)
+{
+    if (num != -1)
+    {
+    if (info_ptr->text[num].key)
+    {
+        png_free(png_ptr, info_ptr->text[num].key);
+        info_ptr->text[num].key = NULL;
+    }
+    if (info_ptr->text[num].lang)
+    {
+        png_free(png_ptr, info_ptr->text[num].lang);
+        info_ptr->text[num].lang = NULL;
+    }
+    }
+    else if (info_ptr->text != NULL)
+    {
+    int i;
+    for (i = 0; i < info_ptr->num_text; i++)
+        png_free_text(png_ptr, info_ptr, i);
+    png_free(png_ptr, info_ptr->text);
+    info_ptr->text = NULL;
+    }
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+/* free any sCAL entry */
+void
+png_free_sCAL(png_structp png_ptr, png_infop info_ptr)
+{
+   if (info_ptr->valid & PNG_INFO_sCAL)
+   {
+       png_free(png_ptr, info_ptr->scal_unit);
+       info_ptr->valid &= ~PNG_INFO_sCAL;
+   }
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+/* free any pCAL entry */
+void
+png_free_pCAL(png_structp png_ptr, png_infop info_ptr)
+{
+   if (info_ptr->valid & PNG_INFO_pCAL)
+   {
+       png_free(png_ptr, info_ptr->pcal_purpose);
+       png_free(png_ptr, info_ptr->pcal_units);
+       if (info_ptr->pcal_params != NULL)
+       {
+           int i;
+           for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+           {
+               png_free(png_ptr, info_ptr->pcal_params[i]);
+           }
+           png_free(png_ptr, info_ptr->pcal_params);
+       }
+       info_ptr->valid &= ~PNG_INFO_pCAL;
+   }
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+/* free any pCAL entry */
+void
+png_free_iCCP(png_structp png_ptr, png_infop info_ptr)
+{
+   if (info_ptr->valid & PNG_INFO_iCCP)
+   {
+       png_free(png_ptr, info_ptr->iccp_name);
+       png_free(png_ptr, info_ptr->iccp_profile);
+       info_ptr->valid &= ~PNG_INFO_iCCP;
+   }
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+/* free a given sPLT entry, or (if num == -1) all sPLT entries */
+void
+png_free_spalettes(png_structp png_ptr, png_infop info_ptr, int num)
+{
+   if (num != -1)
+   {
+       png_free(png_ptr, info_ptr->splt_palettes[num].name);
+       png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+   }
+   else
+   {
+       png_uint_32 i;
+
+       for (i = 0; i < info_ptr->splt_palettes_num; i++)
+          png_free_spalettes(png_ptr, info_ptr, num);
+
+       png_free(png_ptr, info_ptr->splt_palettes);
+       info_ptr->splt_palettes_num = 0;
+   }
+}
+#endif
+
 /* This is an internal routine to free any memory that the info struct is
  * pointing to before re-using it or freeing the struct itself.  Recall
  * that png_free() checks for NULL pointers for us.
@@ -260,39 +367,22 @@
 void
 png_info_destroy(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
    png_debug(1, "in png_info_destroy\n");
-   if (info_ptr->text != NULL)
-   {
-      int i;
-      for (i = 0; i < info_ptr->num_text; i++)
-      {
-         if(info_ptr->text[i].key != NULL)
-         {
-           png_free(png_ptr, info_ptr->text[i].key);
-           info_ptr->text[i].key = NULL;
-         }
-      }
-      png_free(png_ptr, info_ptr->text);
-      info_ptr->text = NULL;
-   }
+#if defined(PNG_READ_TEXT_SUPPORTED)
+   png_free_text(png_ptr, info_ptr, -1);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+   png_free_sCAL(png_ptr, info_ptr);
 #endif
 #if defined(PNG_READ_pCAL_SUPPORTED)
-   png_free(png_ptr, info_ptr->pcal_purpose);
-   png_free(png_ptr, info_ptr->pcal_units);
-   if (info_ptr->pcal_params != NULL)
-   {
-      int i;
-      for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
-      {
-         png_free(png_ptr, info_ptr->pcal_params[i]);
-         info_ptr->pcal_params[i]=NULL;
-      }
-      png_free(png_ptr, info_ptr->pcal_params);
-      info_ptr->pcal_params = NULL;
-   }
+   png_free_pCAL(png_ptr, info_ptr);
 #endif
-
+#if defined(PNG_READ_iCCP_SUPPORTED)
+   png_free_iCCP(png_ptr, info_ptr);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+   png_free_spalettes(png_ptr, info_ptr, -1);
+#endif
    png_info_init(info_ptr);
 }
 
@@ -356,22 +446,65 @@
 }
 #endif /* PNG_TIME_RFC1123_SUPPORTED */
 
+/* Signature string for a PNG file. */
+png_bytep
+png_sig_bytes(png_structp png_ptr)
+{
+   const png_byte png_sig_numbers[9] = {137, 80, 78, 71, 13, 10, 26, 10, 0};
+   if (png_ptr == NULL) /* silence compiler warning */
+     return ((png_bytep) strdup((png_const_charp)png_sig_numbers));
+   return ((png_bytep) strdup((png_const_charp)png_sig_numbers));
+}
+
 png_charp
 png_get_copyright(png_structp png_ptr)
 {
    if (png_ptr != NULL || png_ptr == NULL)  /* silence compiler warning */
-   return ("\n libpng version 1.0.5a - October 23, 1999\n\
+   return ("\n libpng version 1.0.5f - December 6, 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");
    return ("");
 }
 
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz.  To get the version of *.h files used
+ * with your application, print out PNG_LIBPNG_VER_STRING, which is defined
+ * in png.h.
+ */
+
+png_charp
+png_get_libpng_ver(png_structp png_ptr)
+{
+   /* Version of *.c files used when building libpng */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return("1.0.5f");
+   return("1.0.5f");
+}
+
+png_charp
+png_get_header_ver(png_structp png_ptr)
+{
+   /* Version of *.h files used when building libpng */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return(PNG_LIBPNG_VER_STRING);
+   return(PNG_LIBPNG_VER_STRING);
+}
+
+png_charp
+png_get_header_version(png_structp png_ptr)
+{
+   /* Returns longer string containing both version and date */
+   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+      return(PNG_HEADER_VERSION_STRING);
+   return(PNG_HEADER_VERSION_STRING);
+}
+
 /* Generate a compiler error if there is an old png.h in the search path. */
 void
 png_check_version
-   (version_1_0_5a png_h_is_not_version_1_0_5a)
+   (version_1_0_5f png_h_is_not_version_1_0_5f)
 {
-   if(png_h_is_not_version_1_0_5a == NULL)
+   if(png_h_is_not_version_1_0_5f == NULL)
      return;
 }
diff --git a/png.h b/png.h
index a2638bf..6da95a2 100644
--- a/png.h
+++ b/png.h
@@ -1,7 +1,7 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.0.5a - October 23, 1999
+ * libpng version 1.0.5f - December 6, 1999
  * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  * Copyright (c) 1996, 1997 Andreas Dilger
  * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
@@ -9,19 +9,19 @@
  * 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.5a - October 23, 1999: Glenn
+ *  libpng versions 0.97, January 1998, through 1.0.5f - December 6, 1999: Glenn
  *  See also "Contributing Authors", below.
  *
  * Y2K compliance in libpng:
  * =========================
  *    
- *    October 23, 1999
+ *    December 6, 1999
  *    
  *    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.71 and
- *    upward through 1.0.5a are Y2K compliant.  It is my belief that earlier
+ *    upward through 1.0.5f 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
@@ -97,7 +97,9 @@
  *    1.0.4                    1.0.4    10004  2.1.0.4
  *    1.0.4a-f                 1.0.4a-f 10005  2.1.0.4a-f
  *    1.0.5                    1.0.5    10005  2.1.0.5
- *    1.0.5a                   1.0.5a   10006  2.1.0.5a
+ *    1.0.5a-d                 1.0.5a-d 10006  2.1.0.5a-d
+ *    1.0.5e-f                 1.0.5e-f 10100  2.1.0.5e-f
+ *    1.1.0                    1.1.0    10100  3.1.0.0
  *
  *    Henceforth the source version will match the shared-library minor
  *    and patch numbers; the shared-library major version number will be
@@ -121,7 +123,7 @@
  * 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.5a, October 23, 1999)
+ * (libpng versions 0.97, January 1998, through 1.0.5f, December 6, 1999)
  *
  * For the purposes of this copyright and license, "Contributing Authors"
  * is defined as the following set of individuals:
@@ -134,6 +136,7 @@
  *    Tom Lane
  *    Dave Martindale
  *    Glenn Randers-Pehrson
+ *    Eric S. Raymond
  *    Greg Roelofs
  *    Guy Eric Schalnat
  *    Paul Schmidt
@@ -221,14 +224,14 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.0.5a"
+#define PNG_LIBPNG_VER_STRING "1.0.5f"
 
 /* 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    10006  /* 1.0.6 */
+#define PNG_LIBPNG_VER    10100  /* 1.1.0 */
 
 /* Note to maintainer: update this number in scripts/pngdef.pas as well */
 
@@ -237,19 +240,26 @@
 /* Version information for C files, stored in png.c.  This had better match
  * the version above.
  */
-extern char png_libpng_ver[12];   /* need room for 99.99.99aa */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (char) png_libpng_ver[12];   /* need room for 99.99.99aa */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
 
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
 /* Structures to facilitate easy interlacing.  See png.c for more details */
-extern int FARDATA png_pass_start[7];
-extern int FARDATA png_pass_inc[7];
-extern int FARDATA png_pass_ystart[7];
-extern int FARDATA png_pass_yinc[7];
-extern int FARDATA png_pass_mask[7];
-extern int FARDATA png_pass_dsp_mask[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_dsp_mask[7];
 /* These aren't currently used.  If you need them, see png.c for more details
-extern int FARDATA png_pass_width[7];
-extern int FARDATA png_pass_height[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_width[7];
+PNG_EXPORT_VAR (int FARDATA) png_pass_height[7];
 */
+#endif
 
 #endif /* PNG_NO_EXTERN */
 
@@ -288,17 +298,47 @@
 typedef png_color_8 FAR * png_color_8p;
 typedef png_color_8 FAR * FAR * png_color_8pp;
 
-/* png_text holds the text in a PNG file, and whether they are compressed
-   in the PNG file or not.  The "text" field points to a regular C string. */
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_spalette_entry_struct
+{
+   png_uint_16 red;
+   png_uint_16 green;
+   png_uint_16 blue;
+   png_uint_16 alpha;
+   png_uint_16 frequency;
+} png_spalette_entry;
+typedef png_spalette_entry FAR * png_spalette_entryp;
+typedef png_spalette_entry FAR * FAR * png_spalette_entrypp;
+
+typedef struct png_spalette_struct
+{
+   png_charp name;                /* palette name */
+   png_byte depth;                /* depth of palette samples */
+   png_spalette_entryp entries;        /* palette entries */
+   png_int_32 nentries;                /* number of palette entries */
+} png_spalette;
+typedef png_spalette FAR * png_spalette_p;
+typedef png_spalette FAR * FAR * png_spalette_pp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text chunk in a PNG file, and whether 
+ * that contents is compressed or not.  The "keyword" field points to a
+ * regular C string.  */
 typedef struct png_text_struct
 {
    int compression;        /* compression value, see PNG_TEXT_COMPRESSION_ */
    png_charp key;          /* keyword, 1-79 character description of "text" */
+   png_charp lang;         /* language code, 1-79 characters */
    png_charp text;         /* comment, may be an empty string (ie "") */
-   png_size_t text_length; /* length of "text" field */
+   /* text_length is no longer used, and now present for compatibility only */
+   png_size_t text_length; /* length of "text" field (not used any more) */
 } png_text;
 typedef png_text FAR * png_textp;
 typedef png_text FAR * FAR * png_textpp;
+#endif
 
 /* Supported compression types for text in PNG files (tEXt, and zTXt).
  * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
@@ -346,6 +386,21 @@
  * In any case, the order of the parameters in png_info_struct should NOT
  * be changed for as long as possible to keep compatibility with applications
  * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, text, pcal_purpose,
+ * pcal_units, pcal_params, iccp_name, iccp_profile, splt_palettes, and 
+ * scal_unit.  Of these, the text, pcal_*, iccp_*, splt_*, and scal_unit
+ * members are automatically freed when the info structure is deallocated. 
+ * The palette member is not.
+ *
+ * More allocation details: all the chunk-reading functions that change these
+ * members go through the corresponding png_set_* functions.  Functions to
+ * clear these members are available: see png_free_*.  The png_set_* functions
+ * do not depend on being able to point info structure members to any of the 
+ * storage they are passed (they make their own copies), EXCEPT that the 
+ * png_set_text function uses the same storage passed to them
+ * in the text_ptr or itxt_ptr structure argument.
  */
 typedef struct png_info_struct
 {
@@ -375,41 +430,42 @@
     * and initialize the appropriate fields below.
     */
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) || \
-    defined(PNG_READ_GAMMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
    /* The gAMA chunk describes the gamma characteristics of the system
     * on which the image was created, normally in the range [1.0, 2.5].
     * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
     */
    float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+#if defined(PNG_sRGB_SUPPORTED)
     /* GR-P, 0.96a */
     /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
    png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
-   /* The tEXt and zTXt chunks contain human-readable textual data in
-    * uncompressed and compressed forms, respectively.  The data in "text"
-    * is an array of pointers to uncompressed, null-terminated C strings.
-    * Each chunk has a keyword that describes the textual data contained
-    * in that chunk.  Keywords are not required to be unique, and the text
-    * string may be empty.  Any number of text chunks may be in an image.
+#if defined(PNG_TEXT_SUPPORTED)
+   /* The tEXt, and zTXt chunks contain human-readable textual data in
+    * uncompressed, compressed, and optionally compressed forms, respectively.
+    * The data in "text" is an array of pointers to uncompressed, 
+    * null-terminated C strings. Each chunk has a keyword that describes the
+    * textual data contained in that chunk.  Keywords are not required to be
+    * unique, and the text string may be empty.  Any number of text chunks may
+    * be in an image.
     */
    int num_text; /* number of comments read/to write */
    int max_text; /* current size of text array */
    png_textp text; /* array of comments read/to write */
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#endif /* PNG_TEXT_SUPPORTED */
+
+#if defined(PNG_tIME_SUPPORTED)
    /* The tIME chunk holds the last time the displayed image data was
     * modified.  See the png_time struct for the contents of this struct.
     */
    png_time mod_time;
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
    /* The sBIT chunk specifies the number of significant high-order bits
     * in the pixel data.  Values are in the range [1, bit_depth], and are
     * only specified for the channels in the pixel data.  The contents of
@@ -417,9 +473,10 @@
     * (valid & PNG_INFO_sBIT) is non-zero.
     */
    png_color_8 sig_bit; /* significant bits in color channels */
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \
-    defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* The tRNS chunk supplies transparency data for paletted images and
     * other image types that don't need a full alpha channel.  There are
     * "num_trans" transparency values for a paletted image, stored in the
@@ -431,9 +488,9 @@
     */
    png_bytep trans; /* transparent values for paletted image */
    png_color_16 trans_values; /* transparent color for non-palette image */
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \
-    defined(PNG_READ_BACKGROUND_SUPPORTED)
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    /* The bKGD chunk gives the suggested image background color if the
     * display program does not have its own background color and the image
     * is needs to composited onto a background before display.  The colors
@@ -441,18 +498,20 @@
     * pixel data.  Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
     */
    png_color_16 background;
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
    /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
     * and downwards from the top-left corner of the display, page, or other
     * application-specific co-ordinate space.  See the PNG_OFFSET_ defines
     * below for the unit types.  Valid if (valid & PNG_INFO_oFFs) non-zero.
     */
-   png_uint_32 x_offset; /* x offset on page */
-   png_uint_32 y_offset; /* y offset on page */
+   png_int_32 x_offset; /* x offset on page */
+   png_int_32 y_offset; /* y offset on page */
    png_byte offset_unit_type; /* offset units type */
-#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
    /* The pHYs chunk gives the physical pixel density of the image for
     * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
     * defines below).  Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
@@ -460,8 +519,9 @@
    png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
    png_uint_32 y_pixels_per_unit; /* vertical pixel density */
    png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
    /* The hIST chunk contains the relative frequency or importance of the
     * various palette entries, so that a viewer can intelligently select a
     * reduced-color palette, if required.  Data is an array of "num_palette"
@@ -469,8 +529,9 @@
     * is non-zero.
     */
    png_uint_16p hist;
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
    /* The cHRM chunk describes the CIE color characteristics of the monitor
     * on which the PNG was created.  This data allows the viewer to do gamut
     * mapping of the input image to ensure that the viewer sees the same
@@ -485,10 +546,11 @@
    float y_green;
    float x_blue;
    float y_blue;
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
    /* The pCAL chunk describes a transformation between the stored pixel
-    * values and original physcical data values used to create the image.
+    * values and original physical data values used to create the image.
     * The integer range [0, 2^bit_depth - 1] maps to the floating-point
     * range given by [pcal_X0, pcal_X1], and are further transformed by a
     * (possibly non-linear) transformation function given by "pcal_type"
@@ -506,8 +568,37 @@
    png_charpp pcal_params;  /* ASCII strings containing parameter values */
    png_byte pcal_type;      /* equation type (see PNG_EQUATION_ below) */
    png_byte pcal_nparams;   /* number of parameters given in pcal_params */
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+   /* iCCP chunk data. */
+   png_charp iccp_name;     /* profile name */
+   png_charp iccp_profile;  /* International Color Consortium profile data */
+   png_uint_32 iccp_proflen;  /* ICC profile data length */
+   png_byte iccp_compression; /* Always zero */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+   /* data on sPLT chunks (there may be more than one). */
+   png_spalette_p splt_palettes;
+   png_uint_32 splt_palettes_num;
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+   /* The sCAL chunk describes the actual physical dimensions of the 
+    * subject matter of the graphic.  The chunk contains a unit specification
+    * (an ASCII string), and two ASCII strings representing floating-point
+    * values.  The values are width and height corresponsing to one pixel
+    * in the image.  This external representation is converted to double
+    * here.  Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+    */
+   png_charp scal_unit;        /* unit of physical scale */
+   double scal_pixel_width;    /* width of one pixel */
+   double scal_pixel_height;   /* height of one pixel */
+#endif
+
 } png_info;
+
 typedef png_info FAR * png_infop;
 typedef png_info FAR * FAR * png_infopp;
 
@@ -558,12 +649,14 @@
 #define PNG_RESOLUTION_LAST       2 /* Not a valid value */
 
 /* These are for the sRGB chunk.  These values should NOT be changed. */
-#define PNG_sRGB_INTENT_SATURATION 0
-#define PNG_sRGB_INTENT_PERCEPTUAL 1
-#define PNG_sRGB_INTENT_ABSOLUTE   2
-#define PNG_sRGB_INTENT_RELATIVE   3
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE   1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE   3
 #define PNG_sRGB_INTENT_LAST       4 /* Not a valid value */
 
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH     79
 
 
 /* These determine if an ancillary chunk's data has been successfully read
@@ -583,6 +676,9 @@
 #define PNG_INFO_tIME 0x0200
 #define PNG_INFO_pCAL 0x0400
 #define PNG_INFO_sRGB 0x0800   /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000   /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000   /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000   /* ESR, 1.0.6 */
 
 /* This is used for the transformation routines, as some of them
  * change these values for the row.  It also should enable using
@@ -615,18 +711,19 @@
 typedef void (*png_flush_ptr) PNGARG((png_structp));
 typedef void (*png_read_status_ptr) PNGARG((png_structp, png_uint_32, int));
 typedef void (*png_write_status_ptr) PNGARG((png_structp, png_uint_32, int));
+
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop));
 typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop));
 typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
    png_uint_32, int));
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
 typedef void (*png_user_transform_ptr) PNGARG((png_structp,
     png_row_infop, png_bytep));
-#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */
+#endif
 
 typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
 typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
@@ -648,12 +745,15 @@
    png_rw_ptr write_data_fn;  /* function for writing output data */
    png_rw_ptr read_data_fn;   /* function for reading input data */
    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
+
 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
     defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    png_voidp user_transform_ptr; /* user supplied struct for user transform */
@@ -711,25 +811,29 @@
 
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
    png_uint_16 filler;           /* filler bytes for pixel expansion */
-#endif /* PNG_READ_FILLER_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_bKGD_SUPPORTED)
    png_byte background_gamma_type;
    float background_gamma;
    png_color_16 background;   /* background color in screen gamma space */
-#if defined(PNG_READ_GAMMA_SUPPORTED)
-   png_color_16 background_1; /* background normalized to gamma 1.0 */
-#endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
+#  if defined(PNG_READ_GAMMA_SUPPORTED)
+     png_color_16 background_1; /* background normalized to gamma 1.0 */
+#  endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */
 #endif /* PNG_READ_bKGD_SUPPORTED */
+
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
    png_flush_ptr output_flush_fn;/* Function for flushing output */
    png_uint_32 flush_dist;    /* how many rows apart to flush, 0 - no flush */
    png_uint_32 flush_rows;    /* number of rows written since last flush */
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    int gamma_shift;      /* number of "insignificant" bits 16-bit gamma */
    float gamma;          /* file gamma value */
    float screen_gamma;   /* screen gamma value (display_exponent) */
-#endif /* PNG_READ_GAMMA_SUPPORTED */
+#endif
+
 #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_from_1;    /* converts from 1.0 to screen */
@@ -737,18 +841,22 @@
    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 */
+#endif
+
 #if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED)
    png_color_8 sig_bit;       /* significant bits in each available channel */
-#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_READ_sBIT_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
    png_color_8 shift;         /* shift for significant bit tranformation */
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
  || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
    png_bytep trans;           /* transparency values for paletted files */
    png_color_16 trans_values; /* transparency values for non-paletted files */
-#endif /* PNG_READ|WRITE_tRNS_SUPPORTED||PNG_READ_EXPAND|BACKGROUND_SUPPORTED */
+#endif
+
    png_read_status_ptr read_row_fn;   /* called after each row is decoded */
    png_write_status_ptr write_row_fn; /* called after each row is encoded */
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
@@ -767,13 +875,16 @@
    png_size_t current_buffer_size;   /* amount of data now in current_buffer */
    int process_mode;                 /* what push library is currently doing */
    int cur_palette;                  /* current push library palette index */
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-   png_size_t current_text_size;     /* current size of text input data */
-   png_size_t current_text_left;     /* how much text left to read in input */
-   png_charp current_text;           /* current text chunk buffer */
-   png_charp current_text_ptr;       /* current location in current_text */
-#endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_tEXt/zTXt_SUPPORTED */
+
+#  if defined(PNG_READ_TEXT_SUPPORTED)
+     png_size_t current_text_size;   /* current size of text input data */
+     png_size_t current_text_left;   /* how much text left to read in input */
+     png_charp current_text;         /* current text chunk buffer */
+     png_charp current_text_ptr;     /* current location in current_text */
+#  endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_TEXT_SUPPORTED */
+
 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
 /* for the Borland special 64K segment handler */
    png_bytepp offset_table_ptr;
@@ -781,14 +892,17 @@
    png_uint_16 offset_table_number;
    png_uint_16 offset_table_count;
    png_uint_16 offset_table_count_free;
-#endif /* __TURBOC__&&!_Windows&&!__FLAT__ */
+#endif
+
 #if defined(PNG_READ_DITHER_SUPPORTED)
    png_bytep palette_lookup;         /* lookup table for dithering */
    png_bytep dither_index;           /* index translation for palette files */
-#endif /* PNG_READ_DITHER_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_READ_hIST_SUPPORTED)
    png_uint_16p hist;                /* histogram */
 #endif
+
 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
    png_byte heuristic_method;        /* heuristic for row filter selection */
    png_byte num_prev_filters;        /* number of weights for previous rows */
@@ -797,21 +911,25 @@
    png_uint_16p inv_filter_weights;  /* 1/weight(s) for previous line(s) */
    png_uint_16p filter_costs;        /* relative filter calculation cost */
    png_uint_16p inv_filter_costs;    /* 1/relative filter calculation cost */
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#endif
+
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_charp time_buffer;            /* String to hold RFC 1123 time text */
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
+
 #ifdef PNG_USER_MEM_SUPPORTED
    png_voidp mem_ptr;                /* user supplied struct for mem functions */
    png_malloc_ptr malloc_fn;         /* function for allocating memory */
    png_free_ptr free_fn;             /* function for freeing memory */
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
+
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    png_byte rgb_to_gray_status;
    png_byte rgb_to_gray_red_coeff;
    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;
@@ -819,9 +937,9 @@
 };
 
 /* This prevents a compiler error in png_get_copyright() in png.c if png.c
-and png.h are both at * version 1.0.5a
+and png.h are both at * version 1.0.5f
  */
-typedef png_structp version_1_0_5a;
+typedef png_structp version_1_0_5f;
 
 typedef png_struct FAR * FAR * png_structpp;
 
@@ -894,6 +1012,8 @@
 extern void png_info_init PNGARG((png_infop info_ptr));
 
 /* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
 extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
@@ -904,7 +1024,7 @@
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
 extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
    PNGARG((png_structp png_ptr, png_timep ptime));
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
 
 #if defined(PNG_WRITE_tIME_SUPPORTED)
 /* convert from a struct tm to png_time */
@@ -922,17 +1042,17 @@
 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 */
+#endif
 
 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
 /* Use blue, green, red order for pixels. */
 extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
 /* 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 */
+#endif
 
 #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
 /* Reduce RGB to grayscale. */
@@ -940,30 +1060,29 @@
    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 */
+#endif
 
 extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
    png_colorp palette));
 
 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
     defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
 /* Add a filler byte to 24-bit RGB images. */
 extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
    png_uint_32 filler, int flags));
-
 /* The values of the PNG_FILLER_ defines should NOT be changed */
 #define PNG_FILLER_BEFORE 0
 #define PNG_FILLER_AFTER 1
@@ -972,34 +1091,34 @@
 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
 /* 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 */
+#endif
 
 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
 /* 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 */
+#endif
 
 #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_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
 /* Converts files to legal bit depths. */
 extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
    png_color_8p true_bits));
-#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INTERLACING_SUPPORTED) || \
     defined(PNG_WRITE_INTERLACING_SUPPORTED)
 /* Have the code handle the interlacing.  Returns the number of passes. */
 extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
 /* Invert monocrome files */
 extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
-#endif /* PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
 /* Handle alpha and tRNS by replacing with a background color. */
@@ -1010,40 +1129,39 @@
 #define PNG_BACKGROUND_GAMMA_SCREEN  1
 #define PNG_BACKGROUND_GAMMA_FILE    2
 #define PNG_BACKGROUND_GAMMA_UNIQUE  3
-#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_16_TO_8_SUPPORTED)
 /* 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 */
+#endif
 
 #if defined(PNG_READ_DITHER_SUPPORTED)
 /* Turn on dithering, and reduce the palette to the number of colors available. */
 extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
    png_colorp palette, int num_palette, int maximum_colors,
    png_uint_16p histogram, int full_dither));
-#endif /* PNG_READ_DITHER_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_GAMMA_SUPPORTED)
 /* Handle gamma correction. Screen_gamma=(display_exponent) */
 extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
    double screen_gamma, double default_file_gamma));
-#endif /* PNG_READ_GAMMA_SUPPORTED */
+#endif
 
 #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 */
+#endif
 
 #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));
-
 /* Flush the current PNG output buffer */
 extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 
 /* optional update palette with requested transformations */
 extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
@@ -1282,10 +1400,9 @@
 /* Replace the default memory allocation functions with user supplied one(s). */
 extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
    png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
-
 /* Return the user pointer associated with the memory functions */
 extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
 #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
 extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
@@ -1342,7 +1459,7 @@
    png_uint_32 size));
 extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
    png_voidp ptr));
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
    png_voidp s1, png_voidp s2, png_uint_32 size));
@@ -1455,45 +1572,45 @@
 #if defined(PNG_READ_bKGD_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_16p *background));
-#endif /* PNG_READ_bKGD_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
+#if defined(PNG_bKGD_SUPPORTED)
 extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_16p background));
-#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_cHRM_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((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));
-#endif /* PNG_READ_cHRM_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
 extern PNG_EXPORT(void,png_set_cHRM) PNGARG((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));
-#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_gAMA_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double *file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
 extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
    png_infop info_ptr, double file_gamma));
-#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_hIST_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_16p *hist));
-#endif /* PNG_READ_hIST_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+#if defined(PNG_hIST_SUPPORTED)
 extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_16p hist));
-#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
@@ -1506,37 +1623,42 @@
 
 #if defined(PNG_READ_oFFs_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
-   png_infop info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y,
+   png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
    int *unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
 extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
-   png_infop info_ptr, png_uint_32 offset_x, png_uint_32 offset_y,
+   png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
    int unit_type));
-#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_pCAL_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((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));
-#endif /* PNG_READ_pCAL_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_pCAL_SUPPORTED)
 extern PNG_EXPORT(void,png_set_pCAL) PNGARG((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));
-#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_free_pCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
 
 #if defined(PNG_READ_pHYs_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
 extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
-#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */
+#endif
 
 extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_colorp *palette, int *num_palette));
@@ -1547,58 +1669,101 @@
 #if defined(PNG_READ_sBIT_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_8p *sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+#if defined(PNG_sBIT_SUPPORTED)
 extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_color_8p sig_bit));
-#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_sRGB_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int *intent));
-#endif /* PNG_READ_sRGB_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+#if defined(PNG_sRGB_SUPPORTED)
 extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int intent));
 extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
    png_infop info_ptr, int intent));
-#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
-/* png_get_text also returns the number of text chunks in text_ptr */
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charpp name, int *compression_type,
+   png_charpp profile, png_int_32 *proflen));
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp name, int compression_type,
+   png_charp profile, int proflen));
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_spalettes) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_spalette_pp entries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_spalettes) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_spalette_p entries, int nentries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_free_spallettes) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int num));
+#endif
+
+#if defined(PNG_READ_TEXT_SUPPORTED)
+/* png_get_text also returns the number of text chunks in *num_text */
 extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_textp *text_ptr, int *num_text));
-#endif /* PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_TEXT_SUPPORTED)
 extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_textp text_ptr, int num_text));
-#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */
+extern PNG_EXPORT(void,png_free_text) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, int num_text));
+#endif
 
 #if defined(PNG_READ_tIME_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_timep *mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#if defined(PNG_tIME_SUPPORTED)
 extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_timep mod_time));
-#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */
+#endif
 
 #if defined(PNG_READ_tRNS_SUPPORTED)
 extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_bytep *trans, int *num_trans,
    png_color_16p *trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED */
+#endif
 
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+#if defined(PNG_tRNS_SUPPORTED)
 extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_bytep trans, int num_trans,
    png_color_16p trans_values));
-#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charpp unit, double *width, double *height));
+#endif /* PNG_READ_sCAL_SUPPORTED */
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_charp unit, double width, double height));
+#endif /* PNG_READ_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_free_sCAL) PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif /* PNG_READ_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
 
 /* Define PNG_DEBUG at compile time for debugging information.  Higher
  * numbers for PNG_DEBUG mean more debugging information.  This has
@@ -1632,21 +1797,14 @@
 #define png_debug2(l, m, p1, p2)
 #endif
 
+extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((png_structp png_ptr));
+
 extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
 extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
 
-#ifdef PNG_NO_EXTERN
-/* this only gets included in png.c */
-
-#define PNG_GET_HEADER \
-png_charp \
-png_get_header_version(png_structp png_ptr) \
-{ \
-   if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ \
-      return("\n libpng version 1.0.5a - October 23, 1999 (header)\n"); \
-   return("\n libpng version 1.0.5a - October 23, 1999 (header)\n"); \
-}
-#endif
+#define PNG_HEADER_VERSION_STRING " libpng version 1.0.5f - December 6, 1999 (header)\n"
 
 #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
 /* With these routines we avoid an integer divide, which will be slower on
@@ -1700,25 +1858,19 @@
 /* Various modes of operation.  Note that after an init, mode is set to
  * zero automatically when the structure is created.
  */
-#define PNG_BEFORE_IHDR       0x00
-#define PNG_HAVE_IHDR         0x01
-#define PNG_HAVE_PLTE         0x02
-#define PNG_HAVE_IDAT         0x04
-#define PNG_AFTER_IDAT        0x08
-#define PNG_HAVE_IEND         0x10
-#define PNG_HAVE_gAMA         0x20
-#define PNG_HAVE_cHRM         0x40
-#define PNG_HAVE_sRGB         0x80
-
-/* push model modes */
-#define PNG_READ_SIG_MODE   0
-#define PNG_READ_CHUNK_MODE 1
-#define PNG_READ_IDAT_MODE  2
-#define PNG_SKIP_MODE       3
-#define PNG_READ_tEXt_MODE  4
-#define PNG_READ_zTXt_MODE  5
-#define PNG_READ_DONE_MODE  6
-#define PNG_ERROR_MODE      7
+#define PNG_BEFORE_IHDR             0x00
+#define PNG_HAVE_IHDR               0x01
+#define PNG_HAVE_PLTE               0x02
+#define PNG_HAVE_IDAT               0x04
+#define PNG_AFTER_IDAT              0x08
+#define PNG_HAVE_IEND               0x10
+#define PNG_HAVE_gAMA               0x20
+#define PNG_HAVE_cHRM               0x40
+#define PNG_HAVE_sRGB               0x80
+#define PNG_HAVE_CHUNK_HEADER      0x100
+#define PNG_WROTE_tIME             0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY     0x800
 
 /* flags for the transformations the PNG library does on the image data */
 #define PNG_BGR                0x0001
@@ -1772,9 +1924,7 @@
 #define PNG_FLAG_FREE_PALETTE             0x1000
 #define PNG_FLAG_FREE_TRANS               0x2000
 #define PNG_FLAG_FREE_HIST                0x4000
-#define PNG_FLAG_HAVE_CHUNK_HEADER        0x8000L
-#define PNG_FLAG_WROTE_tIME              0x10000L
-#define PNG_FLAG_BACKGROUND_IS_GRAY      0x20000L
+
 
 #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
                                      PNG_FLAG_CRC_ANCILLARY_NOWARN)
@@ -1793,30 +1943,61 @@
 /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
 #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
 /* place to hold the signature string for a PNG file. */
-extern png_byte FARDATA png_sig[8];
+#ifdef PNG_USE_GLOBAL_ARRAYS
+   PNG_EXPORT_VAR (png_byte FARDATA) png_sig[8];
+#else
+#define png_sig png_sig_bytes(NULL)
+#endif
 
 /* Constant strings for known chunk types.  If you need to add a chunk,
- * add a string holding the name here.  See png.c for more details.  We
- * can't selectively include these, since we still check for chunk in the
- * wrong locations with these labels.
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
  */
-extern png_byte FARDATA png_IHDR[5];
-extern png_byte FARDATA png_IDAT[5];
-extern png_byte FARDATA png_IEND[5];
-extern png_byte FARDATA png_PLTE[5];
-extern png_byte FARDATA png_bKGD[5];
-extern png_byte FARDATA png_cHRM[5];
-extern png_byte FARDATA png_gAMA[5];
-extern png_byte FARDATA png_hIST[5];
-extern png_byte FARDATA png_oFFs[5];
-extern png_byte FARDATA png_pCAL[5];
-extern png_byte FARDATA png_pHYs[5];
-extern png_byte FARDATA png_sBIT[5];
-extern png_byte FARDATA png_sRGB[5];
-extern png_byte FARDATA png_tEXt[5];
-extern png_byte FARDATA png_tIME[5];
-extern png_byte FARDATA png_tRNS[5];
-extern png_byte FARDATA png_zTXt[5];
+#define PNG_IHDR const png_byte png_IHDR[5] = { 73,  72,  68,  82, '\0'}
+#define PNG_IDAT const png_byte png_IDAT[5] = { 73,  68,  65,  84, '\0'}
+#define PNG_IEND const png_byte png_IEND[5] = { 73,  69,  78,  68, '\0'}
+#define PNG_PLTE const png_byte png_PLTE[5] = { 80,  76,  84,  69, '\0'}
+#define PNG_bKGD const png_byte png_bKGD[5] = { 98,  75,  71,  68, '\0'}
+#define PNG_cHRM const png_byte png_cHRM[5] = { 99,  72,  82,  77, '\0'}
+#define PNG_gAMA const png_byte png_gAMA[5] = {103,  65,  77,  65, '\0'}
+#define PNG_hIST const png_byte png_hIST[5] = {104,  73,  83,  84, '\0'}
+#define PNG_iCCP const png_byte png_iCCP[5] = {105,  67,  67,  80, '\0'}
+#define PNG_iTXt const png_byte png_iTXt[5] = {105,  84,  88, 116, '\0'}
+#define PNG_oFFs const png_byte png_oFFs[5] = {111,  70,  70, 115, '\0'}
+#define PNG_pCAL const png_byte png_pCAL[5] = {112,  67,  65,  76, '\0'}
+#define PNG_sCAL const png_byte png_sCAL[5] = {115,  67,  65,  76, '\0'}
+#define PNG_pHYs const png_byte png_pHYs[5] = {112,  72,  89, 115, '\0'}
+#define PNG_sBIT const png_byte png_sBIT[5] = {115,  66,  73,  84, '\0'}
+#define PNG_sPLT const png_byte png_sPLT[5] = {115,  80,  76,  84, '\0'}
+#define PNG_sRGB const png_byte png_sRGB[5] = {115,  82,  71,  66, '\0'}
+#define PNG_tEXt const png_byte png_tEXt[5] = {116,  69,  88, 116, '\0'}
+#define PNG_tIME const png_byte png_tIME[5] = {116,  73,  77,  69, '\0'}
+#define PNG_tRNS const png_byte png_tRNS[5] = {116,  82,  78,  83, '\0'}
+#define PNG_zTXt const png_byte png_zTXt[5] = {122,  84,  88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
 
 #endif /* PNG_NO_EXTERN */
 
@@ -1852,10 +2033,10 @@
  */
 extern void png_write_init PNGARG((png_structp png_ptr));
 
-/* allocate memory for an internal libpng struct */
+/* Allocate memory for an internal libpng struct */
 PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
 
-/* free memory from internal libpng struct */
+/* Free memory from internal libpng struct */
 PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
 
 PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
@@ -1863,17 +2044,17 @@
 PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
    png_free_ptr free_fn));
 
-/* free any memory that info_ptr points to and reset struct. */
+/* Free any memory that info_ptr points to and reset struct. */
 PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 
 /* Function to allocate memory for zlib. */
 PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
 
-/* function to free memory for zlib */
+/* Function to free memory for zlib */
 PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
 
-/* reset the CRC variable */
+/* Reset the CRC variable */
 PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
 
 /* Write the "data" buffer to whatever output you are using. */
@@ -1884,14 +2065,22 @@
 PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
    png_size_t length));
 
-/* read bytes into buf, and update png_ptr->crc */
+/* Read bytes into buf, and update png_ptr->crc */
 PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
    png_size_t length));
 
-/* read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_sPLT_SUPPORTED)
+PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
+   int comp_type, png_charp chunkdata, png_size_t chunklength,
+   png_size_t prefix_size));
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
 PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
 
-/* read the CRC from the file and compare it to the libpng calculated CRC */
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
 PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
 
 /* Calculate the CRC over a section of data.  Note that we are only
@@ -1963,6 +2152,17 @@
    int intent));
 #endif
 
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+   png_charp name, int compression_type,
+   png_charp profile, int proflen));
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, 
+                                       png_spalette_p palette));
+#endif
+
 #if defined(PNG_WRITE_tRNS_SUPPORTED)
 PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
    png_color_16p values, int number, int color_type));
@@ -1978,8 +2178,8 @@
    int num_hist));
 #endif
 
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
-    defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
    png_charp key, png_charpp new_key));
 #endif
@@ -1994,6 +2194,11 @@
    png_charp text, png_size_t text_len, int compression));
 #endif
 
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, 
+   int compression, png_charp key, png_charp lang, png_charp text));
+#endif
+
 #if defined(PNG_WRITE_oFFs_SUPPORTED)
 PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
    png_uint_32 x_offset, png_uint_32 y_offset, int unit_type));
@@ -2016,6 +2221,11 @@
    png_timep mod_time));
 #endif
 
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+   png_charp unit, double width, double height));
+#endif
+
 /* Called when finished processing a row of data */
 PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
 
@@ -2207,6 +2417,16 @@
    png_uint_32 length));
 #endif
 
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
 #if defined(PNG_READ_tRNS_SUPPORTED)
 PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
@@ -2232,6 +2452,11 @@
    png_uint_32 length));
 #endif
 
+#if defined(PNG_READ_sCAL_SUPPORTED)
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
 #if defined(PNG_READ_pHYs_SUPPORTED)
 PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
    png_uint_32 length));
@@ -2252,6 +2477,11 @@
    png_uint_32 length));
 #endif
 
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+   png_uint_32 length));
+#endif
+
 PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
    png_infop info_ptr, png_uint_32 length));
 
@@ -2306,6 +2536,12 @@
 PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
    png_infop info_ptr));
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+   png_infop info_ptr));
+#endif
 
 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
 
diff --git a/pngconf.h b/pngconf.h
index 6c81055..9884d04 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,7 +1,7 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -17,7 +17,9 @@
 #ifndef PNGCONF_H
 #define PNGCONF_H
 
-#define PNG_ZBUF_SIZE 524288
+#define PNG_NO_EASY_ACCESS
+#define PNG_NO_READ_EMPTY_PLTE
+#define PNG_NO_WRITE_TRANSFORMS
 #define PNG_READ_USER_TRANSFORM_SUPPORTED
 #define PNG_READ_STRIP_ALPHA_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
@@ -26,8 +28,10 @@
 #define PNG_READ_RGB_TO_GRAY_SUPPORTED
 #define PNG_READ_BACKGROUND_SUPPORTED
 #define PNG_READ_GAMMA_SUPPORTED
-#define PNG_NO_WRITE_TRANSFORMS
-#define PNG_NO_READ_EMPTY_PLTE
+#define PNG_ZBUF_SIZE 524288
+/*
+#define PNG_NO_GLOBAL_ARRAYS
+*/
 
 /* This is the size of the compression buffer, and thus the size of
  * an IDAT chunk.  Make this whatever size you feel is best for your
@@ -430,6 +434,16 @@
 #define PNG_ASSEMBLER_CODE_SUPPORTED
 #endif
 
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#ifdef PNG_NO_GLOBAL_ARRAYS
+#define PNG_USE_LOCAL_ARRAYS
+#else
+#define PNG_USE_GLOBAL_ARRAYS
+#endif
+
 /* These are currently experimental features, define them if you want */
 
 /* very little testing */
@@ -468,87 +482,191 @@
 #ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
 #ifndef PNG_NO_READ_bKGD
 #define PNG_READ_bKGD_SUPPORTED
+#define PNG_bKGD_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_cHRM
 #define PNG_READ_cHRM_SUPPORTED
+#define PNG_cHRM_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_gAMA
 #define PNG_READ_gAMA_SUPPORTED
+#define PNG_gAMA_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_hIST
 #define PNG_READ_hIST_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_iTXt_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_oFFs
 #define PNG_READ_oFFs_SUPPORTED
+#define PNG_oFFs_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_pCAL
 #define PNG_READ_pCAL_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_sCAL_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_pHYs
 #define PNG_READ_pHYs_SUPPORTED
+#define PNG_pHYs_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_sBIT
 #define PNG_READ_sBIT_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_sPLT_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_sRGB
 #define PNG_READ_sRGB_SUPPORTED
+#define PNG_sRGB_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tEXt
 #define PNG_READ_tEXt_SUPPORTED
+#define PNG_tEXt_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tIME
 #define PNG_READ_tIME_SUPPORTED
+#define PNG_tIME_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_tRNS
 #define PNG_READ_tRNS_SUPPORTED
+#define PNG_tRNS_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_zTXt
 #define PNG_READ_zTXt_SUPPORTED
+#define PNG_zTXt_SUPPORTED
 #endif
 #ifndef PNG_NO_READ_OPT_PLTE
 #define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the optional */
 #endif                              /* PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+  defined(PNG_READ_zTXt_SUPPORTED)
+#define PNG_READ_TEXT_SUPPORTED
+#define PNG_TEXT_SUPPORTED
+#endif
 #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
 
 #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 #ifndef PNG_NO_WRITE_bKGD
 #define PNG_WRITE_bKGD_SUPPORTED
+#ifndef PNG_bKGD_SUPPORTED
+#  define PNG_bKGD_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_cHRM
 #define PNG_WRITE_cHRM_SUPPORTED
+#ifndef PNG_cHRM_SUPPORTED
+#  define PNG_cHRM_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_gAMA
 #define PNG_WRITE_gAMA_SUPPORTED
+#ifndef PNG_gAMA_SUPPORTED
+#  define PNG_gAMA_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_hIST
 #define PNG_WRITE_hIST_SUPPORTED
+#ifndef PNG_hIST_SUPPORTED
+#  define PNG_hIST_SUPPORTED
+#endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+#define PNG_WRITE_iCCP_SUPPORTED
+#ifndef PNG_iCCP_SUPPORTED
+#  define PNG_iCCP_SUPPORTED
+#endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+#define PNG_WRITE_iTXt_SUPPORTED
+#ifndef PNG_iTXt_SUPPORTED
+#  define PNG_iTXt_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_oFFs
 #define PNG_WRITE_oFFs_SUPPORTED
+#ifndef PNG_oFFs_SUPPORTED
+#  define PNG_oFFs_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_pCAL
 #define PNG_WRITE_pCAL_SUPPORTED
+#ifndef PNG_pCAL_SUPPORTED
+#  define PNG_pCAL_SUPPORTED
+#endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+#define PNG_WRITE_sCAL_SUPPORTED
+#ifndef PNG_sCAL_SUPPORTED
+#  define PNG_sCAL_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_pHYs
 #define PNG_WRITE_pHYs_SUPPORTED
+#ifndef PNG_pHYs_SUPPORTED
+#  define PNG_pHYs_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_sBIT
 #define PNG_WRITE_sBIT_SUPPORTED
+#ifndef PNG_sBIT_SUPPORTED
+#  define PNG_sBIT_SUPPORTED
+#endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+#define PNG_WRITE_sPLT_SUPPORTED
+#ifndef PNG_sPLT_SUPPORTED
+#  define PNG_sPLT_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_sRGB
 #define PNG_WRITE_sRGB_SUPPORTED
+#ifndef PNG_sRGB_SUPPORTED
+#  define PNG_sRGB_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_tEXt
 #define PNG_WRITE_tEXt_SUPPORTED
+#ifndef PNG_tEXt_SUPPORTED
+#  define PNG_tEXt_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_tIME
 #define PNG_WRITE_tIME_SUPPORTED
+#ifndef PNG_tIME_SUPPORTED
+#  define PNG_tIME_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_tRNS
 #define PNG_WRITE_tRNS_SUPPORTED
+#ifndef PNG_tRNS_SUPPORTED
+#  define PNG_tRNS_SUPPORTED
+#endif
 #endif
 #ifndef PNG_NO_WRITE_zTXt
 #define PNG_WRITE_zTXt_SUPPORTED
+#ifndef PNG_zTXt_SUPPORTED
+#  define PNG_zTXt_SUPPORTED
+#endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+  defined(PNG_WRITE_zTXt_SUPPORTED)
+#define PNG_WRITE_TEXT_SUPPORTED
+#ifndef PNG_TEXT_SUPPORTED
+#  define PNG_TEXT_SUPPORTED
+#endif
 #endif
 #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
 
@@ -696,6 +814,28 @@
 #  define PNG_EXPORT(type,symbol) type symbol
 #endif
 
+#if defined(__MINGW32__) || defined(__CYGWIN32__)
+#  define PNG_ATTR_DLLIMP
+#endif
+
+#ifndef PNG_EXPORT_VAR
+#  ifdef PNG_DECL_DLLEXP
+#    define PNG_EXPORT_VAR(type) extern __declspec(dllexport) type
+#  endif
+#  ifdef PNG_ATTR_DLLEXP
+#    define PNG_EXPORT_VAR(type) extern type __attribute__((dllexport)) 
+#  endif
+#  ifdef PNG_DECL_DLLIMP
+#    define PNG_EXPORT_VAR(type) extern __declspec(dllimport) type
+#  endif
+#  ifdef PNG_ATTR_DLLIMP
+#    define PNG_EXPORT_VAR(type) extern type __attribute__((dllimport))
+#  endif
+#endif
+
+#ifndef PNG_EXPORT_VAR
+#    define PNG_EXPORT_VAR(type) extern type
+#endif
 
 /* User may want to use these so not in PNG_INTERNAL. Any library functions
  * that are passed far data must be model independent.
diff --git a/pngcrush.c b/pngcrush.c
index 617d65f..2a5f110 100644
--- a/pngcrush.c
+++ b/pngcrush.c
@@ -14,7 +14,7 @@
  * occasionally creating Linux executables.
  */
 
-#define PNGCRUSH_VERSION "1.2.0"
+#define PNGCRUSH_VERSION "1.2.1"
 
 /*
  * COPYRIGHT NOTICE, DISCLAIMER, AND LICENSE:
@@ -41,12 +41,26 @@
  *    or altered from any source or altered source distribution.
  */
 
-/* Version 1.2.*: check for unused alpha channel and ok-to-reduce-depth
- *                rearrange palette to put most-used color first and
- *                transparent color second.
+/* To do:
+ *
+ * Version 1.2.*: check for unused alpha channel and ok-to-reduce-depth.
+ *   Rearrange palette to put most-used color first and
+ *   transparent color second.
+ *
+ * Version 1.2.2: Add iCCP, iTXt, sCAL, and sPLT support, which are
+ *   now supported by libpng.
+ *
+ * Change log:
+ *
+ * Version 1.2.1: Fixed -srgb parameter so it really does take an argument,
+ *   and so it continues to use "0" if an integer does not follow the -srgb.
+ *   Added "-plte_len n" argument for truncating the PLTE.  Be sure not to
+ *   truncate it to less than the greatest index actually appearing in IDAT.
  *
  * Version 1.2.0: Removed registration requirement.  Added open source
- * license.  Redefined TOO_FAR=32k in deflate.c
+ *   license.  Redefined TOO_FAR=32k in deflate.c.
+ *
+ * Changes prior to going "open source":
  *
  * Version 1.1.8: built with libpng-1.0.5a.  Runs OK with pngvcrd.c.
  *
@@ -165,6 +179,7 @@
 static int best_of_three;
 static int methods_specified=0;
 static int intent=-1;
+static int plte_len=-1;
 static double specified_gamma=0.;
 static double force_specified_gamma=0.;
 static int double_gamma=0;
@@ -697,6 +712,11 @@
       nosave++;
       pngcrush_mode=EXTENSION_MODE;
       }
+   else if(!strncmp(argv[i],"-plte_len",9))
+      {
+         names++;
+         plte_len=atoi(argv[++i]);
+      }
    else if(!strncmp(argv[i],"-p",2))
       {
       pauses++;
@@ -721,10 +741,19 @@
    else if( !strncmp(argv[i],"-srgb",5) ||
             !strncmp(argv[i],"-sRGB",5))
       {
-         names++;
          specified_gamma=.45455;
          intent=0;
          i++;
+         if(!strncmp(argv[i],"0",1) ||
+            !strncmp(argv[i],"1",1) ||
+            !strncmp(argv[i],"2",1) ||
+            !strncmp(argv[i],"3",1))
+           {
+             names++;
+             intent=(int)atoi(argv[i]);
+           }
+         else
+           i--;
       }
    else if(!strncmp(argv[i],"-s",2))
       {
@@ -1054,6 +1083,16 @@
        "\n               Useful in conjunction with -v option to get info.\n\n");
 
      fprintf(STDERR,
+       "            -plte_len n (truncate PLTE)\n");
+     if(verbose > 1)
+     {
+     fprintf(STDERR,
+       "\n               Truncates the PLTE.  Be sure not to truncate it to\n");
+     fprintf(STDERR,
+       "\n               less than the greatest index present in IDAT.\n");
+ 
+     }
+     fprintf(STDERR,
        "            -q (quiet)\n");
      if(verbose > 1)
         fprintf(STDERR,"\n");
@@ -1173,7 +1212,7 @@
      fprintf(STDERR,
        "\n               zlib compression strategy to use with the preceding\n");
      fprintf(STDERR,
-       "               preceding '-m method' argument.\n\n");
+       "               '-m method' argument.\n\n");
      }
 #if 0
      fprintf(STDERR,
@@ -1558,7 +1597,7 @@
         (png_bytep)png_malloc(read_ptr, (png_uint_32)read_ptr->zbuf_size);
       }
       if(nosave == 0)
-      if(write_ptr->zbuf_size < (png_size_t)max_idat_size)
+      if(write_ptr->zbuf_size > (png_size_t)max_idat_size)
       {
       if(verbose > 2)
          printf("reinitializing write zbuf.\n");
@@ -1697,6 +1736,7 @@
 
                png_set_compression_window_bits(write_ptr, compression_window);
             }
+
             if(verbose > 1)
                 fprintf(STDERR, "   Setting IHDR\n");
 
@@ -1833,7 +1873,7 @@
 #endif
 #if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
       {
-         png_uint_32 offset_x, offset_y;
+         png_int_32 offset_x, offset_y;
          int unit_type;
 
          if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
@@ -1993,6 +2033,8 @@
 
      if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
      {
+        if (plte_len > 0)
+           num_palette=plte_len;
         if(output_color_type == 3)
            png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
         else if(keep_chunk("PLTE",argv))
@@ -2477,6 +2519,10 @@
 
    for(;;)
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+      PNG_IEND;
+#endif
       png_byte chunk_length[4];
       png_byte chunk_name[5];
       png_uint_32 length;
diff --git a/pngerror.c b/pngerror.c
index b10072d..b1674eb 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -1,7 +1,7 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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 96204f1..dd92fb0 100644
--- a/pngget.c
+++ b/pngget.c
@@ -1,7 +1,7 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -104,7 +104,7 @@
 png_uint_32
 png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
@@ -120,7 +120,7 @@
 png_uint_32
 png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
@@ -136,7 +136,7 @@
 png_uint_32
 png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
@@ -153,7 +153,7 @@
 float
 png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
    {
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_pHYs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
@@ -171,7 +171,7 @@
 png_uint_32
 png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
@@ -187,7 +187,7 @@
 png_uint_32
 png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
@@ -203,7 +203,7 @@
 png_uint_32
 png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
@@ -219,7 +219,7 @@
 png_uint_32
 png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    {
       png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
@@ -403,6 +403,39 @@
 }
 #endif
 
+#if defined(PNG_READ_iCCP_SUPPORTED)
+png_uint_32
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charpp name, int *compression_type,
+             png_charpp profile, png_int_32 *proflen)
+{
+   if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+      && name != NULL && profile != NULL && proflen != NULL)
+   {
+      png_debug1(1, "in %s retrieval function\n", "iCCP");
+      *name = info_ptr->iccp_name;
+      *profile = info_ptr->iccp_profile;
+      /* compression_type is a dummy so the API won't have to change
+         if we introduce multiple compression types later. */
+      *proflen = (int)info_ptr->iccp_proflen;
+      *compression_type = (int)info_ptr->iccp_compression;
+      return (PNG_INFO_iCCP);
+   }
+   return (0);
+}
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+png_uint_32
+png_get_spalettes(png_structp png_ptr, png_infop info_ptr, 
+             png_spalette_pp spalettes)
+{
+   if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+     *spalettes = info_ptr->splt_palettes;
+   return ((png_uint_32)info_ptr->splt_palettes_num);
+}
+#endif
+
 #if defined(PNG_READ_hIST_SUPPORTED)
 png_uint_32
 png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
@@ -467,7 +500,7 @@
 #if defined(PNG_READ_oFFs_SUPPORTED)
 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)
+   png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
 {
    if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
       && offset_x != NULL && offset_y != NULL && unit_type != NULL)
@@ -506,6 +539,22 @@
 }
 #endif
 
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+png_uint_32
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+             png_charpp unit, double *width, double *height)
+{
+    if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_sCAL)
+    {
+        *unit = info_ptr->scal_unit;
+        *width = info_ptr->scal_pixel_width;
+        *height = info_ptr->scal_pixel_height;
+        return (PNG_INFO_sCAL);
+    }
+    return(0);
+}
+#endif
+
 #if defined(PNG_READ_pHYs_SUPPORTED)
 png_uint_32
 png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
@@ -567,7 +616,7 @@
 }
 #endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+#if defined(PNG_READ_TEXT_SUPPORTED)
 png_uint_32
 png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
    int *num_text)
diff --git a/pngmem.c b/pngmem.c
index 35f4980..18f7d98 100644
--- a/pngmem.c
+++ b/pngmem.c
@@ -1,7 +1,7 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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/pngpread.c b/pngpread.c
index 98108f3..691936c 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1,7 +1,7 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -13,6 +13,17 @@
 
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
 
+/* push model modes */
+#define PNG_READ_SIG_MODE   0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE  2
+#define PNG_SKIP_MODE       3
+#define PNG_READ_tEXt_MODE  4
+#define PNG_READ_zTXt_MODE  5
+#define PNG_READ_DONE_MODE  6
+#define PNG_READ_iTXt_MODE  7
+#define PNG_ERROR_MODE      8
+
 void
 png_process_data(png_structp png_ptr, png_infop info_ptr,
    png_bytep buffer, png_size_t buffer_size)
@@ -62,6 +73,13 @@
          break;
       }
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      case PNG_READ_iTXt_MODE:
+      {
+         png_push_read_iTXt(png_ptr, info_ptr);
+         break;
+      }
+#endif
       case PNG_SKIP_MODE:
       {
          png_push_crc_finish(png_ptr);
@@ -116,13 +134,58 @@
 void
 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
    /* First we make sure we have enough data for the 4 byte chunk name
     * and the 4 byte chunk length before proceeding with decoding the
     * chunk data.  To fully decode each of these chunks, we also make
     * sure we have enough data in the buffer for the 4 byte CRC at the
     * end of every chunk (except IDAT, which is handled separately).
     */
-   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    {
       png_byte chunk_length[4];
 
@@ -136,7 +199,7 @@
       png_ptr->push_length = png_get_uint_32(chunk_length);
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    }
 
    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
@@ -159,7 +222,7 @@
 
       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    }
-   else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+   else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
    {
       /* If we reach an IDAT chunk, this means we have read all of the
        * header chunks, and we can start reading the image (or if this
@@ -338,12 +401,18 @@
       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
    }
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+   else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+   {
+      png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+   }
+#endif
    else
    {
       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    }
 
-   png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+   png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
 }
 
 void
@@ -496,7 +565,10 @@
 void
 png_push_read_IDAT(png_structp png_ptr)
 {
-   if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
+   if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    {
       png_byte chunk_length[4];
 
@@ -511,9 +583,9 @@
 
       png_reset_crc(png_ptr);
       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-      png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
 
-      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+      if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
       {
          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
@@ -576,7 +648,7 @@
       }
 
       png_crc_finish(png_ptr, 0);
-      png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER;
+      png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    }
 }
 
@@ -767,6 +839,32 @@
 void
 png_read_push_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+   
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+   
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+   
+   /* Width of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+   */
+   
+   /* Height of interlace block.  This is not currently used - if you need
+    * it, uncomment it here and in png.h
+   const int png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+   */
+#endif
+   
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
       return;
@@ -878,6 +976,7 @@
 
       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+      text_ptr->lang = (char *)NULL;
       text_ptr->key = key;
       text_ptr->text = text;
 
@@ -1057,6 +1156,101 @@
 
       text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+      text_ptr->lang = (char *)NULL;
+      text_ptr->key = key;
+      text_ptr->text = text;
+
+      png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+      png_free(png_ptr, text_ptr);
+   }
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+void
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
+      {
+         png_error(png_ptr, "Out of place iTXt");
+         /* to quiet some compiler warnings */
+         if(info_ptr == NULL) return;
+      }
+
+#ifdef PNG_MAX_MALLOC_64K
+   png_ptr->skip_length = 0;  /* This may not be necessary */
+
+   if (length > (png_uint_32)65535L) /* Can't hold the entire string in memory */
+   {
+      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+      png_ptr->skip_length = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+         (png_uint_32)(length+1));
+   png_ptr->current_text[length] = '\0';
+   png_ptr->current_text_ptr = png_ptr->current_text;
+   png_ptr->current_text_size = (png_size_t)length;
+   png_ptr->current_text_left = (png_size_t)length;
+   png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+   if (png_ptr->buffer_size && png_ptr->current_text_left)
+   {
+      png_size_t text_size;
+
+      if (png_ptr->buffer_size < png_ptr->current_text_left)
+         text_size = png_ptr->buffer_size;
+      else
+         text_size = png_ptr->current_text_left;
+      png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+      png_ptr->current_text_left -= text_size;
+      png_ptr->current_text_ptr += text_size;
+   }
+   if (!(png_ptr->current_text_left))
+   {
+      png_textp text_ptr;
+      png_charp text;
+      png_charp lang;
+      png_charp key;
+
+      if (png_ptr->buffer_size < 4)
+      {
+         png_push_save_buffer(png_ptr);
+         return;
+      }
+
+      png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+      if (png_ptr->skip_length)
+         return;
+#endif
+
+      lang = png_ptr->current_text;
+      png_ptr->current_text = 0;
+
+      for (key = lang; *key; key++)
+         /* empty loop */ ;
+
+      if (key != lang + png_ptr->current_text_size)
+         key++;
+
+      for (text = key; *text; text++)
+         /* empty loop */ ;
+
+      if (text != key + png_ptr->current_text_size)
+         text++;
+
+      text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+      text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+      text_ptr->lang = lang;
       text_ptr->key = key;
       text_ptr->text = text;
 
@@ -1115,6 +1309,9 @@
 png_progressive_combine_row (png_structp png_ptr,
    png_bytep old_row, png_bytep new_row)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
 }
diff --git a/pngread.c b/pngread.c
index cd07bb4..ddad581 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,7 +1,7 @@
 
 /* pngread.c - read a PNG file
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -63,7 +63,7 @@
 
 #ifdef PNG_USER_MEM_SUPPORTED
    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
 
@@ -179,6 +179,63 @@
 
    for(;;)
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
       png_byte chunk_length[4];
       png_uint_32 length;
 
@@ -236,6 +293,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
          png_handle_pCAL(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_pHYs_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
          png_handle_pHYs(png_ptr, info_ptr, length);
@@ -248,6 +309,14 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
          png_handle_sRGB(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_tEXt_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
          png_handle_tEXt(png_ptr, info_ptr, length);
@@ -264,6 +333,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
          png_handle_zTXt(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
       else
          png_handle_unknown(png_ptr, info_ptr, length);
    }
@@ -297,6 +370,11 @@
 void
 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+   const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+   const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+#endif
    int ret;
    png_debug2(1, "in png_read_row (row %d, pass %d)\n",
       png_ptr->row_number, png_ptr->pass);
@@ -529,7 +607,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.5a.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.5f.
  */
 
 void
@@ -578,7 +656,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.5a.
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.5f.
  */
 void
 png_read_image(png_structp png_ptr, png_bytepp image)
@@ -630,6 +708,64 @@
 
    do
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IHDR;
+      PNG_IDAT;
+      PNG_IEND;
+      PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+      PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+      PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+      PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+      PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+      PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+      PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+      PNG_sBIT;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+      PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+      PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+      PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+      PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+      PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+      PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+
       png_read_data(png_ptr, chunk_length, 4);
       length = png_get_uint_32(chunk_length);
 
@@ -678,6 +814,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
          png_handle_pCAL(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+         png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_pHYs_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
          png_handle_pHYs(png_ptr, info_ptr, length);
@@ -690,6 +830,14 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
          png_handle_sRGB(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+         png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+         png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
 #if defined(PNG_READ_tEXt_SUPPORTED)
       else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
          png_handle_tEXt(png_ptr, info_ptr, length);
@@ -706,6 +854,10 @@
       else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
          png_handle_zTXt(png_ptr, info_ptr, length);
 #endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+      else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+         png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
       else
          png_handle_unknown(png_ptr, info_ptr, length);
    } while (!(png_ptr->mode & PNG_HAVE_IEND));
@@ -720,7 +872,7 @@
    png_infop info_ptr = NULL, end_info_ptr = NULL;
 #ifdef PNG_USER_MEM_SUPPORTED
    png_free_ptr free_fn = NULL;
-#endif /* PNG_USER_MEM_SUPPORTED */
+#endif
 
    png_debug(1, "in png_destroy_read_struct\n");
    /* save jump buffer and error functions */
@@ -741,7 +893,7 @@
 
    if (info_ptr != NULL)
    {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+#if defined(PNG_TEXT_SUPPORTED)
       png_free(png_ptr, info_ptr->text);
 #endif
 
@@ -755,7 +907,7 @@
 
    if (end_info_ptr != NULL)
    {
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
+#if defined(PNG_READ_TEXT_SUPPORTED)
       png_free(png_ptr, end_info_ptr->text);
 #endif
 #ifdef PNG_USER_MEM_SUPPORTED
@@ -813,7 +965,7 @@
 #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) || \
+#if defined(PNG_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);
@@ -858,7 +1010,7 @@
 #endif
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
 
    inflateEnd(&png_ptr->zstream);
 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
diff --git a/pngrio.c b/pngrio.c
index ba1c996..a8c1657 100644
--- a/pngrio.c
+++ b/pngrio.c
@@ -1,7 +1,7 @@
 
 /* pngrio.c - functions for data input
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -146,6 +146,6 @@
 
 #if defined(PNG_WRITE_FLUSH_SUPPORTED)
    png_ptr->output_flush_fn = NULL;
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 }
 
diff --git a/pngrtran.c b/pngrtran.c
index 693befc..9215bfa 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.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -92,13 +92,13 @@
    /* Note:  if need_expand is set and color_type is either RGB or RGB_ALPHA
     * (in which case need_expand is superfluous anyway), the background color
     * might actually be gray yet not be flagged as such. This is not a problem
-    * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to
+    * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
     * decide when to do the png_do_gray_to_rgb() transformation.
     */
    if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
        (!need_expand && background_color->red == background_color->green &&
         background_color->red == background_color->blue))
-      png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY;
+      png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
 }
 #endif
 
@@ -1171,7 +1171,7 @@
    /* if gray -> RGB, do so now only if background is non-gray; else do later
     * for performance reasons */
    if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
-       !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY))
+       !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 #endif
 
@@ -1245,7 +1245,7 @@
 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
    /* if gray -> RGB, do so now only if we did not do so above */
    if (png_ptr->transformations & PNG_GRAY_TO_RGB &&
-       png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)
+       png_ptr->mode & PNG_BACKGROUND_IS_GRAY)
       png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
 #endif
 
diff --git a/pngrutil.c b/pngrutil.c
index 7d10313..4669b4e 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1,7 +1,7 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -136,6 +136,125 @@
       return (0);
 }
 
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+    defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_sPLT_SUPPORTED)
+/*
+ * Decompress trailing data in a chunk.  The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part.  What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+png_charp png_decompress_chunk(png_structp png_ptr, int comp_type, 
+                              png_charp chunkdata, png_size_t chunklength,
+                              png_size_t prefix_size)
+{
+   static char msg[] = "Error decoding compressed text";
+   png_charp text = NULL;
+   png_size_t text_size = (chunklength - prefix_size);
+
+   if (comp_type == PNG_TEXT_COMPRESSION_zTXt)
+   {
+      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
+      png_ptr->zstream.next_out = png_ptr->zbuf;
+      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+      text_size = 0;
+      text = NULL;
+
+      while (png_ptr->zstream.avail_in)
+      {
+         int ret;
+
+         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+         if (ret != Z_OK && ret != Z_STREAM_END)
+         {
+            if (png_ptr->zstream.msg != NULL)
+               png_warning(png_ptr, png_ptr->zstream.msg);
+            else
+               png_warning(png_ptr, msg);
+            inflateReset(&png_ptr->zstream);
+            png_ptr->zstream.avail_in = 0;
+
+            if (text ==  NULL)
+            {
+               text_size = prefix_size + sizeof(msg) + 1;
+               text = (png_charp)png_malloc(png_ptr, text_size);
+               png_memcpy(text, chunkdata, prefix_size);
+            }
+
+            text[text_size - 1] = 0x00;
+
+            /* Copy what we can of the error message into the text chunk */
+            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
+            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+            png_memcpy(text + prefix_size, msg, text_size + 1);
+            break;
+         }
+         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+         {
+            if (text == NULL)
+            {
+               text_size = prefix_size + 
+                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               text = (png_charp)png_malloc(png_ptr, text_size + 1);
+               png_memcpy(text + prefix_size, png_ptr->zbuf,
+                          text_size - prefix_size);
+               png_memcpy(text, chunkdata, prefix_size);
+               *(text + text_size) = 0x00;
+            }
+            else
+            {
+               png_charp tmp;
+
+               tmp = text;
+               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
+                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+               png_memcpy(text, tmp, text_size);
+               png_free(png_ptr, tmp);
+               png_memcpy(text + text_size, png_ptr->zbuf,
+                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+               *(text + text_size) = 0x00;
+            }
+            if (ret == Z_STREAM_END)
+               break;
+            else
+            {
+               png_ptr->zstream.next_out = png_ptr->zbuf;
+               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+            }
+         }
+      }
+
+      inflateReset(&png_ptr->zstream);
+      png_ptr->zstream.avail_in = 0;
+
+      png_free(png_ptr, chunkdata);
+      chunkdata = text;
+   }
+   else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
+   {
+      png_size_t text_size;
+#if !defined(PNG_NO_STDIO)
+      char umsg[50];
+
+      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+      png_warning(png_ptr, umsg);
+#else
+      png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+      /* Copy what we can of the error message into the text chunk */
+      text_size = (png_size_t)(chunklength - (text - chunkdata));
+      text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+      png_memcpy(text, msg, text_size);
+   }
+
+   return chunkdata;
+}
+#endif
 
 /* read and check the IDHR chunk */
 void
@@ -726,6 +845,195 @@
 }
 #endif /* PNG_READ_sRGB_SUPPORTED */
 
+#if defined(PNG_READ_iCCP_SUPPORTED)
+void
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_charp chunkdata;
+   png_byte compression_type; 
+   png_charp profile;
+   png_uint_32 skip = 0;
+   png_size_t slength, prefix_length;
+
+   png_debug(1, "in png_handle_iCCP\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iCCP");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid iCCP after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place iCCP chunk");
+
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_iCCP)
+   {
+      png_warning(png_ptr, "Duplicate iCCP chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (profile = chunkdata; *profile; profile++)
+      /* empty loop to find end of name */ ;
+   ++profile;
+
+   /* there should be at least one NUL (the compression type byte)
+      following the separator, and we should be on it  */
+   if (profile >= chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_error(png_ptr, "malformed iCCP chunk");
+   }
+
+   /* compression should always be zero */
+   compression_type = *profile++;
+
+   prefix_length = profile - chunkdata;
+   chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
+                                    slength, prefix_length);
+
+   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
+                chunkdata + prefix_length, png_strlen(chunkdata + prefix_length));
+   png_free(png_ptr, chunkdata);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+void
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+   png_bytep chunkdata;
+   png_bytep entry_start;
+   png_spalette new_palette;
+   int data_length, entry_size, i;
+   png_uint_32 skip = 0;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sPLT\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sPLT");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sPLT after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (png_ptr->mode & PNG_HAVE_PLTE)
+      /* Should be an error, but we can cope with it */
+      png_warning(png_ptr, "Out of place sPLT chunk");
+
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sPLT)
+   {
+      png_warning(png_ptr, "Duplicate sPLT chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+#ifdef PNG_MAX_MALLOC_64K
+   if (length > (png_uint_32)65535L)
+   {
+      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+      skip = length - (png_uint_32)65535L;
+      length = (png_uint_32)65535L;
+   }
+#endif
+
+   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, chunkdata, slength);
+
+   if (png_crc_finish(png_ptr, skip))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (entry_start = chunkdata; *entry_start; entry_start++)
+      /* empty loop to find end of name */ ;
+   ++entry_start;
+
+   /* a sample depth should follow the separator, and we should be on it  */
+   if (entry_start > chunkdata + slength)
+   {
+      png_free(png_ptr, chunkdata);
+      png_error(png_ptr, "malformed sPLT chunk");
+   }
+
+   new_palette.depth = *entry_start++;
+   entry_size = (new_palette.depth == 8 ? 6 : 10);
+   data_length = (slength - (entry_start - chunkdata));
+
+   /* integrity-check the data length */
+   if (data_length % entry_size)
+   {
+      png_free(png_ptr, chunkdata);
+      png_error(png_ptr, "sPLT chunk has bad length");
+   }
+
+   new_palette.nentries = data_length / entry_size;
+   new_palette.entries = (png_spalette_entryp)png_malloc(
+       png_ptr, new_palette.nentries * sizeof(png_spalette_entry));
+
+   for (i = 0; i < new_palette.nentries; i++)
+   {
+      png_spalette_entryp pp = new_palette.entries + i;
+
+      if (new_palette.depth == 8)
+      {
+          pp->red = *entry_start++;
+          pp->green = *entry_start++;
+          pp->blue = *entry_start++;
+          pp->alpha = *entry_start++;
+      }
+      else
+      {
+          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
+          pp->green = png_get_uint_16(entry_start); entry_start += 2;
+          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
+          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+      }
+      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+   }
+
+   /* discard all chunk data except the name and stash that */
+   new_palette.name = (png_charp)chunkdata;
+
+   png_set_spalettes(png_ptr, info_ptr, &new_palette, 1);
+
+   png_free(png_ptr, chunkdata);
+   png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
 #if defined(PNG_READ_tRNS_SUPPORTED)
 void
 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -1012,7 +1320,7 @@
 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
    png_byte buf[9];
-   png_uint_32 offset_x, offset_y;
+   png_int_32 offset_x, offset_y;
    int unit_type;
 
    png_debug(1, "in png_handle_oFFs\n");
@@ -1043,8 +1351,8 @@
    if (png_crc_finish(png_ptr, 0))
       return;
 
-   offset_x = png_get_uint_32(buf);
-   offset_y = png_get_uint_32(buf + 4);
+   offset_x = png_get_int_32(buf);
+   offset_y = png_get_int_32(buf + 4);
    unit_type = buf[8];
    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
 }
@@ -1167,6 +1475,77 @@
 }
 #endif
 
+#if defined(PNG_READ_sCAL_SUPPORTED)
+/* read the sCAL chunk */
+void
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_charp unit, ep, vp;
+   double width, height;
+   png_size_t slength;
+
+   png_debug(1, "in png_handle_sCAL\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before sCAL");
+   else if (png_ptr->mode & PNG_HAVE_IDAT)
+   {
+      png_warning(png_ptr, "Invalid sCAL after IDAT");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+   else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sCAL)
+   {
+      png_warning(png_ptr, "Duplicate sCAL chunk");
+      png_crc_finish(png_ptr, length);
+      return;
+   }
+
+   png_debug1(2, "Allocating and reading sCAL chunk data (%d bytes)\n",
+      length + 1);
+   unit = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)unit, slength);
+
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, unit);
+      return;
+   }
+
+   unit[slength] = 0x00; /* null terminate the last string */
+
+   png_debug(3, "Finding end of sCAL unit string\n");
+   for (ep = unit; *ep; ep++)
+      /* empty loop */ ;
+   ep++;
+
+   width = strtod(ep, &vp);
+   if (*vp)
+       png_error(png_ptr, "malformed width string in sCAL chunk");
+
+   for (ep = unit; *ep; ep++)
+      /* empty loop */ ;
+   ep++;
+
+   height = strtod(ep, &vp);
+   if (*vp)
+       png_error(png_ptr, "malformed height string in sCAL chunk");
+
+   if (unit + slength < ep || width <= 0. || height <= 0.)
+   {
+      png_warning(png_ptr, "Invalid sCAL data");
+      png_free(png_ptr, unit);
+      return;
+   }
+
+
+   png_set_sCAL(png_ptr, info_ptr, unit, width, height);
+
+   png_free(png_ptr, unit);
+}
+#endif
+
 #if defined(PNG_READ_tIME_SUPPORTED)
 void
 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -1258,6 +1637,7 @@
 
    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+   text_ptr->lang = NULL;
    text_ptr->key = key;
    text_ptr->text = text;
 
@@ -1273,12 +1653,11 @@
 void
 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
-   static char msg[] = "Error decoding zTXt chunk";
    png_textp text_ptr;
-   png_charp key;
+   png_charp chunkdata;
    png_charp text;
    int comp_type = PNG_TEXT_COMPRESSION_NONE;
-   png_size_t slength;
+   png_size_t slength, prefix_len;
 
    png_debug(1, "in png_handle_zTXt\n");
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
@@ -1298,142 +1677,128 @@
    }
 #endif
 
-   key = (png_charp)png_malloc(png_ptr, length + 1);
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
    slength = (png_size_t)length;
-   png_crc_read(png_ptr, (png_bytep)key, slength);
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
    if (png_crc_finish(png_ptr, 0))
    {
-      png_free(png_ptr, key);
+      png_free(png_ptr, chunkdata);
       return;
    }
 
-   key[slength] = 0x00;
+   chunkdata[slength] = 0x00;
 
-   for (text = key; *text; text++)
+   for (text = chunkdata; *text; text++)
       /* empty loop */ ;
 
-   /* zTXt must have some text after the keyword */
-   if (text == key + slength)
+   /* zTXt must have some text after the chunkdataword */
+   if (text == chunkdata + slength)
    {
+      comp_type = PNG_TEXT_COMPRESSION_NONE;
       png_warning(png_ptr, "Zero length zTXt chunk");
    }
-   else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
+   else
    {
-      png_size_t text_size, key_size;
-      text++;
-
-      png_ptr->zstream.next_in = (png_bytep)text;
-      png_ptr->zstream.avail_in = (uInt)(length - (text - key));
-      png_ptr->zstream.next_out = png_ptr->zbuf;
-      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-
-      key_size = (png_size_t)(text - key);
-      text_size = 0;
-      text = NULL;
-
-      while (png_ptr->zstream.avail_in)
-      {
-         int ret;
-
-         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-         if (ret != Z_OK && ret != Z_STREAM_END)
-         {
-            if (png_ptr->zstream.msg != NULL)
-               png_warning(png_ptr, png_ptr->zstream.msg);
-            else
-               png_warning(png_ptr, msg);
-            inflateReset(&png_ptr->zstream);
-            png_ptr->zstream.avail_in = 0;
-
-            if (text ==  NULL)
-            {
-               text_size = key_size + sizeof(msg) + 1;
-               text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size);
-               png_memcpy(text, key, key_size);
-            }
-
-            text[text_size - 1] = 0x00;
-
-            /* Copy what we can of the error message into the text chunk */
-            text_size = (png_size_t)(slength - (text - key) - 1);
-            text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
-            png_memcpy(text + key_size, msg, text_size + 1);
-            break;
-         }
-         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
-         {
-            if (text == NULL)
-            {
-               text = (png_charp)png_malloc(png_ptr,
-                  (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
-                     + key_size + 1));
-               png_memcpy(text + key_size, png_ptr->zbuf,
-                  png_ptr->zbuf_size - png_ptr->zstream.avail_out);
-               png_memcpy(text, key, key_size);
-               text_size = key_size + png_ptr->zbuf_size -
-                  png_ptr->zstream.avail_out;
-               *(text + text_size) = 0x00;
-            }
-            else
-            {
-               png_charp tmp;
-
-               tmp = text;
-               text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size +
-                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
-               png_memcpy(text, tmp, text_size);
-               png_free(png_ptr, tmp);
-               png_memcpy(text + text_size, png_ptr->zbuf,
-                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
-               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
-               *(text + text_size) = 0x00;
-            }
-            if (ret != Z_STREAM_END)
-            {
-               png_ptr->zstream.next_out = png_ptr->zbuf;
-               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-            }
-            else
-            {
-               break;
-            }
-         }
-      }
-
-      inflateReset(&png_ptr->zstream);
-      png_ptr->zstream.avail_in = 0;
-
-      png_free(png_ptr, key);
-      key = text;
-      text += key_size;
+       comp_type = *(++text);
+       text++;        /* skip the compression byte */
    }
-   else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
-   {
-      png_size_t text_size;
-#if !defined(PNG_NO_STDIO)
-      char umsg[50];
+   prefix_len = text - chunkdata;
 
-      sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
-      png_warning(png_ptr, umsg);
-#else
-      png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
-
-      /* Copy what we can of the error message into the text chunk */
-      text_size = (png_size_t)(slength - (text - key) - 1);
-      text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
-      png_memcpy(text, msg, text_size + 1);
-   }
+   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
+                                    (png_size_t)length, prefix_len);
 
    text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
    text_ptr->compression = comp_type;
-   text_ptr->key = key;
-   text_ptr->text = text;
+   text_ptr->lang = NULL;
+   text_ptr->key = chunkdata;
+   text_ptr->text = chunkdata + prefix_len;
+
+   png_set_text(png_ptr, info_ptr, text_ptr, 1);
+
+   png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+   png_textp text_ptr;
+   png_charp chunkdata;
+   png_charp lang, text;
+   int comp_type = PNG_TEXT_COMPRESSION_NONE;
+   int comp_flag = 0;
+   png_size_t slength, prefix_len;
+
+   png_debug(1, "in png_handle_iTXt\n");
+
+   if (!(png_ptr->mode & PNG_HAVE_IHDR))
+      png_error(png_ptr, "Missing IHDR before iTXt");
+
+   if (png_ptr->mode & PNG_HAVE_IDAT)
+      png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+   /* We will no doubt have problems with chunks even half this size, but
+      there is no hard and fast rule to tell us where to stop. */
+   if (length > (png_uint_32)65535L)
+   {
+     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+     png_crc_finish(png_ptr, length);
+     return;
+   }
+#endif
+
+   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+   slength = (png_size_t)length;
+   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+   if (png_crc_finish(png_ptr, 0))
+   {
+      png_free(png_ptr, chunkdata);
+      return;
+   }
+
+   chunkdata[slength] = 0x00;
+
+   for (lang = chunkdata; *lang; lang++)
+      /* empty loop */ ;
+   lang++;        /* skip NUL separator */
+
+   /* iTXt must have a language tag and some text after the keyword */
+   if (lang >= chunkdata + slength)
+   {
+      comp_type = PNG_TEXT_COMPRESSION_NONE;
+      png_warning(png_ptr, "Zero length iTXt chunk");
+   }
+   else
+   {
+       comp_flag = *lang++;
+       comp_type = *lang++;
+   }
+
+   for (text = lang; *text; text++)
+      /* empty loop */ ;
+   text++;        /* skip NUL separator */
+
+   prefix_len = text - chunkdata;
+
+   if (comp_flag)
+       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
+                                        (size_t)length, prefix_len);
+
+   text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+   text_ptr->compression = (png_byte)comp_type;
+   text_ptr->lang = NULL;
+   text_ptr->key = chunkdata;
+   text_ptr->text = chunkdata + prefix_len;
 
    png_set_text(png_ptr, info_ptr, text_ptr, 1);
 
    png_free(png_ptr, text_ptr->key);
    png_free(png_ptr, text_ptr);
+   png_free(png_ptr, chunkdata);
 }
 #endif
 
@@ -1713,6 +2078,13 @@
    (png_row_infop row_info, png_bytep row, int pass,
    png_uint_32 transformations)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+   
    png_debug(1,"in png_do_read_interlace\n");
    if (row != NULL && row_info != NULL)
    {
@@ -2051,6 +2423,22 @@
 void
 png_read_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+   
    png_debug(1, "in png_read_finish_row\n");
    png_ptr->row_number++;
    if (png_ptr->row_number < png_ptr->num_rows)
@@ -2091,6 +2479,9 @@
 
    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    {
+#ifdef PNG_USE_LOCAL_ARRAYS
+      PNG_IDAT;
+#endif
       char extra;
       int ret;
 
@@ -2111,7 +2502,7 @@
 
                png_reset_crc(png_ptr);
                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
-               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
                   png_error(png_ptr, "Not enough image data");
 
             }
@@ -2154,6 +2545,22 @@
 void
 png_read_start_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   
+   /* start of interlace block in the y direction */
+   const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   
+   /* offset to next interlace block in the y direction */
+   const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+   
    int max_pixel_depth;
    png_uint_32 row_bytes;
 
diff --git a/pngset.c b/pngset.c
index d965d1f..8c79109 100644
--- a/pngset.c
+++ b/pngset.c
@@ -1,7 +1,7 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -16,7 +16,7 @@
 #define PNG_INTERNAL
 #include "png.h"
 
-#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
+#if defined(PNG_bKGD_SUPPORTED)
 void
 png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
 {
@@ -29,7 +29,7 @@
 }
 #endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
 void
 png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
    double white_x, double white_y, double red_x, double red_y,
@@ -51,7 +51,7 @@
 }
 #endif
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
 void
 png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
 {
@@ -64,7 +64,7 @@
 }
 #endif
 
-#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
+#if defined(PNG_hIST_SUPPORTED)
 void
 png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
 {
@@ -117,10 +117,10 @@
       info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
 }
 
-#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+#if defined(PNG_oFFs_SUPPORTED)
 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)
+   png_int_32 offset_x, png_int_32 offset_y, int unit_type)
 {
    png_debug1(1, "in %s storage function\n", "oFFs");
    if (png_ptr == NULL || info_ptr == NULL)
@@ -133,7 +133,7 @@
 }
 #endif
 
-#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_pCAL_SUPPORTED)
 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,
@@ -178,7 +178,29 @@
 }
 #endif
 
-#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+void
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+             png_charp unit, double width, double height)
+{
+   png_uint_32 length;
+
+   png_debug1(1, "in %s storage function\n", "sCAL");
+   if (png_ptr == NULL || info_ptr == NULL)
+      return;
+
+   length = png_strlen(unit) + 1;
+   png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+   info_ptr->scal_unit = (png_charp)png_malloc(png_ptr, length);
+   png_memcpy(info_ptr->scal_unit, unit, (png_size_t)length);
+   info_ptr->scal_pixel_width = width;
+   info_ptr->scal_pixel_height = height;
+
+   info_ptr->valid |= PNG_INFO_sCAL;
+}
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
 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)
@@ -207,7 +229,7 @@
    info_ptr->valid |= PNG_INFO_PLTE;
 }
 
-#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
+#if defined(PNG_sBIT_SUPPORTED)
 void
 png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
    png_color_8p sig_bit)
@@ -221,7 +243,7 @@
 }
 #endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
+#if defined(PNG_sRGB_SUPPORTED)
 void
 png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
 {
@@ -236,10 +258,10 @@
 png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
    int intent)
 {
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
    float file_gamma;
 #endif
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
 #endif
    png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
@@ -248,12 +270,12 @@
 
    png_set_sRGB(png_ptr, info_ptr, intent);
 
-#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
+#if defined(PNG_gAMA_SUPPORTED)
    file_gamma = (float).45455;
    png_set_gAMA(png_ptr, info_ptr, file_gamma);
 #endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
    white_x = (float).3127;
    white_y = (float).3290;
    red_x   = (float).64;
@@ -270,8 +292,29 @@
 }
 #endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
-    defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_iCCP_SUPPORTED)
+void
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+             png_charp name, int compression_type,
+             png_charp profile, int proflen)
+{
+   png_debug1(1, "in %s storage function\n", "iCCP");
+   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+      return;
+
+   info_ptr->iccp_name = png_malloc(png_ptr, png_strlen(name)+1);
+   strcpy(info_ptr->iccp_name, name);
+   info_ptr->iccp_profile = png_malloc(png_ptr, proflen);
+   memcpy(info_ptr->iccp_profile, profile, proflen);
+   info_ptr->iccp_proflen = (png_uint_32)proflen;
+   /* Compression is always zero but is here so the API and info structure
+    * does not have to change * if we introduce multiple compression types */
+   info_ptr->iccp_compression = (png_byte)compression_type;
+   info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
 void
 png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
    int num_text)
@@ -320,7 +363,13 @@
       png_charp key,text;
 
       if (text_ptr[i].key == (png_charp)NULL)
-         continue;
+          continue;
+
+#ifdef PNG_iTXt_SUPPORTED
+      textp->lang = text_ptr[i].lang;
+#else
+      textp->lang = NULL;
+#endif
 
       if (text_ptr[i].text[0] == '\0')
       {
@@ -346,6 +395,7 @@
 
       png_memcpy(textp->key, text_ptr[i].key,
          (png_size_t)(text - key));  /* includes the zero-byte separator */
+
       textp->text = textp->key + (text-key);
       if(textp->text_length)
       {
@@ -362,13 +412,13 @@
 }
 #endif
 
-#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
+#if defined(PNG_tIME_SUPPORTED)
 void
 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 ||
-       (png_ptr->flags & PNG_FLAG_WROTE_tIME))
+       (png_ptr->mode & PNG_WROTE_tIME))
       return;
 
    png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
@@ -376,7 +426,7 @@
 }
 #endif
 
-#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
+#if defined(PNG_tRNS_SUPPORTED)
 void
 png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
    png_bytep trans, int num_trans, png_color_16p trans_values)
@@ -402,6 +452,40 @@
 }
 #endif
 
+#if defined(PNG_sPLT_SUPPORTED)
+void
+png_set_spalettes(png_structp png_ptr,
+             png_infop info_ptr, png_spalette_p entries, int nentries)
+{
+    png_spalette_p        np;
+    int i;
+
+    np = (png_spalette_p)png_malloc(png_ptr,
+        (info_ptr->splt_palettes_num + nentries) * sizeof(png_spalette));
+
+    memcpy(np, info_ptr->splt_palettes, 
+           info_ptr->splt_palettes_num * sizeof(png_spalette));
+    png_free(png_ptr, info_ptr->splt_palettes);
+
+    for (i = 0; i < nentries; i++)
+    {
+        png_spalette_p to = np + i;
+        png_spalette_p from = entries + i;
+
+        to->name = (png_charp)png_malloc(png_ptr,
+                                        png_strlen(from->name) + 1);
+        png_strcpy(to->name, from->name);
+        to->entries = (png_spalette_entryp)png_malloc(png_ptr,
+                                 from->nentries * sizeof(png_spalette));
+        memcpy(to->entries, from->entries, 
+               from->nentries * sizeof(png_spalette));
+    }
+
+    info_ptr->splt_palettes = np;
+    info_ptr->splt_palettes_num += nentries;
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
 #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
 void
 png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
@@ -412,3 +496,10 @@
    png_ptr->empty_plte_permitted=(png_byte)empty_plte_permitted;
 }
 #endif
+
+
+
+
+
+
+
diff --git a/pngtrans.c b/pngtrans.c
index 4ec7b38..c0f29fc 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.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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/pngtypes.h b/pngtypes.h
new file mode 100644
index 0000000..9b5049c
--- /dev/null
+++ b/pngtypes.h
@@ -0,0 +1,31 @@
+/* pngtypes.h - array of chunk-types for libpng
+ *
+ * libpng 1.0.5d - November 28, 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
+ * Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+ */
+
+/* Constant strings for known chunk types.  If you need to add a chunk,
+ * define the string in png.h and invoke it here.
+ */
+
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_oFFs;
+PNG_pCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+
diff --git a/pngvcrd.c b/pngvcrd.c
index 092037a..3398fff 100644
--- a/pngvcrd.c
+++ b/pngvcrd.c
@@ -2,7 +2,7 @@
  *
  * For Intel x86 CPU and Microsoft Visual C++ compiler
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -96,6 +96,9 @@
 void
 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
 #ifdef DISABLE_PNGVCRD_COMBINE
    int save_mmx_supported = mmx_supported;
 #endif
@@ -966,6 +969,9 @@
 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
    png_uint_32 transformations)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
 #ifdef DISABLE_PNGVCRD_INTERLACE
    int save_mmx_supported = mmx_supported;
 #endif
@@ -1496,8 +1502,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*2 - 2);	// sign fixed
-                     dp -= (width_mmx*16 - 2);	// sign fixed
+                     sptr -= (width_mmx*2 - 2);            // sign fixed
+                     dp -= (width_mmx*16 - 2);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
@@ -1541,8 +1547,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*2 - 2);	// sign fixed
-                     dp -= (width_mmx*8 - 2);	// sign fixed
+                     sptr -= (width_mmx*2 - 2);            // sign fixed
+                     dp -= (width_mmx*8 - 2);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
@@ -1581,8 +1587,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*2 - 2);	// sign fixed
-                     dp -= (width_mmx*4 - 2);	// sign fixed
+                     sptr -= (width_mmx*2 - 2);            // sign fixed
+                     dp -= (width_mmx*4 - 2);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
@@ -1634,8 +1640,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*4 - 4);	// sign fixed
-                     dp -= (width_mmx*32 - 4);	// sign fixed
+                     sptr -= (width_mmx*4 - 4);            // sign fixed
+                     dp -= (width_mmx*32 - 4);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
@@ -1679,8 +1685,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*4 - 4);	// sign fixed
-                     dp -= (width_mmx*16 - 4);	// sign fixed
+                     sptr -= (width_mmx*4 - 4);            // sign fixed
+                     dp -= (width_mmx*16 - 4);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
@@ -1722,8 +1728,8 @@
                         }
                      }
 
-                     sptr -= (width_mmx*4 - 4);	// sign fixed
-                     dp -= (width_mmx*8 - 4);	// sign fixed
+                     sptr -= (width_mmx*4 - 4);          // sign fixed
+                     dp -= (width_mmx*8 - 4);            // sign fixed
                      for (i = width; i; i--)
                      {
                         png_byte v[8];
diff --git a/pngwio.c b/pngwio.c
index 958e74e..91c3fbb 100644
--- a/pngwio.c
+++ b/pngwio.c
@@ -1,7 +1,7 @@
 
 /* pngwio.c - functions for data output
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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 e93ba47..1f836ad 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1,7 +1,7 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -22,13 +22,14 @@
  * them in png_write_end(), and compressing them.
  */
 void
-png_write_info(png_structp png_ptr, png_infop info_ptr)
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
 {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
    int i;
 #endif
-
-   png_debug(1, "in png_write_info\n");
+   png_debug(1, "in png_write_info_before_PLTE\n");
+   if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+   {
    png_write_sig(png_ptr); /* write PNG signature */
    /* write IHDR information. */
    png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
@@ -49,6 +50,16 @@
    if (info_ptr->valid & PNG_INFO_sRGB)
       png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
 #endif
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_iCCP)
+      png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_TEXT_COMPRESSION_NONE,
+                     info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sPLT)
+     for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+       png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif
 #if defined(PNG_WRITE_sBIT_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_sBIT)
       png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
@@ -61,6 +72,21 @@
          info_ptr->x_green, info_ptr->y_green,
          info_ptr->x_blue, info_ptr->y_blue);
 #endif
+      png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+   }
+}
+
+void
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+   int i;
+#endif
+
+   png_debug(1, "in png_write_info\n");
+
+   png_write_info_before_PLTE(png_ptr, info_ptr);
+
    if (info_ptr->valid & PNG_INFO_PLTE)
       png_write_PLTE(png_ptr, info_ptr->palette,
          (png_uint_32)info_ptr->num_palette);
@@ -103,6 +129,11 @@
          info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
          info_ptr->pcal_units, info_ptr->pcal_params);
 #endif
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+   if (info_ptr->valid & PNG_INFO_sCAL)
+      png_write_sCAL(png_ptr, info_ptr->scal_unit, 
+          info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#endif
 #if defined(PNG_WRITE_pHYs_SUPPORTED)
    if (info_ptr->valid & PNG_INFO_pHYs)
       png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
@@ -112,17 +143,33 @@
    if (info_ptr->valid & PNG_INFO_tIME)
    {
       png_write_tIME(png_ptr, &(info_ptr->mod_time));
-      png_ptr->flags |= PNG_FLAG_WROTE_tIME;
+      png_ptr->mode |= PNG_WROTE_tIME;
    }
 #endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
    /* Check to see if we need to write text chunks */
    for (i = 0; i < info_ptr->num_text; i++)
    {
       png_debug2(2, "Writing header text chunk %d, type %d\n", i,
          info_ptr->text[i].compression);
+      /* an internationalized chunk? */
+      if (info_ptr->text[i].lang)
+      {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+          /* write international chunk */
+          png_write_iTXt(png_ptr, 
+                         info_ptr->text[i].compression,
+                         info_ptr->text[i].lang,
+                         info_ptr->text[i].key,
+                         info_ptr->text[i].text);
+#else
+          png_warning(png_ptr, "Unable to write international text\n");
+#endif
+          /* Mark this chunk as written */
+          info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+      }
       /* If we want a compressed text chunk */
-      if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+      else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
       {
 #if defined(PNG_WRITE_zTXt_SUPPORTED)
          /* write compressed chunk */
@@ -140,7 +187,8 @@
 #if defined(PNG_WRITE_tEXt_SUPPORTED)
          /* write uncompressed chunk */
          png_write_tEXt(png_ptr, info_ptr->text[i].key,
-            info_ptr->text[i].text, info_ptr->text[i].text_length);
+                         info_ptr->text[i].text, 
+                         info_ptr->text[i].text_length);
 #else
          png_warning(png_ptr, "Unable to write uncompressed text\n");
 #endif
@@ -166,16 +214,16 @@
    /* see if user wants us to write information chunks */
    if (info_ptr != NULL)
    {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
       int i; /* local index variable */
 #endif
 #if defined(PNG_WRITE_tIME_SUPPORTED)
       /* check to see if user has supplied a time chunk */
       if (info_ptr->valid & PNG_INFO_tIME &&
-         !(png_ptr->flags & PNG_FLAG_WROTE_tIME))
+         !(png_ptr->mode & PNG_WROTE_tIME))
          png_write_tIME(png_ptr, &(info_ptr->mod_time));
 #endif
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
       /* loop through comment chunks */
       for (i = 0; i < info_ptr->num_text; i++)
       {
@@ -630,7 +678,7 @@
 
    if (info_ptr != NULL)
    {
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
    png_debug(1, "in png_info_destroy\n");
    if (info_ptr->text != NULL)
    {
@@ -642,6 +690,11 @@
            png_free(png_ptr, info_ptr->text[i].key);
            info_ptr->text[i].key = NULL;
          }
+         if(info_ptr->text[i].lang != NULL)
+         {
+           png_free(png_ptr, info_ptr->text[i].lang);
+           info_ptr->text[i].lang = NULL;
+         }
       }
       png_free(png_ptr, info_ptr->text);
       info_ptr->text = NULL;
@@ -705,16 +758,18 @@
    png_free(png_ptr, png_ptr->up_row);
    png_free(png_ptr, png_ptr->avg_row);
    png_free(png_ptr, png_ptr->paeth_row);
+
 #if defined(PNG_TIME_RFC1123_SUPPORTED)
    png_free(png_ptr, png_ptr->time_buffer);
-#endif /* PNG_TIME_RFC1123_SUPPORTED */
+#endif
+
 #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
    png_free(png_ptr, png_ptr->prev_filters);
    png_free(png_ptr, png_ptr->filter_weights);
    png_free(png_ptr, png_ptr->inv_filter_weights);
    png_free(png_ptr, png_ptr->filter_costs);
    png_free(png_ptr, png_ptr->inv_filter_costs);
-#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+#endif
 
    /* reset structure */
    png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
diff --git a/pngwtran.c b/pngwtran.c
index f695631..310064e 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.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -19,6 +19,9 @@
 {
    png_debug(1, "in png_do_write_transformations\n");
 
+   if (png_ptr == NULL)
+      return;
+
 #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
    if (png_ptr->transformations & PNG_USER_TRANSFORM)
       if(png_ptr->write_user_transform_fn != NULL)
diff --git a/pngwutil.c b/pngwutil.c
index 459800d..37a4f50 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -1,7 +1,7 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * libpng 1.0.5a - October 23, 1999
+ * libpng 1.0.5f - December 6, 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
@@ -127,11 +127,229 @@
 void
 png_write_sig(png_structp png_ptr)
 {
+   png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    /* write the rest of the 8 byte signature */
-   png_write_data(png_ptr, &png_sig[png_ptr->sig_bytes],
+   png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
       (png_size_t)8 - png_ptr->sig_bytes);
 }
 
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+/*
+ * This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+    char *input;   /* the uncompressed input data */
+    int input_len;   /* its length */
+    int num_output_ptr; /* number of output pointers used */
+    int max_output_ptr; /* size of output_ptr */
+    png_charpp output_ptr; /* array of pointers to output */
+} compression_state;
+
+/* compress given text into storage in the png_ptr structure */
+static int 
+png_text_compress(png_structp png_ptr, 
+        png_charp text, png_size_t text_len, int compression,
+        compression_state *comp)
+{
+   int ret;
+
+   comp->num_output_ptr = comp->max_output_ptr = 0;
+   comp->output_ptr = NULL;
+   comp->input = NULL;
+
+   /* we may just want to pass the text right through */
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+       comp->input = text;
+       comp->input_len = text_len;
+       return(text_len);
+   }
+
+   if (compression >= PNG_TEXT_COMPRESSION_LAST)
+   {
+#if !defined(PNG_NO_STDIO)
+      char msg[50];
+      sprintf(msg, "Unknown compression type %d", compression);
+      png_warning(png_ptr, msg);
+#else
+      png_warning(png_ptr, "Unknown compression type");
+#endif
+      compression = PNG_TEXT_COMPRESSION_zTXt;
+   }
+
+   /* We can't write the chunk until we find out how much data we have,
+    * which means we need to run the compressor first and save the
+    * output.  This shouldn't be a problem, as the vast majority of
+    * comments should be reasonable, but we will set up an array of
+    * malloc'd pointers to be sure.
+    *
+    * If we knew the application was well behaved, we could simplify this
+    * greatly by assuming we can always malloc an output buffer large
+    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+    * and malloc this directly.  The only time this would be a bad idea is
+    * if we can't malloc more than 64K and we have 64K of random input
+    * data, or if the input string is incredibly large (although this
+    * wouldn't cause a failure, just a slowdown due to swapping).
+    */
+
+   /* set up the compression buffers */
+   png_ptr->zstream.avail_in = (uInt)text_len;
+   png_ptr->zstream.next_in = (Bytef *)text;
+   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+   /* this is the same compression loop as in png_write_row() */
+   do
+   {
+      /* compress the data */
+      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+      if (ret != Z_OK)
+      {
+         /* error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+      /* check to see if we need more room */
+      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
+      {
+         /* make sure the output array has room */
+         if (comp->num_output_ptr >= comp->max_output_ptr)
+         {
+            int old_max;
+
+            old_max = comp->max_output_ptr;
+            comp->max_output_ptr = comp->num_output_ptr + 4;
+            if (comp->output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = comp->output_ptr;
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+               png_memcpy(comp->output_ptr, old_ptr, 
+           old_max * sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+         }
+
+         /* save the data */
+         comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         comp->num_output_ptr++;
+
+         /* and reset the buffer */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   /* continue until we don't have any more to compress */
+   } while (png_ptr->zstream.avail_in);
+
+   /* finish the compression */
+   do
+   {
+      /* tell zlib we are finished */
+      ret = deflate(&png_ptr->zstream, Z_FINISH);
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+         /* we got an error */
+         if (png_ptr->zstream.msg != NULL)
+            png_error(png_ptr, png_ptr->zstream.msg);
+         else
+            png_error(png_ptr, "zlib error");
+      }
+
+      /* check to see if we need more room */
+      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
+      {
+         /* check to make sure our output array has room */
+         if (comp->num_output_ptr >= comp->max_output_ptr)
+         {
+            int old_max;
+
+            old_max = comp->max_output_ptr;
+            comp->max_output_ptr = comp->num_output_ptr + 4;
+            if (comp->output_ptr != NULL)
+            {
+               png_charpp old_ptr;
+
+               old_ptr = comp->output_ptr;
+               /* This could be optimized to realloc() */
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+               png_memcpy(comp->output_ptr, old_ptr, 
+           old_max * sizeof (png_charp));
+               png_free(png_ptr, old_ptr);
+            }
+            else
+               comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+                  (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+         }
+
+         /* save off the data */
+         comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+            (png_uint_32)png_ptr->zbuf_size);
+         png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+            png_ptr->zbuf_size);
+         comp->num_output_ptr++;
+
+         /* and reset the buffer pointers */
+         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+         png_ptr->zstream.next_out = png_ptr->zbuf;
+      }
+   } while (ret != Z_STREAM_END);
+
+   /* text length is number of buffers plus last buffer */
+   text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+   return(text_len);
+}
+
+/* ship the compressed text out via chunk writes */
+static void 
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+   int i;
+
+   /* handle the no-compression case */
+   if (comp->input)
+   {
+       png_write_chunk_data(png_ptr, (png_bytep)comp->input, comp->input_len);
+       return;
+   }
+
+   /* write saved output buffers, if any */
+   for (i = 0; i < comp->num_output_ptr; i++)
+   {
+      png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],png_ptr->zbuf_size);
+      png_free(png_ptr, comp->output_ptr[i]);
+   }
+   if (comp->max_output_ptr != 0)
+      png_free(png_ptr, comp->output_ptr);
+   /* write anything left in zbuf */
+   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+      png_write_chunk_data(png_ptr, png_ptr->zbuf,
+         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+   /* reset zlib for another zTXt/iTXt or the image data */
+   deflateReset(&png_ptr->zstream);
+
+}
+#endif
+
 /* Write the IHDR chunk, and update the png_struct with the necessary
  * information.  Note that the rest of this code depends upon this
  * information being correct.
@@ -141,6 +359,9 @@
    int bit_depth, int color_type, int compression_type, int filter_type,
    int interlace_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IHDR;
+#endif
    png_byte buf[13]; /* buffer to store the IHDR info */
 
    png_debug(1, "in png_write_IHDR\n");
@@ -234,7 +455,7 @@
    buf[12] = (png_byte)interlace_type;
 
    /* write the chunk */
-   png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+   png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
 
    /* initialize zlib with PNG info */
    png_ptr->zstream.zalloc = png_zalloc;
@@ -279,6 +500,9 @@
 void
 png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_PLTE;
+#endif
    png_uint_32 i;
    png_colorp pal_ptr;
    png_byte buf[3];
@@ -304,7 +528,7 @@
    png_ptr->num_palette = (png_uint_16)num_pal;
    png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
 
-   png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3);
+   png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3);
    for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
    {
       buf[0] = pal_ptr->red;
@@ -320,8 +544,11 @@
 void
 png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IDAT;
+#endif
    png_debug(1, "in png_write_IDAT\n");
-   png_write_chunk(png_ptr, png_IDAT, data, length);
+   png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
    png_ptr->mode |= PNG_HAVE_IDAT;
 }
 
@@ -329,8 +556,11 @@
 void
 png_write_IEND(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_IEND;
+#endif
    png_debug(1, "in png_write_IEND\n");
-   png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+   png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL, (png_size_t)0);
    png_ptr->mode |= PNG_HAVE_IEND;
 }
 
@@ -339,6 +569,9 @@
 void
 png_write_gAMA(png_structp png_ptr, double file_gamma)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_gAMA;
+#endif
    png_uint_32 igamma;
    png_byte buf[4];
 
@@ -346,7 +579,7 @@
    /* file_gamma is saved in 1/1000000ths */
    igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
    png_save_uint_32(buf, igamma);
-   png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+   png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
 }
 #endif
 
@@ -355,6 +588,9 @@
 void
 png_write_sRGB(png_structp png_ptr, int srgb_intent)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sRGB;
+#endif
    png_byte buf[1];
 
    png_debug(1, "in png_write_sRGB\n");
@@ -362,7 +598,105 @@
          png_warning(png_ptr,
             "Invalid sRGB rendering intent specified");
    buf[0]=(png_byte)srgb_intent;
-   png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+   png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+/* write an iCCP chunk */
+void
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+   png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iCCP;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   compression_state comp;
+
+   png_debug(1, "in png_write_iCCP\n");
+   if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
+      &new_name)) == 0)
+   {
+      png_warning(png_ptr, "Empty keyword in iCCP chunk");
+      return;
+   }
+
+   if (compression_type)
+      /* ignore */ ;
+
+   if (profile == NULL || *profile == '\0')
+      profile_len = 0;
+
+   if (profile_len)
+       profile_len = png_text_compress(png_ptr, profile, profile_len,
+                   PNG_TEXT_COMPRESSION_zTXt, &comp);
+
+   /* make sure we include the NULL after the name and the compression type */
+   png_write_chunk_start(png_ptr, (png_bytep)png_iCCP, 
+          (png_uint_32)name_len+profile_len+2);
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
+
+   if (profile_len)
+      png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+/* write a sPLT chunk */
+void
+png_write_sPLT(png_structp png_ptr, png_spalette_p spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sPLT;
+#endif
+   png_size_t name_len;
+   png_charp new_name;
+   png_byte entrybuf[10];
+   int entry_size = (spalette->depth == 8 ? 6 : 10);
+   int palette_size = entry_size * spalette->nentries;
+   png_spalette_entryp ep;
+
+   png_debug(1, "in png_write_sPLT\n");
+   if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, spalette->name, &new_name))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in sPLT chunk");
+      return;
+   }
+
+   /* make sure we include the NULL after the name */
+   png_write_chunk_start(png_ptr, (png_bytep) png_sPLT, 
+          (png_uint_32)(name_len + 1 + palette_size));
+   png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
+
+   /* loop through each palette entry, writing appropriately */
+   for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
+   {
+       if (spalette->depth == 8)
+       {
+           entrybuf[0] = (png_byte)ep->red;
+           entrybuf[1] = (png_byte)ep->green;
+           entrybuf[2] = (png_byte)ep->blue;
+           entrybuf[3] = (png_byte)ep->alpha;
+           png_save_uint_16(entrybuf + 4, ep->frequency);
+       }
+       else
+       {
+           png_save_uint_16(entrybuf + 0, ep->red);
+           png_save_uint_16(entrybuf + 2, ep->green);
+           png_save_uint_16(entrybuf + 4, ep->blue);
+           png_save_uint_16(entrybuf + 6, ep->alpha);
+           png_save_uint_16(entrybuf + 8, ep->frequency);
+       }
+       png_write_chunk_data(png_ptr, entrybuf, entry_size);
+   }
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_name);
 }
 #endif
 
@@ -371,6 +705,9 @@
 void
 png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sBIT;
+#endif
    png_byte buf[4];
    png_size_t size;
 
@@ -415,7 +752,7 @@
       buf[size++] = sbit->alpha;
    }
 
-   png_write_chunk(png_ptr, png_sBIT, buf, size);
+   png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
 }
 #endif
 
@@ -426,6 +763,9 @@
    double red_x, double red_y, double green_x, double green_y,
    double blue_x, double blue_y)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_cHRM;
+#endif
    png_uint_32 itemp;
    png_byte buf[32];
 
@@ -475,7 +815,7 @@
    itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
    png_save_uint_32(buf + 28, itemp);
 
-   png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32);
+   png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
 }
 #endif
 
@@ -485,6 +825,9 @@
 png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
    int num_trans, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tRNS;
+#endif
    png_byte buf[6];
 
    png_debug(1, "in png_write_tRNS\n");
@@ -496,13 +839,13 @@
          return;
       }
       /* write the chunk out as it is */
-      png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
    }
    else if (color_type == PNG_COLOR_TYPE_GRAY)
    {
       /* one 16 bit value */
       png_save_uint_16(buf, tran->gray);
-      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
    }
    else if (color_type == PNG_COLOR_TYPE_RGB)
    {
@@ -510,7 +853,7 @@
       png_save_uint_16(buf, tran->red);
       png_save_uint_16(buf + 2, tran->green);
       png_save_uint_16(buf + 4, tran->blue);
-      png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+      png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
    }
    else
    {
@@ -524,6 +867,9 @@
 void
 png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_bKGD;
+#endif
    png_byte buf[6];
 
    png_debug(1, "in png_write_bKGD\n");
@@ -540,19 +886,19 @@
          return;
       }
       buf[0] = back->index;
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
    }
    else if (color_type & PNG_COLOR_MASK_COLOR)
    {
       png_save_uint_16(buf, back->red);
       png_save_uint_16(buf + 2, back->green);
       png_save_uint_16(buf + 4, back->blue);
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
    }
    else
    {
       png_save_uint_16(buf, back->gray);
-      png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+      png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
    }
 }
 #endif
@@ -562,6 +908,9 @@
 void
 png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_hIST;
+#endif
    int i;
    png_byte buf[3];
 
@@ -574,7 +923,7 @@
       return;
    }
 
-   png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+   png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2));
    for (i = 0; i < num_hist; i++)
    {
       png_save_uint_16(buf, hist[i]);
@@ -584,8 +933,8 @@
 }
 #endif
 
-#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
-    defined(PNG_WRITE_pCAL_SUPPORTED)
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+    defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
 /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
  * and if invalid, correct the keyword rather than discarding the entire
  * chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
@@ -710,6 +1059,9 @@
 png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
    png_size_t text_len)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tEXt;
+#endif
    png_size_t key_len;
    png_charp new_key;
 
@@ -724,11 +1076,12 @@
       text_len = 0;
 
    /* 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);
+   png_write_chunk_start(png_ptr, (png_bytep)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.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
     */
    png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
    if (text_len)
@@ -745,13 +1098,13 @@
 png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
    png_size_t text_len, int compression)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_zTXt;
+#endif
    png_size_t key_len;
    char buf[1];
    png_charp new_key;
-   int i, ret;
-   png_charpp output_ptr = NULL; /* array of pointers to output */
-   int num_output_ptr = 0; /* number of output pointers used */
-   int max_output_ptr = 0; /* size of output_ptr */
+   compression_state comp;
 
    png_debug(1, "in png_write_zTXt\n");
 
@@ -770,177 +1123,92 @@
 
    png_free(png_ptr, new_key);
 
-   if (compression >= PNG_TEXT_COMPRESSION_LAST)
-   {
-#if !defined(PNG_NO_STDIO)
-      char msg[50];
-      sprintf(msg, "Unknown zTXt compression type %d", compression);
-      png_warning(png_ptr, msg);
-#else
-      png_warning(png_ptr, "Unknown zTXt compression type");
-#endif
-      compression = PNG_TEXT_COMPRESSION_zTXt;
-   }
-
-   /* We can't write the chunk until we find out how much data we have,
-    * which means we need to run the compressor first and save the
-    * output.  This shouldn't be a problem, as the vast majority of
-    * comments should be reasonable, but we will set up an array of
-    * malloc'd pointers to be sure.
-    *
-    * If we knew the application was well behaved, we could simplify this
-    * greatly by assuming we can always malloc an output buffer large
-    * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
-    * and malloc this directly.  The only time this would be a bad idea is
-    * if we can't malloc more than 64K and we have 64K of random input
-    * data, or if the input string is incredibly large (although this
-    * wouldn't cause a failure, just a slowdown due to swapping).
-    */
-
-   /* set up the compression buffers */
-   png_ptr->zstream.avail_in = (uInt)text_len;
-   png_ptr->zstream.next_in = (Bytef *)text;
-   png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-   png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
-
-   /* this is the same compression loop as in png_write_row() */
-   do
-   {
-      /* compress the data */
-      ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
-      if (ret != Z_OK)
-      {
-         /* error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-         else
-            png_error(png_ptr, "zlib error");
-      }
-      /* check to see if we need more room */
-      if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
-      {
-         /* make sure the output array has room */
-         if (num_output_ptr >= max_output_ptr)
-         {
-            int old_max;
-
-            old_max = max_output_ptr;
-            max_output_ptr = num_output_ptr + 4;
-            if (output_ptr != NULL)
-            {
-               png_charpp old_ptr;
-
-               old_ptr = output_ptr;
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
-               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
-               png_free(png_ptr, old_ptr);
-            }
-            else
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
-         }
-
-         /* save the data */
-         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
-            (png_uint_32)png_ptr->zbuf_size);
-         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
-            png_ptr->zbuf_size);
-         num_output_ptr++;
-
-         /* and reset the buffer */
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-      }
-   /* continue until we don't have any more to compress */
-   } while (png_ptr->zstream.avail_in);
-
-   /* finish the compression */
-   do
-   {
-      /* tell zlib we are finished */
-      ret = deflate(&png_ptr->zstream, Z_FINISH);
-      if (ret != Z_OK && ret != Z_STREAM_END)
-      {
-         /* we got an error */
-         if (png_ptr->zstream.msg != NULL)
-            png_error(png_ptr, png_ptr->zstream.msg);
-         else
-            png_error(png_ptr, "zlib error");
-      }
-
-      /* check to see if we need more room */
-      if (!(png_ptr->zstream.avail_out) && ret == Z_OK)
-      {
-         /* check to make sure our output array has room */
-         if (num_output_ptr >= max_output_ptr)
-         {
-            int old_max;
-
-            old_max = max_output_ptr;
-            max_output_ptr = num_output_ptr + 4;
-            if (output_ptr != NULL)
-            {
-               png_charpp old_ptr;
-
-               old_ptr = output_ptr;
-               /* This could be optimized to realloc() */
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charpp)));
-               png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp));
-               png_free(png_ptr, old_ptr);
-            }
-            else
-               output_ptr = (png_charpp)png_malloc(png_ptr,
-                  (png_uint_32)(max_output_ptr * sizeof (png_charp)));
-         }
-
-         /* save off the data */
-         output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr,
-            (png_uint_32)png_ptr->zbuf_size);
-         png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf,
-            png_ptr->zbuf_size);
-         num_output_ptr++;
-
-         /* and reset the buffer pointers */
-         png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
-         png_ptr->zstream.next_out = png_ptr->zbuf;
-      }
-   } while (ret != Z_STREAM_END);
-
-   /* text length is number of buffers plus last buffer */
-   text_len = png_ptr->zbuf_size * num_output_ptr;
-   if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
-      text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+   /* compute the compressed data; do it now for the length */ 
+   text_len = png_text_compress(png_ptr, text, text_len, compression, &comp);
 
    /* write start of chunk */
-   png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)(key_len+text_len+2));
+   png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
+      (key_len+text_len+2));
    /* write key */
    png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
    buf[0] = (png_byte)compression;
    /* write compression */
    png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+   /* write the compressed data */
+   png_write_compressed_data_out(png_ptr, &comp);
 
-   /* write saved output buffers, if any */
-   for (i = 0; i < num_output_ptr; i++)
-   {
-      png_write_chunk_data(png_ptr,(png_bytep)output_ptr[i],png_ptr->zbuf_size);
-      png_free(png_ptr, output_ptr[i]);
-   }
-   if (max_output_ptr != 0)
-      png_free(png_ptr, output_ptr);
-   /* write anything left in zbuf */
-   if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
-      png_write_chunk_data(png_ptr, png_ptr->zbuf,
-         png_ptr->zbuf_size - png_ptr->zstream.avail_out);
    /* close the chunk */
    png_write_chunk_end(png_ptr);
-
-   /* reset zlib for another zTXt or the image data */
-   deflateReset(&png_ptr->zstream);
 }
 #endif
 
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+/* write an iTXt chunk */
+void
+png_write_iTXt(png_structp png_ptr, int compression, 
+          png_charp key, png_charp lang, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_iTXt;
+#endif
+   png_size_t lang_len, key_len, text_len = png_strlen(text);
+   png_charp new_lang, new_key;
+   png_byte cbuf[2];
+   compression_state comp;
+
+   png_debug(1, "in png_write_iTXt\n");
+   if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang,
+      &new_lang))==0)
+   {
+      png_warning(png_ptr, "Empty language field in iTXt chunk");
+      return;
+   }
+   if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+   {
+      png_warning(png_ptr, "Empty keyword in iTXt chunk");
+      return;
+   }
+
+   if (text == NULL || *text == '\0')
+      text_len = 0;
+
+   /* compute the compressed data; do it now for the length */ 
+   text_len = png_text_compress(png_ptr, text, text_len, compression, &comp);
+
+   /* make sure we include the compression flag, the compression byte, 
+    * and the NULs after the lang and key parts */
+   png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, 
+          (png_uint_32)(2 + lang_len+1 + key_len+1 + text_len));
+
+   /* set the compression bits */
+   if (compression == PNG_TEXT_COMPRESSION_NONE)
+   {
+       cbuf[0] = 0;
+       cbuf[1] = 0;
+   }
+   else /* compression == PNG_TEXT_COMPRESSION_zTXt */
+   {
+       cbuf[0] = 1;
+       cbuf[1] = 0;
+   }
+   png_write_chunk_data(png_ptr, cbuf, 2);
+
+   /*
+    * 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.
+    * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+    */
+   png_write_chunk_data(png_ptr, (png_bytep)new_lang, lang_len + 1);
+   png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+
+   png_write_compressed_data_out(png_ptr, &comp);
+
+   png_write_chunk_end(png_ptr);
+   png_free(png_ptr, new_key);
+   png_free(png_ptr, new_lang);
+}
+#endif
 
 #if defined(PNG_WRITE_oFFs_SUPPORTED)
 /* write the oFFs chunk */
@@ -949,6 +1217,9 @@
    png_uint_32 y_offset,
    int unit_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_oFFs;
+#endif
    png_byte buf[9];
 
    png_debug(1, "in png_write_oFFs\n");
@@ -959,7 +1230,7 @@
    png_save_uint_32(buf + 4, y_offset);
    buf[8] = (png_byte)unit_type;
 
-   png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+   png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
 }
 #endif
 
@@ -969,6 +1240,9 @@
 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)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pCAL;
+#endif
    png_size_t purpose_len, units_len, total_len;
    png_uint_32p params_len;
    png_byte buf[10];
@@ -998,7 +1272,7 @@
    }
 
    png_debug1(3, "pCAL total length = %d\n", total_len);
-   png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
    png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
    png_save_int_32(buf, X0);
    png_save_int_32(buf + 4, X1);
@@ -1020,6 +1294,33 @@
 }
 #endif
 
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+/* write the sCAL chunk */
+void
+png_write_sCAL(png_structp png_ptr, png_charp unit, double width,double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_sCAL;
+#endif
+   png_size_t total_len;
+   char wbuf[32], hbuf[32];
+
+   png_debug(1, "in png_write_sCAL\n");
+
+   sprintf(wbuf, "%12.12e", width);
+   sprintf(hbuf, "%12.12e", height);
+   total_len = png_strlen(unit)+1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+   png_debug1(3, "sCAL total length = %d\n", total_len);
+   png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+   png_write_chunk_data(png_ptr, (png_bytep)unit, png_strlen(unit)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)wbuf, strlen(wbuf)+1);
+   png_write_chunk_data(png_ptr, (png_bytep)hbuf, strlen(hbuf));
+
+   png_write_chunk_end(png_ptr);
+}
+#endif
+
 #if defined(PNG_WRITE_pHYs_SUPPORTED)
 /* write the pHYs chunk */
 void
@@ -1027,6 +1328,9 @@
    png_uint_32 y_pixels_per_unit,
    int unit_type)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_pHYs;
+#endif
    png_byte buf[9];
 
    png_debug(1, "in png_write_pHYs\n");
@@ -1037,7 +1341,7 @@
    png_save_uint_32(buf + 4, y_pixels_per_unit);
    buf[8] = (png_byte)unit_type;
 
-   png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+   png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
 }
 #endif
 
@@ -1048,6 +1352,9 @@
 void
 png_write_tIME(png_structp png_ptr, png_timep mod_time)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   PNG_tIME;
+#endif
    png_byte buf[7];
 
    png_debug(1, "in png_write_tIME\n");
@@ -1066,7 +1373,7 @@
    buf[5] = mod_time->minute;
    buf[6] = mod_time->second;
 
-   png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+   png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
 }
 #endif
 
@@ -1074,6 +1381,22 @@
 void
 png_write_start_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+   
    png_size_t buf_size;
 
    png_debug(1, "in png_write_start_row\n");
@@ -1152,6 +1475,22 @@
 void
 png_write_finish_row(png_structp png_ptr)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+   
+   /* start of interlace block in the y direction */
+   int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+   
+   /* offset to next interlace block in the y direction */
+   int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+   
    int ret;
 
    png_debug(1, "in png_write_finish_row\n");
@@ -1250,6 +1589,16 @@
 void
 png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
 {
+#ifdef PNG_USE_LOCAL_ARRAYS
+   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+   
+   /* start of interlace block */
+   int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+   
+   /* offset to next interlace block */
+   int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+   
    png_debug(1, "in png_do_write_interlace\n");
    /* we don't have to do anything on the last pass (6) */
 #if defined(PNG_USELESS_TESTS_SUPPORTED)
@@ -2076,5 +2425,5 @@
    {
       png_write_flush(png_ptr);
    }
-#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+#endif
 }