/* pngfix.c
 *
 * Copyright (c) 2014-2016 John Cunningham Bowler
 *
 * Last changed in libpng 1.6.21 [(PENDING RELEASE)]
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 *
 * Tool to check and fix the zlib inflate 'too far back' problem.
 * See the usage message for more information.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <assert.h>

#define implies(x,y) assert(!(x) || (y))

#ifdef __GNUC__
   /* This is used to fix the error:
    *
    * pngfix.c:
    * In function 'zlib_advance':
    * pngfix.c:181:13: error: assuming signed overflow does not
    *   occur when simplifying conditional to constant [-Werror=strict-overflow]
    */
#  define FIX_GCC volatile
#else
#  define FIX_GCC
#endif

#define PROGRAM_NAME "pngfix"

/* Define the following to use this program against your installed libpng,
 * rather than the one being built here:
 */
#ifdef PNG_FREESTANDING_TESTS
#  include <png.h>
#else
#  include "../../png.h"
#endif

#if PNG_LIBPNG_VER < 10603 /* 1.6.3 */
#  error "pngfix will not work with libpng prior to 1.6.3"
#endif

#ifdef PNG_SETJMP_SUPPORTED
#include <setjmp.h>

#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) &&\
   (defined(PNG_READ_DEINTERLACE_SUPPORTED) ||\
    defined(PNG_READ_INTERLACING_SUPPORTED))

/* zlib.h defines the structure z_stream, an instance of which is included
 * in this structure and is required for decompressing the LZ compressed
 * data in PNG files.
 */
#ifndef ZLIB_CONST
   /* We must ensure that zlib uses 'const' in declarations. */
#  define ZLIB_CONST
#endif
#include <zlib.h>
#ifdef const
   /* zlib.h sometimes #defines const to nothing, undo this. */
#  undef const
#endif

/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
 * with older builds.
 */
#if ZLIB_VERNUM < 0x1260
#  define PNGZ_MSG_CAST(s) constcast(char*,s)
#  define PNGZ_INPUT_CAST(b) constcast(png_bytep,b)
#else
#  define PNGZ_MSG_CAST(s) (s)
#  define PNGZ_INPUT_CAST(b) (b)
#endif

#ifndef PNG_MAXIMUM_INFLATE_WINDOW
#  error "pngfix not supported in this libpng version"
#endif

#if ZLIB_VERNUM >= 0x1240

/* Copied from pngpriv.h */
#ifdef __cplusplus
#  define voidcast(type, value) static_cast<type>(value)
#  define constcast(type, value) const_cast<type>(value)
#  define aligncast(type, value) \
   static_cast<type>(static_cast<void*>(value))
#  define aligncastconst(type, value) \
   static_cast<type>(static_cast<const void*>(value))
#else
#  define voidcast(type, value) (value)
#  define constcast(type, value) ((type)(value))
#  define aligncast(type, value) ((void*)(value))
#  define aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */

#if PNG_LIBPNG_VER < 10700
/* Chunk tags (copied from pngpriv.h) */
#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
#define PNG_U32(b1,b2,b3,b4) \
   (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))

/* Constants for known chunk types. */
#define png_IDAT PNG_U32( 73,  68,  65,  84)
#define png_IEND PNG_U32( 73,  69,  78,  68)
#define png_IHDR PNG_U32( 73,  72,  68,  82)
#define png_PLTE PNG_U32( 80,  76,  84,  69)
#define png_bKGD PNG_U32( 98,  75,  71,  68)
#define png_cHRM PNG_U32( 99,  72,  82,  77)
#define png_fRAc PNG_U32(102,  82,  65,  99) /* registered, not defined */
#define png_gAMA PNG_U32(103,  65,  77,  65)
#define png_gIFg PNG_U32(103,  73,  70, 103)
#define png_gIFt PNG_U32(103,  73,  70, 116) /* deprecated */
#define png_gIFx PNG_U32(103,  73,  70, 120)
#define png_hIST PNG_U32(104,  73,  83,  84)
#define png_iCCP PNG_U32(105,  67,  67,  80)
#define png_iTXt PNG_U32(105,  84,  88, 116)
#define png_oFFs PNG_U32(111,  70,  70, 115)
#define png_pCAL PNG_U32(112,  67,  65,  76)
#define png_pHYs PNG_U32(112,  72,  89, 115)
#define png_sBIT PNG_U32(115,  66,  73,  84)
#define png_sCAL PNG_U32(115,  67,  65,  76)
#define png_sPLT PNG_U32(115,  80,  76,  84)
#define png_sRGB PNG_U32(115,  82,  71,  66)
#define png_sTER PNG_U32(115,  84,  69,  82)
#define png_tEXt PNG_U32(116,  69,  88, 116)
#define png_tIME PNG_U32(116,  73,  77,  69)
#define png_tRNS PNG_U32(116,  82,  78,  83)
#define png_zTXt PNG_U32(122,  84,  88, 116)
#endif

/* The 8-byte signature as a pair of 32-bit quantities */
#define sig1 PNG_U32(137,  80,  78,  71)
#define sig2 PNG_U32( 13,  10,  26,  10)

/* Is the chunk critical? */
#define CRITICAL(chunk) (((chunk) & PNG_U32(32,0,0,0)) == 0)

/* Is it safe to copy? */
#define SAFE_TO_COPY(chunk) (((chunk) & PNG_U32(0,0,0,32)) != 0)

/* Fix ups for builds with limited read support */
#ifndef PNG_ERROR_TEXT_SUPPORTED
#  define png_error(a,b) png_err(a)
#endif

/********************************* UTILITIES **********************************/
/* UNREACHED is a value to cause an assert to fail. Because of the way the
 * assert macro is written the string "UNREACHED" is produced in the error
 * message.
 */
#define UNREACHED 0

/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8-byte
 * (16-bit RGBA) pixels in size; that's less than 2^65 bytes or 2^68 bits, so
 * arithmetic of 80-bit numbers is sufficient.  This representation uses an
 * arbitrary length array of png_uint_16 digits (0..65535).  The representation
 * is little endian.
 *
 * The arithmetic functions take zero to two uarb values together with the
 * number of digits in those values and write the result to the given uarb
 * (always the first argument) returning the number of digits in the result.
 * If the result is negative the return value is also negative (this would
 * normally be an error).
 */
typedef png_uint_16  udigit; /* A 'unum' is an array of these */
typedef png_uint_16p uarb;
typedef png_const_uint_16p uarbc;

#define UDIGITS(unum) ((sizeof unum)/(sizeof (udigit))
   /* IMPORTANT: only apply this to an array, applied to a pointer the result
    * will typically be '2', which is not useful.
    */

static int
uarb_set(uarb result, png_alloc_size_t val)
   /* Set (initialize) 'result' to 'val'.  The size required for 'result' must
    * be determined by the caller from a knowledge of the maximum for 'val'.
    */
{
   int ndigits = 0;

   while (val > 0)
   {
      result[ndigits++] = (png_uint_16)(val & 0xffff);
      val >>= 16;
   }

   return ndigits;
}

static int
uarb_copy(uarb to, uarb from, int idigits)
   /* Copy a uarb, may reduce the digit count */
{
   int d, odigits;

   for (d=odigits=0; d<idigits; ++d)
      if ((to[d] = from[d]) != 0)
         odigits = d+1;

   return odigits;
}

static int
uarb_inc(uarb num, int in_digits, png_int_32 add)
   /* This is a signed 32-bit add, except that to avoid overflow the value added
    * or subtracted must be no more than 2^31-65536.  A negative result
    * indicates a negative number (which is an error below).  The size of
    * 'num' should be max(in_digits+1,2) for arbitrary 'add' but can be just
    * in_digits+1 if add is known to be in the range -65535..65535.
    */
{
   FIX_GCC int out_digits = 0;

   while (out_digits < in_digits)
   {
      add += num[out_digits];
      num[out_digits++] = (png_uint_16)(add & 0xffff);
      add >>= 16;
   }

   while (add != 0 && add != (-1))
   {
      num[out_digits++] = (png_uint_16)(add & 0xffff);
      add >>= 16;
   }

   if (add == 0)
   {
      while (out_digits > 0 && num[out_digits-1] == 0)
         --out_digits;
      return out_digits; /* may be 0 */
   }

   else /* negative result */
   {
      while (out_digits > 1 && num[out_digits-1] == 0xffff)
         --out_digits;

      return -out_digits;
   }
}

static int
uarb_add32(uarb num, int in_digits, png_uint_32 add)
   /* As above but this works with any 32-bit value and only does 'add' */
{
   if (in_digits > 0)
   {
      in_digits = uarb_inc(num, in_digits, add & 0xffff);
      return uarb_inc(num+1, in_digits-1, add >> 16)+1;
   }

   return uarb_set(num, add);
}

static int
uarb_mult_digit(uarb acc, int a_digits, uarb num, FIX_GCC int n_digits,
   png_uint_16 val)
   /* Primitive one-digit multiply - 'val' must be 0..65535. Note that this
    * primitive is a multiply and accumulate - the result of *num * val is added
    * to *acc.
    *
    * This is a one-digit multiply, so the product may be up to one digit longer
    * than 'num', however the add to 'acc' means that the caller must ensure
    * that 'acc' is at least one digit longer than this *and* at least one digit
    * longer than the current length of 'acc'.  (Or the caller must otherwise
    * ensure 'adigits' is adequate from knowledge of the values.)
    */
{
   /* The digits in *acc, *num and val are in the range 0..65535, so the
    * result below is at most (65535*65535)+2*65635 = 65535*(65535+2), which is
    * exactly 0xffffffff.
    */
   if (val > 0 && n_digits > 0) /* Else the product is 0 */
   {
      png_uint_32 carry = 0;
      int out_digits = 0;

      while (out_digits < n_digits || carry > 0)
      {
         if (out_digits < a_digits)
            carry += acc[out_digits];

         if (out_digits < n_digits)
            carry += (png_uint_32)num[out_digits] * val;

         acc[out_digits++] = (png_uint_16)(carry & 0xffff);
         carry >>= 16;
      }

      /* So carry is 0 and all the input digits have been consumed. This means
       * that it is possible to skip any remaining digits in acc.
       */
      if (out_digits > a_digits)
         return out_digits;
   }

   return a_digits;
}

static int
uarb_mult32(uarb acc, int a_digits, uarb num, int n_digits, png_uint_32 val)
   /* calculate acc += num * val, 'val' may be any 32-bit value, 'acc' and 'num'
    * may be any value, returns the number of digits in 'acc'.
    */
{
   if (n_digits > 0 && val > 0)
   {
      a_digits = uarb_mult_digit(acc, a_digits, num, n_digits,
         (png_uint_16)(val & 0xffff));

      val >>= 16;
      if (val > 0)
         a_digits = uarb_mult_digit(acc+1, a_digits-1, num, n_digits,
            (png_uint_16)val) + 1;

      /* Because n_digits and val are >0 the following must be true: */
      assert(a_digits > 0);
   }

   return a_digits;
}

static int
uarb_shift(uarb inout, int ndigits, unsigned int right_shift)
   /* Shift inout right by right_shift bits, right_shift must be in the range
    * 1..15
    */
{
   FIX_GCC int i = ndigits;
   png_uint_16 carry = 0;

   assert(right_shift >= 1 && right_shift <= 15);

   while (--i >= 0)
   {
      png_uint_16 temp = (png_uint_16)(carry | (inout[i] >> right_shift));

      /* Bottom bits to top bits of carry */
      carry = (png_uint_16)((inout[i] << (16-right_shift)) & 0xffff);

      inout[i] = temp;

      /* The shift may reduce ndigits */
      if (i == ndigits-1 && temp == 0)
         ndigits = i;
   }

   return ndigits;
}

static int
uarb_cmp(uarb a, int adigits, uarb b, int bdigits)
   /* Return -1/0/+1 according as a<b/a==b/a>b */
{
   if (adigits < bdigits)
      return -1;

   if (adigits > bdigits)
      return 1;

   while (adigits-- > 0)
      if (a[adigits] < b[adigits])
         return -1;

      else if (a[adigits] > b[adigits])
         return 1;

   return 0;
}

#if 0 /*UNUSED*/
static int
uarb_eq32(uarb num, int digits, png_uint_32 val)
   /* Return true if the uarb is equal to 'val' */
{
   switch (digits)
   {
      case 0:  return val == 0;
      case 1:  return val == num[0];
      case 2:  return (val & 0xffff) == num[0] && (val >> 16) == num[1];
      default: return 0;
   }
}
#endif

static void
uarb_printx(uarb num, int digits, FILE *out)
   /* Print 'num' as a hexadecimal number (easier than decimal!) */
{
   while (digits > 0)
      if (num[--digits] > 0)
      {
         fprintf(out, "0x%x", num[digits]);

         while (digits > 0)
            fprintf(out, "%.4x", num[--digits]);
      }

      else if (digits == 0) /* the number is 0 */
         fputs("0x0", out);
}

static void
uarb_print(uarb num, int digits, FILE *out)
   /* Prints 'num' as a decimal if it will fit in an unsigned long, else as a
    * hexadecimal number.  Notice that the results vary for images over 4GByte
    * in a system dependent way, and the hexadecimal form doesn't work very well
    * in awk script input.
    *
    *
    * TODO: write uarb_div10
    */
{
   if (digits * sizeof (udigit) > sizeof (unsigned long))
      uarb_printx(num, digits, out);

   else
   {
      unsigned long n = 0;

      while (digits > 0)
         n = (n << 16) + num[--digits];

      fprintf(out, "%lu", n);
   }
}

/* Generate random bytes.  This uses a boring repeatable algorithm and it
 * is implemented here so that it gives the same set of numbers on every
 * architecture.  It's a linear congruential generator (Knuth or Sedgewick
 * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
 * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
 * Generation.)
 *
 * (Copied from contrib/libtests/pngvalid.c)
 */
static void
make_random_bytes(png_uint_32* seed, void* pv, size_t size)
{
   png_uint_32 u0 = seed[0], u1 = seed[1];
   png_bytep bytes = voidcast(png_bytep, pv);

   /* There are thirty-three bits; the next bit in the sequence is bit-33 XOR
    * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.
    */
   size_t i;
   for (i=0; i<size; ++i)
   {
      /* First generate 8 new bits then shift them in at the end. */
      png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
      u1 <<= 8;
      u1 |= u0 >> 24;
      u0 <<= 8;
      u0 |= u;
      *bytes++ = (png_byte)u;
   }

   seed[0] = u0;
   seed[1] = u1;
}

/* Clear an object to a random value. */
static void
clear(void *pv, size_t size)
{
   static png_uint_32 clear_seed[2] = { 0x12345678, 0x9abcdef0 };
   make_random_bytes(clear_seed, pv, size);
}

#define CLEAR(object) clear(&(object), sizeof (object))

/* Copied from unreleased 1.7 code.
 *
 * CRC checking uses a local pre-built implementation of the Ethernet CRC32.
 * This is to avoid a function call to the zlib DLL and to optimize the
 * byte-by-byte case.
 */
static png_uint_32 crc_table[256] =
{
   0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
   0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
   0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
   0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
   0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
   0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
   0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
   0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
   0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
   0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
   0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
   0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
   0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
   0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
   0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
   0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
   0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
   0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
   0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
   0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
   0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
   0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
   0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
   0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
   0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
   0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
   0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
   0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
   0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
   0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
   0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
   0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
   0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
   0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
   0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
   0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
   0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
   0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
   0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
   0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
   0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
   0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
   0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
   0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
   0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
   0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
   0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
   0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
   0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
   0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
   0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
   0x2d02ef8d
};

/* The CRC calculated here *IS* conditioned, the corresponding value used by
 * zlib and the result value is obtained by XORing with CRC_INIT, which is also
 * the first value that must be passed in (for the first byte) to crc_one_byte.
 */
#define CRC_INIT 0xffffffff

static png_uint_32
crc_one_byte(png_uint_32 crc, int b)
{
   return crc_table[(crc ^ b) & 0xff] ^ (crc >> 8);
}

static png_uint_32
crc_init_4(png_uint_32 value)
{
   /* This is an alternative to the algorithm used in zlib, which requires four
    * separate tables to parallelize the four byte operations, it only works for
    * a CRC of the first four bytes of the stream, but this is what happens in
    * the parser below where length+chunk-name is read and chunk-name used to
    * initialize the CRC.  Notice that the calculation here avoids repeated
    * conditioning (xor with 0xffffffff) by storing the conditioned value.
    */
   png_uint_32 crc = crc_table[(~value >> 24)] ^ 0xffffff;

   crc = crc_table[(crc ^ (value >> 16)) & 0xff] ^ (crc >> 8);
   crc = crc_table[(crc ^ (value >> 8)) & 0xff] ^ (crc >> 8);
   return crc_table[(crc ^ value) & 0xff] ^ (crc >> 8);
}

static int
chunk_type_valid(png_uint_32 c)
   /* Bit whacking approach to chunk name validation that is intended to avoid
    * branches.  The cost is that it uses a lot of 32-bit constants, which might
    * be bad on some architectures.
    */
{
   png_uint_32 t;

   /* Remove bit 5 from all but the reserved byte; this means every
    * 8-bit unit must be in the range 65-90 to be valid.  So bit 5
    * must be zero, bit 6 must be set and bit 7 zero.
    */
   c &= ~PNG_U32(32,32,0,32);
   t = (c & ~0x1f1f1f1f) ^ 0x40404040;

   /* Subtract 65 for each 8-bit quantity, this must not overflow
    * and each byte must then be in the range 0-25.
    */
   c -= PNG_U32(65,65,65,65);
   t |=c ;

   /* Subtract 26, handling the overflow which should set the top
    * three bits of each byte.
    */
   c -= PNG_U32(25,25,25,26);
   t |= ~c;

   return (t & 0xe0e0e0e0) == 0;
}

/**************************** CONTROL INFORMATION *****************************/

/* Information about a sequence of IDAT chunks, the chunks have been re-synced
 * using sync_stream below and the new lengths are recorded here.  Because the
 * number of chunks is unlimited this is handled using a linked list of these
 * structures.
 */
struct IDAT_list
{
   struct IDAT_list *next;     /* Linked list */
   unsigned int      length;   /* Actual length of the array below */
   unsigned int      count;    /* Number of entries that are valid */
#     define IDAT_INIT_LENGTH 16
   png_uint_32       lengths[IDAT_INIT_LENGTH];
};

static void
IDAT_list_init(struct IDAT_list *list)
{
   CLEAR(*list);

   list->next = NULL;
   list->length = IDAT_INIT_LENGTH;
}

static size_t
IDAT_list_size(struct IDAT_list *list, unsigned int length)
   /* Return the size in bytes of an IDAT_list of the given length. */
{
   if (list != NULL)
      length = list->length;

   return sizeof *list - sizeof list->lengths +
      length * sizeof list->lengths[0];
}

static void
IDAT_list_end(struct IDAT_list *IDAT_list)
{
   struct IDAT_list *list = IDAT_list->next;

   CLEAR(*IDAT_list);

   while (list != NULL)
   {
      struct IDAT_list *next = list->next;

      clear(list, IDAT_list_size(list, 0));
      free(list);
      list = next;
   }
}

static struct IDAT_list *
IDAT_list_extend(struct IDAT_list *tail)
{
   /* Use the previous cached value if available. */
   struct IDAT_list *next = tail->next;

   if (next == NULL)
   {
      /* Insert a new, malloc'ed, block of IDAT information buffers, this
       * one twice as large as the previous one:
       */
      unsigned int length = 2 * tail->length;

      if (length < tail->length) /* arithmetic overflow */
         length = tail->length;

      next = voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length)));
      CLEAR(*next);

      /* The caller must handle this: */
      if (next == NULL)
         return NULL;

      next->next = NULL;
      next->length = length;
      tail->next = next;
   }

   return next;
}

/* GLOBAL CONTROL STRUCTURE */
struct global
{
   /* PUBLIC GLOBAL VARIABLES: OWNER INITIALIZE */
   unsigned int   errors        :1; /* print file errors to stderr */
   unsigned int   warnings      :1; /* print libpng warnings to stderr */
   unsigned int   optimize_zlib :1; /* Run optimization search */
   unsigned int   quiet         :2; /* don't output summaries */
   unsigned int   verbose       :3; /* various internal tracking */
   unsigned int   skip          :3; /* Non-critical chunks to skip */
#     define SKIP_NONE      0
#     define SKIP_BAD_CRC   1    /* Chunks with a bad CRC */
#     define SKIP_UNSAFE    2    /* Chunks not safe to copy */
#     define SKIP_UNUSED    3    /* Chunks not used by libpng */
#     define SKIP_TRANSFORM 4    /* Chunks only used in transforms */
#     define SKIP_COLOR     5    /* Everything but tRNS, sBIT, gAMA and sRGB */
#     define SKIP_ALL       6    /* Everything but tRNS and sBIT */

   png_uint_32    idat_max;         /* 0 to perform no re-chunking */

   int            status_code;      /* Accumulated status code */
#     define TOO_FAR_BACK   0x01 /* found a too-far-back error */
#     define CRC_ERROR      0x02 /* fixed an invalid CRC */
#     define STREAM_ERROR   0x04 /* damaged PNG stream (may be fixable) */
#     define TRUNCATED      0x08 /* truncated but still readable */
#     define FILE_ERROR     0x10 /* could not read the file */
#     define WRITE_ERROR    0x20 /* write error (this terminates the read) */
#     define INTERNAL_ERROR 0x40 /* internal limits/errors encountered */

   /* PUBLIC GLOBAL VARIABLES: USED INTERNALLY BY IDAT READ CODE */
   struct IDAT_list idat_cache;  /* Cache of file IDAT information buffers */
      /* The structure is shared across all uses of this global control
       * structure to avoid reallocation between IDAT streams.
       */
};

static int
global_end(struct global *global)
{

   int rc;

   IDAT_list_end(&global->idat_cache);
   rc = global->status_code;
   CLEAR(*global);
   return rc;
}

static void
global_init(struct global *global)
   /* Call this once (and only once) to initialize the control */
{
   CLEAR(*global);

   /* Globals */
   global->errors        = 0;
   global->warnings      = 0;
   global->quiet         = 0;
   global->verbose       = 0;
   global->idat_max      = 0;         /* no re-chunking of IDAT */
   global->optimize_zlib = 0;
   global->skip          = SKIP_NONE;
   global->status_code   = 0;

   IDAT_list_init(&global->idat_cache);
}

static int
skip_chunk_type(const struct global *global, png_uint_32 type)
   /* Return true if this chunk is to be skipped according to the --strip
    * option.  This code needs to recognize all known ancillary chunks in order
    * to handle the --strip=unsafe option.
    */
{
   /* Never strip critical chunks: */
   if (CRITICAL(type))
      return 0;

   switch (type)
   {
      /* Chunks that are treated as, effectively, critical because they affect
       * correct interpretation of the pixel values:
       */
      case png_tRNS: case png_sBIT:
         return 0;

      /* Chunks that specify gamma encoding which should therefore only be
       * removed the the user insists:
       */
      case png_gAMA: case png_sRGB:
         if (global->skip >= SKIP_ALL)
            return 1;
         return 0;

      /* Chunks that affect color interpretation - not used by libpng and rarely
       * used by applications, but technically still required for correct
       * interpretation of the image data:
       */
      case png_cHRM: case png_iCCP:
         if (global->skip >= SKIP_COLOR)
            return 1;
         return 0;

      /* Other chunks that are used by libpng in image transformations (as
       * opposed to known chunks that have get/set APIs but are not otherwise
       * used.)
       */
      case png_bKGD:
         if (global->skip >= SKIP_TRANSFORM)
            return 1;
         return 0;

      /* All other chunks that libpng knows about and affect neither image
       * interpretation nor libpng transforms - chunks that are effectively
       * unused by libpng even though libpng might recognize and store them.
       */
      case png_fRAc: case png_gIFg: case png_gIFt: case png_gIFx: case png_hIST:
      case png_iTXt: case png_oFFs: case png_pCAL: case png_pHYs: case png_sCAL:
      case png_sPLT: case png_sTER: case png_tEXt: case png_tIME: case png_zTXt:
         if (global->skip >= SKIP_UNUSED)
            return 1;
         return 0;

      /* Chunks that libpng does not know about (notice that this depends on the
       * list above including all known chunks!)  The decision here depends on
       * whether the safe-to-copy bit is set in the chunk type.
       */
      default:
         if (SAFE_TO_COPY(type))
         {
            if (global->skip >= SKIP_UNUSED) /* as above */
               return 1;
         }

         else if (global->skip >= SKIP_UNSAFE)
            return 1;

         return 0;
   }
}

/* PER-FILE CONTROL STRUCTURE */
struct chunk;
struct IDAT;
struct file
{
   /* ANCESTORS */
   struct global *global;

   /* PUBLIC PER-FILE VARIABLES: CALLER INITIALIZE */
   const char *   file_name;
   const char *   out_name;      /* Name of output file (if required) */

   /* PUBLIC PER-FILE VARIABLES: SET BY PNG READ CODE */
   /* File specific result codes */
   int            status_code;   /* Set to a bit mask of the following: */
   int            read_errno;    /* Records a read error errno */
   int            write_errno;   /* Records a write error errno */

   /* IHDR information */
   png_uint_32    width;
   png_uint_32    height;
   png_byte       bit_depth;
   png_byte       color_type;
   png_byte       compression_method;
   png_byte       filter_method;
   png_byte       interlace_method;

   udigit         image_bytes[5];
   int            image_digits;

   /* PROTECTED PER-FILE VARIABLES: USED BY THE READ CODE */
   FILE *         file;          /* Original PNG file */
   FILE *         out;           /* If a new one is being written */
   jmp_buf        jmpbuf;        /* Set while reading a PNG */

   /* PROTECTED CHUNK SPECIFIC VARIABLES: USED BY CHUNK CODE */
   /* The following variables are used during reading to record the length, type
    * and data position of the *next* chunk or, right at the start, the
    * signature (in length,type).
    *
    * When a chunk control structure is instantiated these values are copied
    * into the structure and can then be overritten with the data for the next
    * chunk.
    */
   fpos_t         data_pos;      /* Position of first byte of chunk data */
   png_uint_32    length;        /* First word (length or signature start) */
   png_uint_32    type;          /* Second word (type or signature end) */
   png_uint_32    crc;           /* Running chunk CRC (used by read_chunk) */

   /* These counts are maintained by the read and write routines below and are
    * reset by the chunk handling code.  They record the total number of bytes
    * read or written for the chunk, including the header (length,type) bytes.
    */
   png_uint_32    read_count;    /* Count of bytes read (in the chunk) */
   png_uint_32    write_count;   /* Count of bytes written (in the chunk) */
   int            state;         /* As defined here: */
#     define STATE_SIGNATURE  0  /* The signature is being written */
#     define STATE_CHUNKS     1  /* Non-IDAT chunks are being written */
#     define STATE_IDAT       2  /* An IDAT stream is being written */

   /* Two pointers used to enable clean-up in the event of fatal errors and to
    * hold state about the parser process (only one of each at present.)
    */
   struct chunk * chunk;
   struct IDAT *  idat;

   /* Interface to allocate a new chunk or IDAT control structure.  The result
    * is returned by setting one or other of the above variables.  Note that the
    * relevant initializer is called by the allocator function.  The alloc_ptr
    * is used only by the implementation of the allocate function.
    */
   void *         alloc_ptr;
   void         (*alloc)(struct file*,int idat);
                                  /* idat: allocate IDAT not chunk */
};

/* Valid longjmp (stop) codes are: */
#define LIBPNG_WARNING_CODE   1 /* generic png_error */
#define LIBPNG_ERROR_CODE     2 /* generic png_error */
#define ZLIB_ERROR_CODE       3 /* generic zlib error */
#define INVALID_ERROR_CODE    4 /* detected an invalid PNG */
#define READ_ERROR_CODE       5 /* read failed */
#define WRITE_ERROR_CODE      6 /* error in write */
#define UNEXPECTED_ERROR_CODE 7 /* unexpected (internal?) error */

static void
emit_string(const char *str, FILE *out)
   /* Print a string with spaces replaced by '_' and non-printing characters by
    * an octal escape.
    */
{
   for (; *str; ++str)
      if (isgraph(UCHAR_MAX & *str))
         putc(*str, out);

      else if (isspace(UCHAR_MAX & *str))
         putc('_', out);

      else
         fprintf(out, "\\%.3o", *str);
}

static const char *
strcode(int code)
{
   switch (code)
   {
      case LIBPNG_WARNING_CODE:   return "warning";
      case LIBPNG_ERROR_CODE:     return "libpng";
      case ZLIB_ERROR_CODE:       return "zlib";
      case INVALID_ERROR_CODE:    return "invalid";
      case READ_ERROR_CODE:       return "read";
      case WRITE_ERROR_CODE:      return "write";
      case UNEXPECTED_ERROR_CODE: return "unexpected";
      default:                    return "INVALID";
   }
}

static void
emit_error(struct file *file, int code, const char *what)
   /* Generic error message routine, takes a 'stop' code but can be used
    * elsewhere.  Always outputs a message.
    */
{
   const char *reason;
   int err = 0;

   switch (code)
   {
      case LIBPNG_WARNING_CODE:   reason = "libpng warning:"; break;
      case LIBPNG_ERROR_CODE:     reason = "libpng error:"; break;
      case ZLIB_ERROR_CODE:       reason = "zlib error:"; break;
      case INVALID_ERROR_CODE:    reason = "invalid"; break;
      case READ_ERROR_CODE:       reason = "read failure:";
                                  err = file->read_errno;
                                  break;
      case WRITE_ERROR_CODE:      reason = "write error";
                                  err = file->write_errno;
                                  break;
      case UNEXPECTED_ERROR_CODE: reason = "unexpected error:";
                                  err = file->read_errno;
                                  if (err == 0)
                                     err = file->write_errno;
                                  break;
      default:                    reason = "INVALID (internal error):"; break;
   }

   if (err != 0)
      fprintf(stderr, "%s: %s %s [%s]\n", file->file_name, reason, what,
         strerror(err));

   else
      fprintf(stderr, "%s: %s %s\n", file->file_name, reason, what);
}

static void chunk_end(struct chunk **);
static void IDAT_end(struct IDAT **);

static int
file_end(struct file *file)
{
   int rc;

   /* If either of the chunk pointers are set end them here, the IDAT structure
    * must be deallocated first as it may deallocate the chunk structure.
    */
   if (file->idat != NULL)
      IDAT_end(&file->idat);

   if (file->chunk != NULL)
      chunk_end(&file->chunk);

   rc = file->status_code;

   if (file->file != NULL)
      (void)fclose(file->file);

   if (file->out != NULL)
   {
      /* NOTE: this is bitwise |, all the following functions must execute and
       * must succeed.
       */
      if (ferror(file->out) | fflush(file->out) | fclose(file->out))
      {
         perror(file->out_name);
         emit_error(file, READ_ERROR_CODE, "output write error");
         rc |= WRITE_ERROR;
      }
   }

   /* Accumulate the result codes */
   file->global->status_code |= rc;

   CLEAR(*file);

   return rc; /* status code: non-zero on read or write error */
}

static int
file_init(struct file *file, struct global *global, const char *file_name,
   const char *out_name, void *alloc_ptr, void (*alloc)(struct file*,int))
   /* Initialize a file control structure.  This will open the given files as
    * well.  The status code returned is 0 on success, non zero (using the flags
    * above) on a file open error.
    */
{
   CLEAR(*file);
   file->global = global;

   file->file_name = file_name;
   file->out_name = out_name;
   file->status_code = 0;
   file->read_errno = 0;
   file->write_errno = 0;

   file->file = NULL;
   file->out = NULL;
   /* jmpbuf is garbage: must be set by read_png */

   file->read_count = 0;
   file->state = STATE_SIGNATURE;

   file->chunk = NULL;
   file->idat = NULL;

   file->alloc_ptr = alloc_ptr;
   file->alloc = alloc;

   /* Open the files: */
   assert(file_name != NULL);
   file->file = fopen(file_name, "rb");

   if (file->file == NULL)
   {
      file->read_errno = errno;
      file->status_code |= FILE_ERROR;
      /* Always output: please give a readable file! */
      perror(file_name);
      return FILE_ERROR;
   }

   if (out_name != NULL)
   {
      file->out = fopen(out_name, "wb");

      if (file->out == NULL)
      {
         file->write_errno = errno;
         file->status_code |= WRITE_ERROR;
         perror(out_name);
         return WRITE_ERROR;
      }
   }

   return 0;
}

static void
log_error(struct file *file, int code, const char *what)
   /* Like emit_error but checks the global 'errors' flag */
{
   if (file->global->errors)
      emit_error(file, code, what);
}

static char
type_char(png_uint_32 v)
{
   /* In fact because chunk::chunk_type is validated prior to any call to this
    * function it will always return a-zA-Z, but the extra codes are just there
    * to help in finding internal (programming) errors.  Note that the code only
    * ever considers the low 7 bits of the value (so it is not necessary for the
    * type_name function to mask of the byte.)
    */
   if (v & 32)
      return "!abcdefghijklmnopqrstuvwxyz56789"[(v-96)&31];

   else
      return "@ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"[(v-64)&31];
}

static void
type_name(png_uint_32 type, FILE *out)
{
   putc(type_char(type >> 24), out);
   putc(type_char(type >> 16), out);
   putc(type_char(type >>  8), out);
   putc(type_char(type      ), out);
}

static void
type_sep(FILE *out)
{
   putc(':', out);
   putc(' ', out);
}

static png_uint_32 current_type(struct file *file, int code);

PNG_NORETURN static void
stop(struct file *file, int code, const char *what)
   /* Return control when a PNG file cannot be read. This outputs an 'ERR'
    * summary line too.
    */
{
   log_error(file, code, what);

   /* The chunk being read is typically identified by file->chunk or, if this is
    * NULL, by file->type.  This may be wrong if libpng reads ahead, but this
    * only happens with IDAT where libpng reads the header then jumps around
    * finding errors in the previous chunks.  We know that is happening because
    * we are at the start of the IDAT (i.e. no IDAT data has yet been written.)
    *
    * SUMMARY FORMAT (stop):
    *
    * IDAT ERR status code read-errno write-errno message file
    *
    * 'uncompressed' will be 0 if there was a problem in the IHDR.  The errno
    * values are emit_string(strerror(errno)).
    */
   if (file->global->quiet < 2) /* need two quiets to stop this. */
   {
      png_uint_32 type;

      if (file->chunk != NULL)
         type = current_type(file, code); /* Gropes in struct chunk and IDAT */

      else
         type = file->type;

      if (type)
         type_name(type, stdout);

      else /* magic: an IDAT header, produces bogons for too many IDATs */
         fputs("HEAD", stdout); /* not a registered chunk! */

      printf(" ERR %.2x %s ", file->status_code, strcode(code));
      /* This only works one strerror at a time, because of the way strerror is
       * implemented.
       */
      emit_string(strerror(file->read_errno), stdout);
      putc(' ', stdout);
      emit_string(strerror(file->write_errno), stdout);
      putc(' ', stdout);
      emit_string(what, stdout);
      putc(' ', stdout);
      fputs(file->file_name, stdout);
      putc('\n', stdout);
   }

   file->status_code |= FILE_ERROR;
   longjmp(file->jmpbuf, code);
}

PNG_NORETURN static void
stop_invalid(struct file *file, const char *what)
{
   stop(file, INVALID_ERROR_CODE, what);
}

static void
type_message(struct file *file, png_uint_32 type, const char *what)
   /* Error message for a chunk; the chunk name comes from 'type' */
{
   if (file->global->errors)
   {
      fputs(file->file_name, stderr);
      type_sep(stderr);
      type_name(type, stderr);
      type_sep(stderr);
      fputs(what, stderr);
      putc('\n', stderr);
   }
}

/* Input file positioning - we jump around in the input file while reading
 * stuff, these wrappers deal with the error handling.
 */
static void
file_getpos(struct file *file, fpos_t *pos)
{
   if (fgetpos(file->file, pos))
   {
      /* This is unexpected, so perror it */
      perror(file->file_name);
      stop(file, READ_ERROR_CODE, "fgetpos");
   }
}

static void
file_setpos(struct file *file, const fpos_t *pos)
{
   if (fsetpos(file->file, pos))
   {
      perror(file->file_name);
      stop(file, READ_ERROR_CODE, "fsetpos");
   }
}

static void
getpos(struct file *file)
   /* Get the current position and store it in 'data_pos'.  The corresponding
    * setpos() function is chunk specific because it uses the copy of the
    * position for the specific chunk.
    */
{
   file_getpos(file, &file->data_pos);
}


/* Read utility - read a single byte, returns a value in the range 0..255 or EOF
 * on a read error.  In the latter case status_code and read_errno are updated
 * appropriately.
 */
static int
read_byte(struct file *file)
{
   int ch = getc(file->file);

   if (ch >= 0 && ch <= 255)
   {
      ++(file->read_count);
      return ch;
   }

   else if (ch != EOF)
   {
      file->status_code |= INTERNAL_ERROR;
      file->read_errno = ERANGE; /* out of range character */

      /* This is very unexpected; an error message is always output: */
      emit_error(file, UNEXPECTED_ERROR_CODE, "file read");
   }

#  ifdef EINTR
      else if (errno == EINTR) /* Interrupted, try again */
      {
         errno = 0;
         return read_byte(file);
      }
#  endif

   else
   {
      /* An error, it doesn't really matter what the error is but it gets
       * recorded anyway.
       */
      if (ferror(file->file))
         file->read_errno = errno;

      else if (feof(file->file))
         file->read_errno = 0; /* I.e. a regular EOF, no error */

      else /* unexpected */
         file->read_errno = EDOM;
   }

   /* 'TRUNCATED' is used for all cases of failure to read a byte, because of
    * the way libpng works a byte read is never attempted unless the byte is
    * expected to be there, so EOF should not occur.
    */
   file->status_code |= TRUNCATED;
   return EOF;
}

static png_byte
reread_byte(struct file *file)
   /* Read a byte when an error is not expected to happen because the byte has
    * been read before without error.
    */
{
   int ch = getc(file->file);

   if (errno != 0)
      file->read_errno = errno;

   if (ch < 0 || ch > 255)
      stop(file, UNEXPECTED_ERROR_CODE, "reread");

   return (png_byte)ch;
}

static png_uint_32
reread_4(struct file *file)
   /* The same but for a four byte quantity */
{
   png_uint_32 result = 0;
   int i = 0;

   while (++i <= 4)
      result = (result << 8) + reread_byte(file);

   return result;
}

static void
skip_12(struct file *file)
   /* Skip exactly 12 bytes in the input stream - used to skip a CRC and chunk
    * header that has been read before.
    */
{
   /* Since the chunks were read before this shouldn't fail: */
   if (fseek(file->file, 12, SEEK_CUR) != 0)
   {
      if (errno != 0)
         file->read_errno = errno;

      stop(file, UNEXPECTED_ERROR_CODE, "reskip");
   }
}

static void
write_byte(struct file *file, int b)
   /* Write one byte to the output - this causes a fatal error if the write
    * fails and the read of this PNG file immediately terminates.  Just
    * increments the write count if there is no output file.
    */
{
   if (file->out != NULL)
   {
      if (putc(b, file->out) != b)
      {
         file->write_errno = errno;
         file->status_code |= WRITE_ERROR;
         stop(file, WRITE_ERROR_CODE, "write byte");
      }
   }

   ++(file->write_count);
}

/* Derivatives of the read/write functions. */
static unsigned int
read_4(struct file *file, png_uint_32 *pu)
   /* Read four bytes, returns the number of bytes read successfully and, if all
    * four bytes are read, assigns the result to *pu.
    */
{
   unsigned int i = 0;
   png_uint_32 val = 0;

   do
   {
      int ch = read_byte(file);

      if (ch == EOF)
         return i;

      val = (val << 8) + ch;
   } while (++i < 4);

   *pu = val;
   return i;
}

/* CRC handling - read but calculate the CRC while doing so. */
static int
crc_read_many(struct file *file, png_uint_32 length)
   /* Reads 'length' bytes and updates the CRC, returns true on success, false
    * if the input is truncated.
    */
{
   if (length > 0)
   {
      png_uint_32 crc = file->crc;

      do
      {
         int ch = read_byte(file);

         if (ch == EOF)
            return 0; /* Truncated */

         crc = crc_one_byte(crc, ch);
      }
      while (--length > 0);

      file->crc = crc;
   }

   return 1; /* OK */
}

static int
calc_image_size(struct file *file)
   /* Fill in the image_bytes field given the IHDR information, calls stop on
    * error.
    */
{
   png_uint_16 pd = file->bit_depth;

   switch (file->color_type)
   {
      default:
         stop_invalid(file, "IHDR: colour type");

      invalid_bit_depth:
         stop_invalid(file, "IHDR: bit depth");

      case 0: /* g */
         if (pd != 1 && pd != 2 && pd != 4 && pd != 8 && pd != 16)
            goto invalid_bit_depth;
         break;

      case 3:
         if (pd != 1 && pd != 2 && pd != 4 && pd != 8)
            goto invalid_bit_depth;
         break;

      case 2: /* rgb */
         if (pd != 8 && pd != 16)
            goto invalid_bit_depth;

         pd = (png_uint_16)(pd * 3);
         break;

      case 4: /* ga */
         if (pd != 8 && pd != 16)
            goto invalid_bit_depth;

         pd = (png_uint_16)(pd * 2);
         break;

      case 6: /* rgba */
         if (pd != 8 && pd != 16)
            goto invalid_bit_depth;

         pd = (png_uint_16)(pd * 4);
         break;
   }

   if (file->width < 1 || file->width > 0x7fffffff)
      stop_invalid(file, "IHDR: width");

   else if (file->height < 1 || file->height > 0x7fffffff)
      stop_invalid(file, "IHDR: height");

   else if (file->compression_method != 0)
      stop_invalid(file, "IHDR: compression method");

   else if (file->filter_method != 0)
      stop_invalid(file, "IHDR: filter method");

   else switch (file->interlace_method)
   {
      case PNG_INTERLACE_ADAM7:
         /* Interlacing makes the image larger because of the replication of
          * both the filter byte and the padding to a byte boundary.
          */
         {
            int pass;
            int image_digits = 0;
            udigit row_width[2], row_bytes[3];

            for (pass=0; pass<=6; ++pass)
            {
               png_uint_32 pw = PNG_PASS_COLS(file->width, pass);

               if (pw > 0)
               {
                  int  digits;

                  /* calculate 1+((pw*pd+7)>>3) in row_bytes */
                  digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),
                     row_width, uarb_set(row_width, pw), pd);
                  digits = uarb_shift(row_bytes, digits, 3);
                  digits = uarb_inc(row_bytes, digits, 1);

                  /* Add row_bytes * pass-height to the file image_bytes field
                   */
                  image_digits = uarb_mult32(file->image_bytes, image_digits,
                     row_bytes, digits,
                     PNG_PASS_ROWS(file->height, pass));
               }
            }

            file->image_digits = image_digits;
         }
         break;

      case PNG_INTERLACE_NONE:
         {
            int  digits;
            udigit row_width[2], row_bytes[3];

            /* As above, but use image_width in place of the pass width: */
            digits = uarb_mult_digit(row_bytes, uarb_set(row_bytes, 7),
               row_width, uarb_set(row_width, file->width), pd);
            digits = uarb_shift(row_bytes, digits, 3);
            digits = uarb_inc(row_bytes, digits, 1);

            /* Set row_bytes * image-height to the file image_bytes field */
            file->image_digits = uarb_mult32(file->image_bytes, 0,
               row_bytes, digits, file->height);
         }
         break;

      default:
         stop_invalid(file, "IHDR: interlace method");
   }

   assert(file->image_digits >= 1 && file->image_digits <= 5);
   return 1;
}

/* PER-CHUNK CONTROL STRUCTURE
 * This structure is instantiated for each chunk, except for the IDAT chunks
 * where one chunk control structure is used for the whole of a single stream of
 * IDAT chunks (see the IDAT control structure below).
 */
struct chunk
{
   /* ANCESTORS */
   struct file *         file;
   struct global *       global;

   /* PUBLIC IDAT INFORMATION: SET BY THE ZLIB CODE */
   udigit         uncompressed_bytes[5];
   int            uncompressed_digits;
   udigit         compressed_bytes[5];
   int            compressed_digits;

   /* PUBLIC PER-CHUNK INFORMATION: USED BY CHUNK READ CODE */
   /* This information is filled in by chunk_init from the data in the file
    * control structure, but chunk_length may be changed later.
    */
   fpos_t         chunk_data_pos;    /* Position of first byte of chunk data */
   png_uint_32    chunk_length;      /* From header (or modified below) */
   png_uint_32    chunk_type;        /* From header */

   /* PUBLIC PER-CHUNK INFORMATION: FOR THE CHUNK WRITE CODE */
   png_uint_32    write_crc;         /* Output CRC (may differ from read_crc) */
   png_uint_32    rewrite_offset;    /* Count of bytes before rewrite. */
   int            rewrite_length;    /* Number of bytes left to change */
   png_byte       rewrite_buffer[2]; /* Buffer of new byte values */
};

static void
chunk_message(struct chunk *chunk, const char *message)
{
   type_message(chunk->file, chunk->chunk_type, message);
}

static void
chunk_end(struct chunk **chunk_var)
{
   struct chunk *chunk = *chunk_var;

   *chunk_var = NULL;
   CLEAR(*chunk);
}

static void
chunk_init(struct chunk * const chunk, struct file * const file)
   /* When a chunk is initialized the file length/type/pos are copied into the
    * corresponding chunk fields and the new chunk is registered in the file
    * structure.  There can only be one chunk at a time.
    *
    * NOTE: this routine must onely be called from the file alloc routine!
    */
{
   assert(file->chunk == NULL);

   CLEAR(*chunk);

   chunk->file = file;
   chunk->global = file->global;

   chunk->chunk_data_pos = file->data_pos;
   chunk->chunk_length = file->length;
   chunk->chunk_type = file->type;

   /* Compresssed/uncompressed size information (from the zlib control structure
    * that is used to check the compressed data in a chunk.)
    */
   chunk->uncompressed_digits = 0;
   chunk->compressed_digits = 0;

   file->chunk = chunk;
}

static png_uint_32
current_type(struct file *file, int code)
   /* Guess the actual chunk type that causes a stop() */
{
   /* This may return png_IDAT for errors detected (late) in the header; that
    * includes any inter-chunk consistency check that libpng performs.  Assume
    * that if the chunk_type is png_IDAT and the file write count is 8 this is
    * what is happening.
    */
   if (file->chunk != NULL)
   {
      png_uint_32 type = file->chunk->chunk_type;

      /* This is probably wrong for the excess IDATs case, because then libpng
       * whines about too many of them (apparently in some cases erroneously)
       * when the header is read.
       */
      if (code <= LIBPNG_ERROR_CODE && type == png_IDAT &&
         file->write_count == 8)
         type = 0; /* magic */

      return type;
   }

   else
      return file->type;
}

static void
setpos(struct chunk *chunk)
   /* Reset the position to 'chunk_data_pos' - the start of the data for this
    * chunk.  As a side effect the read_count in the file is reset to 8, just
    * after the length/type header.
    */
{
   chunk->file->read_count = 8;
   file_setpos(chunk->file, &chunk->chunk_data_pos);
}

/* Specific chunk handling - called for each chunk header, all special chunk
 * processing is initiated in these functions.
 */
/* The next functions handle special processing for those chunks with LZ data,
 * the data is identified and checked for validity.  If there are problems which
 * cannot be corrected the routines return false, otherwise true (although
 * modification to the zlib header may be required.)
 *
 * The compressed data is in zlib format (RFC1950) and consequently has a
 * minimum length of 7 bytes.
 */
static int zlib_check(struct file *file, png_uint_32 offset);

static int
process_zTXt_iCCP(struct file *file)
   /* zTXt and iCCP have exactly the same form - keyword, null, compression
    * method then compressed data.
    */
{
   struct chunk *chunk = file->chunk;
   png_uint_32 length;
   png_uint_32 index = 0;

   assert(chunk != NULL && file->idat == NULL);
   length = chunk->chunk_length;
   setpos(chunk);

   while (length >= 9)
   {
      --length;
      ++index;
      if (reread_byte(file) == 0) /* keyword null terminator */
      {
         --length;
         ++index;
         (void)reread_byte(file); /* compression method */
         return zlib_check(file, index);
      }
   }

   chunk_message(chunk, "too short");
   return 0; /* skip */
}

static int
process_iTXt(struct file *file)
{
   /* Like zTXt but more fields. */
   struct chunk *chunk = file->chunk;
   png_uint_32 length;
   png_uint_32 index = 0;

   assert(chunk != NULL && file->idat == NULL);
   length = chunk->chunk_length;
   setpos(chunk);

   while (length >= 5)
   {
      --length;
      ++index;
      if (reread_byte(file) == 0) /* keyword null terminator */
      {
         --length;
         ++index;
         if (reread_byte(file) == 0) /* uncompressed text */
            return 1; /* nothing to check */

         --length;
         ++index;
         (void)reread_byte(file); /* compression method */

         /* Skip the language tag (null terminated). */
         while (length >= 9)
         {
            --length;
            ++index;
            if (reread_byte(file) == 0) /* terminator */
            {
               /* Skip the translated keyword */
               while (length >= 8)
               {
                  --length;
                  ++index;
                  if (reread_byte(file) == 0) /* terminator */
                     return zlib_check(file, index);
               }
            }
         }

         /* Ran out of bytes in the compressed case. */
         break;
      }
   }

   log_error(file, INVALID_ERROR_CODE, "iTXt chunk length");

   return 0; /* skip */
}

/* IDAT READ/WRITE CONTROL STRUCTURE */
struct IDAT
{
   /* ANCESTORS */
   struct file *         file;
   struct global *       global;

   /* PROTECTED IDAT INFORMATION: SET BY THE IDAT READ CODE */
   struct IDAT_list *idat_list_head; /* START of the list of IDAT information */
   struct IDAT_list *idat_list_tail; /* *END* of the list of IDAT information */

   /* PROTECTED IDAT INFORMATION: USED BY THE IDAT WRITE CODE */
   struct IDAT_list *idat_cur;       /* Current list entry */
   unsigned int      idat_count;     /* And the *current* index into the list */
   png_uint_32       idat_index;     /* Index of *next* input byte to write */
   png_uint_32       idat_length;    /* Cache of current chunk length */
};

/* NOTE: there is currently no IDAT_reset, so a stream cannot contain more than
 * one IDAT sequence (i.e. MNG is not supported).
 */

static void
IDAT_end(struct IDAT **idat_var)
{
   struct IDAT *idat = *idat_var;
   struct file *file = idat->file;

   *idat_var = NULL;

   CLEAR(*idat);

   assert(file->chunk != NULL);
   chunk_end(&file->chunk);

   /* Regardless of why the IDAT was killed set the state back to CHUNKS (it may
    * already be CHUNKS because the state isn't changed until process_IDAT
    * returns; a stop will cause IDAT_end to be entered in state CHUNKS!)
    */
   file->state = STATE_CHUNKS;
}

static void
IDAT_init(struct IDAT * const idat, struct file * const file)
   /* When the chunk is png_IDAT instantiate an IDAT control structure in place
    * of a chunk control structure.  The IDAT will instantiate a chunk control
    * structure using the file alloc routine.
    *
    * NOTE: this routine must only be called from the file alloc routine!
    */
{
   assert(file->chunk == NULL);
   assert(file->idat == NULL);

   CLEAR(*idat);

   idat->file = file;
   idat->global = file->global;

   /* Initialize the tail to the pre-allocated buffer and set the count to 0
    * (empty.)
    */
   idat->global->idat_cache.count = 0;
   idat->idat_list_head = idat->idat_list_tail = &idat->global->idat_cache;

   /* Now the chunk.  The allocator calls the initializer of the new chunk and
    * stores the result in file->chunk:
    */
   file->alloc(file, 0/*chunk*/);
   assert(file->chunk != NULL);

   /* And store this for cleanup (and to check for double alloc or failure to
    * free.)
    */
   file->idat = idat;
}

static png_uint_32
rechunk_length(struct IDAT *idat)
   /* Return the length for the next IDAT chunk, taking into account
    * rechunking.
    */
{
   png_uint_32 len = idat->global->idat_max;

   if (len == 0) /* use original chunk lengths */
   {
      const struct IDAT_list *cur;
      unsigned int count;

      if (idat->idat_index == 0) /* at the new chunk (first time) */
         return idat->idat_length; /* use the cache */

      /* Otherwise rechunk_length is called at the end of a chunk for the length
       * of the next one.
       */
      cur = idat->idat_cur;
      count = idat->idat_count;

      assert(idat->idat_index == idat->idat_length &&
         idat->idat_length == cur->lengths[count]);

      /* Return length of the *next* chunk */
      if (++count < cur->count)
         return cur->lengths[count];

      /* End of this list */
      assert(cur != idat->idat_list_tail);
      cur = cur->next;
      assert(cur != NULL && cur->count > 0);
      return cur->lengths[0];
   }

   else /* rechunking */
   {
      /* The chunk size is the lesser of file->idat_max and the number
       * of remaining bytes.
       */
      png_uint_32 have = idat->idat_length - idat->idat_index;

      if (len > have)
      {
         struct IDAT_list *cur = idat->idat_cur;
         unsigned int j = idat->idat_count+1; /* the next IDAT in the list */

         do
         {
            /* Add up the remaining bytes.  This can't overflow because the
             * individual lengths are always <= 0x7fffffff, so when we add two
             * of them overflow is not possible.
             */
            assert(cur != NULL);

            for (;;)
            {
               /* NOTE: IDAT_list::count here, not IDAT_list::length */
               for (; j < cur->count; ++j)
               {
                  have += cur->lengths[j];
                  if (len <= have)
                     return len;
               }

               /* If this was the end return the count of the available bytes */
               if (cur == idat->idat_list_tail)
                  return have;

               cur = cur->next;
               j = 0;
            }
         }
         while (len > have);
      }

      return len;
   }
}

static int
process_IDAT(struct file *file)
   /* Process the IDAT stream, this is the more complex than the preceding
    * cases because the compressed data is spread across multiple IDAT chunks
    * (typically).  Rechunking of the data is not handled here; all this
    * function does is establish whether the zlib header needs to be modified.
    *
    * Initially the function returns false, indicating that the chunk should not
    * be written.  It does this until the last IDAT chunk is passed in, then it
    * checks the zlib data and returns true.
    *
    * It does not return false on a fatal error; it calls stop instead.
    *
    * The caller must have an instantiated (IDAT) control structure and it must
    * have extent over the whole read of the IDAT stream.  For a PNG this means
    * the whole PNG read, for MNG it could have lesser extent.
    */
{
   struct IDAT_list *list;

   assert(file->idat != NULL && file->chunk != NULL);

   /* We need to first check the entire sequence of IDAT chunks to ensure the
    * stream is in sync.  Do this by building a list of all the chunks and
    * recording the length of each because the length may have been fixed up by
    * sync_stream below.
    *
    * At the end of the list of chunks, where the type of the next chunk is not
    * png_IDAT, process the whole stream using the list data to check validity
    * then return control to the start and rewrite everything.
    */
   list = file->idat->idat_list_tail;

   if (list->count == list->length)
   {
      list = IDAT_list_extend(list);

      if (list == NULL)
         stop(file, READ_ERROR_CODE, "out of memory");

      /* Move to the next block */
      list->count = 0;
      file->idat->idat_list_tail = list;
   }

   /* And fill in the next IDAT information buffer. */
   list->lengths[(list->count)++] = file->chunk->chunk_length;

   /* The type of the next chunk was recorded in the file control structure by
    * the caller, if this is png_IDAT return 'skip' to the caller.
    */
   if (file->type == png_IDAT)
      return 0; /* skip this for the moment */

   /* This is the final IDAT chunk, so run the tests to check for the too far
    * back error and possibly optimize the window bits.  This means going back
    * to the start of the first chunk data, which is stored in the original
    * chunk allocation.
    */
   setpos(file->chunk);

   if (zlib_check(file, 0))
   {
      struct IDAT *idat;
      int cmp;

      /* The IDAT stream was successfully uncompressed; see whether it
       * contained the correct number of bytes of image data.
       */
      cmp = uarb_cmp(file->image_bytes, file->image_digits,
         file->chunk->uncompressed_bytes, file->chunk->uncompressed_digits);

      if (cmp < 0)
         type_message(file, png_IDAT, "extra uncompressed data");

      else if (cmp > 0)
         stop(file, LIBPNG_ERROR_CODE, "IDAT: uncompressed data too small");

      /* Return the stream to the start of the first IDAT chunk; the length
       * is set in the write case below but the input chunk variables must be
       * set (once) here:
       */
      setpos(file->chunk);

      idat = file->idat;
      idat->idat_cur = idat->idat_list_head;
      idat->idat_length = idat->idat_cur->lengths[0];
      idat->idat_count = 0; /* Count of chunks read in current list */
      idat->idat_index = 0; /* Index into chunk data */

      /* Update the chunk length to the correct value for the IDAT chunk: */
      file->chunk->chunk_length = rechunk_length(idat);

      /* Change the state to writing IDAT chunks */
      file->state = STATE_IDAT;

      return 1;
   }

   else /* Failure to decompress the IDAT stream; give up. */
      stop(file, ZLIB_ERROR_CODE, "could not uncompress IDAT");
}

/* ZLIB CONTROL STRUCTURE */
struct zlib
{
   /* ANCESTORS */
   struct IDAT *  idat;          /* NOTE: May be NULL */
   struct chunk * chunk;
   struct file *  file;
   struct global *global;

   /* GLOBAL ZLIB INFORMATION: SET BY THE CALLER */
   png_uint_32    rewrite_offset;

   /* GLOBAL ZLIB INFORMATION: SET BY THE ZLIB READ CODE */
   udigit         compressed_bytes[5];
   int            compressed_digits;
   udigit         uncompressed_bytes[5];
   int            uncompressed_digits;
   int            file_bits;             /* window bits from the file */
   int            ok_bits;               /* Set <16 on a successful read */
   int            cksum;                 /* Set on a checksum error */

   /* PROTECTED ZLIB INFORMATION: USED BY THE ZLIB ROUTINES */
   z_stream       z;
   png_uint_32    extra_bytes;   /* Count of extra compressed bytes */
   int            state;
   int            rc;            /* Last return code */
   int            window_bits;   /* 0 if no change */
   png_byte       header[2];
};

static const char *
zlib_flevel(struct zlib *zlib)
{
   switch (zlib->header[1] >> 6)
   {
      case 0:  return "supfast";
      case 1:  return "stdfast";
      case 2:  return "default";
      case 3:  return "maximum";
      default: assert(UNREACHED);
   }

   return "COMPILER BUG";
}

static const char *
zlib_rc(struct zlib *zlib)
   /* Return a string for the zlib return code */
{
   switch (zlib->rc)
   {
      case Z_OK:              return "Z_OK";
      case Z_STREAM_END:      return "Z_STREAM_END";
      case Z_NEED_DICT:       return "Z_NEED_DICT";
      case Z_ERRNO:           return "Z_ERRNO";
      case Z_STREAM_ERROR:    return "Z_STREAM_ERROR";
      case Z_DATA_ERROR:      return "Z_DATA_ERROR";
      case Z_MEM_ERROR:       return "Z_MEM_ERROR";
      case Z_BUF_ERROR:       return "Z_BUF_ERROR";
      case Z_VERSION_ERROR:   return "Z_VERSION_ERROR";
      default:                return "Z_*INVALID_RC*";
   }
}

static void
zlib_message(struct zlib *zlib, int unexpected)
   /* Output a message given a zlib rc */
{
   if (zlib->global->errors)
   {
      const char *reason = zlib->z.msg;

      if (reason == NULL)
         reason = "[no message]";

      fputs(zlib->file->file_name, stderr);
      type_sep(stderr);
      type_name(zlib->chunk->chunk_type, stderr);
      fprintf(stderr, ": %szlib error: %d (%s) (%s)\n",
         unexpected ? "unexpected " : "", zlib->rc, zlib_rc(zlib), reason);
   }
}

static void
zlib_end(struct zlib *zlib)
{
   /* Output the summary line now; this ensures a summary line always gets
    * output regardless of the manner of exit.
    */
   if (!zlib->global->quiet)
   {
      if (zlib->ok_bits < 16) /* stream was read ok */
      {
         const char *reason;

         if (zlib->cksum)
            reason = "CHK"; /* checksum error */

         else if (zlib->ok_bits > zlib->file_bits)
            reason = "TFB"; /* fixing a too-far-back error */

         else if (zlib->ok_bits == zlib->file_bits)
            reason = "OK ";

         else
            reason = "OPT"; /* optimizing window bits */

         /* SUMMARY FORMAT (for a successful zlib inflate):
          *
          * IDAT reason flevel file-bits ok-bits compressed uncompressed file
          */
         type_name(zlib->chunk->chunk_type, stdout);
         printf(" %s %s %d %d ", reason, zlib_flevel(zlib), zlib->file_bits,
            zlib->ok_bits);
         uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);
         putc(' ', stdout);
         uarb_print(zlib->uncompressed_bytes, zlib->uncompressed_digits,
            stdout);
         putc(' ', stdout);
         fputs(zlib->file->file_name, stdout);
         putc('\n', stdout);
      }

      else
      {
         /* This is a zlib read error; the chunk will be skipped.  For an IDAT
          * stream this will also cause a fatal read error (via stop()).
          *
          * SUMMARY FORMAT:
          *
          * IDAT SKP flevel file-bits z-rc compressed message file
          *
          * z-rc is the zlib failure code; message is the error message with
          * spaces replaced by '-'.  The compressed byte count indicates where
          * in the zlib stream the error occurred.
          */
         type_name(zlib->chunk->chunk_type, stdout);
         printf(" SKP %s %d %s ", zlib_flevel(zlib), zlib->file_bits,
            zlib_rc(zlib));
         uarb_print(zlib->compressed_bytes, zlib->compressed_digits, stdout);
         putc(' ', stdout);
         emit_string(zlib->z.msg ? zlib->z.msg : "[no_message]", stdout);
         putc(' ', stdout);
         fputs(zlib->file->file_name, stdout);
         putc('\n', stdout);
      }
   }

   if (zlib->state >= 0)
   {
      zlib->rc = inflateEnd(&zlib->z);

      if (zlib->rc != Z_OK)
         zlib_message(zlib, 1/*unexpected*/);
   }

   CLEAR(*zlib);
}

static int
zlib_reset(struct zlib *zlib, int window_bits)
   /* Reinitializes a zlib with a different window_bits */
{
   assert(zlib->state >= 0); /* initialized by zlib_init */

   zlib->z.next_in = Z_NULL;
   zlib->z.avail_in = 0;
   zlib->z.next_out = Z_NULL;
   zlib->z.avail_out = 0;

   zlib->window_bits = window_bits;
   zlib->compressed_digits = 0;
   zlib->uncompressed_digits = 0;

   zlib->state = 0; /* initialized, once */
   zlib->rc = inflateReset2(&zlib->z, 0);
   if (zlib->rc != Z_OK)
   {
      zlib_message(zlib, 1/*unexpected*/);
      return 0;
   }

   return 1;
}

static int
zlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk,
   int window_bits, png_uint_32 offset)
   /* Initialize a zlib_control; the result is true/false */
{
   CLEAR(*zlib);

   zlib->idat = idat;
   zlib->chunk = chunk;
   zlib->file = chunk->file;
   zlib->global = chunk->global;
   zlib->rewrite_offset = offset; /* never changed for this zlib */

   /* *_out does not need to be set: */
   zlib->z.next_in = Z_NULL;
   zlib->z.avail_in = 0;
   zlib->z.zalloc = Z_NULL;
   zlib->z.zfree = Z_NULL;
   zlib->z.opaque = Z_NULL;

   zlib->state = -1;
   zlib->window_bits = window_bits;

   zlib->compressed_digits = 0;
   zlib->uncompressed_digits = 0;

   /* These values are sticky across reset (in addition to the stuff in the
    * first block, which is actually constant.)
    */
   zlib->file_bits = 24;
   zlib->ok_bits = 16; /* unset */
   zlib->cksum = 0; /* set when a checksum error is detected */

   /* '0' means use the header; inflateInit2 should always succeed because it
    * does nothing apart from allocating the internal zstate.
    */
   zlib->rc = inflateInit2(&zlib->z, 0);
   if (zlib->rc != Z_OK)
   {
      zlib_message(zlib, 1/*unexpected*/);
      return 0;
   }

   else
   {
      zlib->state = 0; /* initialized */
      return 1;
   }
}

static int
max_window_bits(uarbc size, int ndigits)
   /* Return the zlib stream window bits required for data of the given size. */
{
   png_uint_16 cb;

   if (ndigits > 1)
      return 15;

   cb = size[0];

   if (cb > 16384) return 15;
   if (cb >  8192) return 14;
   if (cb >  4096) return 13;
   if (cb >  2048) return 12;
   if (cb >  1024) return 11;
   if (cb >   512) return 10;
   if (cb >   256) return  9;
   return 8;
}

static int
zlib_advance(struct zlib *zlib, png_uint_32 nbytes)
   /* Read nbytes compressed bytes; the stream will be initialized if required.
    * Bytes are always being reread and errors are fatal.  The return code is as
    * follows:
    *
    *    -1: saw the "too far back" error
    *     0: ok, keep going
    *     1: saw Z_STREAM_END (zlib->extra_bytes indicates too much data)
    *     2: a zlib error that cannot be corrected (error message already
    *        output if required.)
    */
#  define ZLIB_TOO_FAR_BACK (-1)
#  define ZLIB_OK           0
#  define ZLIB_STREAM_END   1
#  define ZLIB_FATAL        2
{
   int state = zlib->state;
   int endrc = ZLIB_OK;
   png_uint_32 in_bytes = 0;
   struct file *file = zlib->file;

   assert(state >= 0);

   while (in_bytes < nbytes && endrc == ZLIB_OK)
   {
      png_uint_32 out_bytes;
      int flush;
      png_byte bIn = reread_byte(file);
      png_byte bOut;

      switch (state)
      {
         case 0: /* first header byte */
            {
               int file_bits = 8+(bIn >> 4);
               int new_bits = zlib->window_bits;

               zlib->file_bits = file_bits;

               /* Check against the existing value - it may not need to be
                * changed.  Note that a bogus file_bits is allowed through once,
                * to see if it works, but the window_bits value is set to 15,
                * the maximum.
                */
               if (new_bits == 0) /* no change */
                  zlib->window_bits = ((file_bits > 15) ? 15 : file_bits);

               else if (new_bits != file_bits) /* rewrite required */
                  bIn = (png_byte)((bIn & 0xf) + ((new_bits-8) << 4));
            }

            zlib->header[0] = bIn;
            zlib->state = state = 1;
            break;

         case 1: /* second header byte */
            {
               int b2 = bIn & 0xe0; /* top 3 bits */

               /* The checksum calculation, on the first 11 bits: */
               b2 += 0x1f - ((zlib->header[0] << 8) + b2) % 0x1f;

               /* Update the checksum byte if required: */
               if (bIn != b2)
               {
                  /* If the first byte wasn't changed this indicates an error in
                   * the checksum calculation; signal this by setting 'cksum'.
                   */
                  if (zlib->file_bits == zlib->window_bits)
                     zlib->cksum = 1;

                  bIn = (png_byte)b2;
               }
            }

            zlib->header[1] = bIn;
            zlib->state = state = 2;
            break;

         default: /* After the header bytes */
            break;
      }

      /* For some streams, perhaps only those compressed with 'superfast
       * compression' (which results in a lot of copying) Z_BUF_ERROR can happen
       * immediately after all output has been flushed on the next input byte.
       * This is handled below when Z_BUF_ERROR is detected by adding an output
       * byte.
       */
      zlib->z.next_in = &bIn;
      zlib->z.avail_in = 1;
      zlib->z.next_out = &bOut;
      zlib->z.avail_out = 0;     /* Initially */

      /* Initially use Z_NO_FLUSH in an attempt to persuade zlib to look at this
       * byte without confusing what is going on with output.
       */
      flush = Z_NO_FLUSH;
      out_bytes = 0;

      /* NOTE: expression 3 is only evaluted on 'continue', because of the
       * 'break' at the end of this loop below.
       */
      for (;endrc == ZLIB_OK;
         flush = Z_SYNC_FLUSH,
         zlib->z.next_out = &bOut,
         zlib->z.avail_out = 1,
         ++out_bytes)
      {
         zlib->rc = inflate(&zlib->z, flush);
         out_bytes -= zlib->z.avail_out;

         switch (zlib->rc)
         {
            case Z_BUF_ERROR:
               if (zlib->z.avail_out == 0)
                  continue; /* Try another output byte. */

               if (zlib->z.avail_in == 0)
                  break; /* Try another input byte */

               /* Both avail_out and avail_in are 1 yet zlib returned a code
                * indicating no progress was possible.  This is unexpected.
                */
               zlib_message(zlib, 1/*unexpected*/);
               endrc = ZLIB_FATAL; /* stop processing */
               break;

            case Z_OK:
               /* Zlib is supposed to have made progress: */
               assert(zlib->z.avail_out == 0 || zlib->z.avail_in == 0);
               continue;

            case Z_STREAM_END:
               /* This is the successful end. */
               zlib->state = 3; /* end of stream */
               endrc = ZLIB_STREAM_END;
               break;

            case Z_NEED_DICT:
               zlib_message(zlib, 0/*stream error*/);
               endrc = ZLIB_FATAL;
               break;

            case Z_DATA_ERROR:
               /* The too far back error can be corrected, others cannot: */
               if (zlib->z.msg != NULL &&
                  strcmp(zlib->z.msg, "invalid distance too far back") == 0)
               {
                  endrc = ZLIB_TOO_FAR_BACK;
                  break;
               }
               /* FALL THROUGH */

            default:
               zlib_message(zlib, 0/*stream error*/);
               endrc = ZLIB_FATAL;
               break;
         } /* switch (inflate rc) */

         /* Control gets here when further output is not possible; endrc may
          * still be ZLIB_OK if more input is required.
          */
         break;
      } /* for (output bytes) */

      /* Keep a running count of output byte produced: */
      zlib->uncompressed_digits = uarb_add32(zlib->uncompressed_bytes,
         zlib->uncompressed_digits, out_bytes);

      /* Keep going, the loop will terminate when endrc is no longer set to
       * ZLIB_OK or all the input bytes have been consumed; meanwhile keep
       * adding input bytes.
       */
      assert(zlib->z.avail_in == 0 || endrc != ZLIB_OK);

      in_bytes += 1 - zlib->z.avail_in;
   } /* while (input bytes) */

   assert(in_bytes == nbytes || endrc != ZLIB_OK);

   /* Update the running total of input bytes consumed */
   zlib->compressed_digits = uarb_add32(zlib->compressed_bytes,
      zlib->compressed_digits, in_bytes - zlib->z.avail_in);

   /* At the end of the stream update the chunk with the accumulated
    * information if it is an improvement:
    */
   if (endrc == ZLIB_STREAM_END && zlib->window_bits < zlib->ok_bits)
   {
      struct chunk *chunk = zlib->chunk;

      chunk->uncompressed_digits = uarb_copy(chunk->uncompressed_bytes,
         zlib->uncompressed_bytes, zlib->uncompressed_digits);
      chunk->compressed_digits = uarb_copy(chunk->compressed_bytes,
         zlib->compressed_bytes, zlib->compressed_digits);
      chunk->rewrite_buffer[0] = zlib->header[0];
      chunk->rewrite_buffer[1] = zlib->header[1];

      if (zlib->window_bits != zlib->file_bits || zlib->cksum)
      {
         /* A rewrite is required */
         chunk->rewrite_offset = zlib->rewrite_offset;
         chunk->rewrite_length = 2;
      }

      else
      {
         chunk->rewrite_offset = 0;
         chunk->rewrite_length = 0;
      }

      if (in_bytes < nbytes)
         chunk_message(chunk, "extra compressed data");

      zlib->extra_bytes = nbytes - in_bytes;
      zlib->ok_bits = zlib->window_bits;
   }

   return endrc;
}

static int
zlib_run(struct zlib *zlib)
   /* Like zlib_advance but also handles a stream of IDAT chunks. */
{
   /* The 'extra_bytes' field is set by zlib_advance if there is extra
    * compressed data in the chunk it handles (if it sees Z_STREAM_END before
    * all the input data has been used.)  This function uses the value to update
    * the correct chunk length, so the problem should only ever be detected once
    * for each chunk.  zlib_advance outputs the error message, though see the
    * IDAT specific check below.
    */
   zlib->extra_bytes = 0;

   if (zlib->idat != NULL)
   {
      struct IDAT_list *list = zlib->idat->idat_list_head;
      struct IDAT_list *last = zlib->idat->idat_list_tail;
      int        skip = 0;

      /* 'rewrite_offset' is the offset of the LZ data within the chunk, for
       * IDAT it should be 0:
       */
      assert(zlib->rewrite_offset == 0);

      /* Process each IDAT_list in turn; the caller has left the stream
       * positioned at the start of the first IDAT chunk data.
       */
      for (;;)
      {
         const unsigned int count = list->count;
         unsigned int i;

         for (i = 0; i<count; ++i)
         {
            int rc;

            if (skip > 0) /* Skip CRC and next IDAT header */
               skip_12(zlib->file);

            skip = 12; /* for the next time */

            rc = zlib_advance(zlib, list->lengths[i]);

            switch (rc)
            {
               case ZLIB_OK: /* keep going */
                  break;

               case ZLIB_STREAM_END: /* stop */
                  /* There may be extra chunks; if there are and one of them is
                   * not zero length output the 'extra data' message.  Only do
                   * this check if errors are being output.
                   */
                  if (zlib->global->errors && zlib->extra_bytes == 0)
                  {
                     struct IDAT_list *check = list;
                     int j = i+1, jcount = count;

                     for (;;)
                     {
                        for (; j<jcount; ++j)
                           if (check->lengths[j] > 0)
                           {
                              chunk_message(zlib->chunk,
                                 "extra compressed data");
                              goto end_check;
                           }

                        if (check == last)
                           break;

                        check = check->next;
                        jcount = check->count;
                        j = 0;
                     }
                  }

               end_check:
                  /* Terminate the list at the current position, reducing the
                   * length of the last IDAT too if required.
                   */
                  list->lengths[i] -= zlib->extra_bytes;
                  list->count = i+1;
                  zlib->idat->idat_list_tail = list;
                  /* FALL THROUGH */

               default:
                  return rc;
            }
         }

         /* At the end of the compressed data and Z_STREAM_END was not seen. */
         if (list == last)
            return ZLIB_OK;

         list = list->next;
      }
   }

   else
   {
      struct chunk *chunk = zlib->chunk;
      int rc;

      assert(zlib->rewrite_offset < chunk->chunk_length);

      rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset);

      /* The extra bytes in the chunk are handled now by adjusting the chunk
       * length to exclude them; the zlib data is always stored at the end of
       * the PNG chunk (although clearly this is not necessary.)  zlib_advance
       * has already output a warning message.
       */
      chunk->chunk_length -= zlib->extra_bytes;
      return rc;
   }
}

static int /* global function; not a member function */
zlib_check(struct file *file, png_uint_32 offset)
   /* Check the stream of zlib compressed data in either idat (if given) or (if
    * not) chunk.  In fact it is zlib_run that handles the difference in reading
    * a single chunk and a list of IDAT chunks.
    *
    * In either case the input file must be positioned at the first byte of zlib
    * compressed data (the first header byte).
    *
    * The return value is true on success, including the case where the zlib
    * header may need to be rewritten, and false on an unrecoverable error.
    *
    * In the case of IDAT chunks 'offset' should be 0.
    */
{
   fpos_t start_pos;
   struct zlib zlib;

   /* Record the start of the LZ data to allow a re-read. */
   file_getpos(file, &start_pos);

   /* First test the existing (file) window bits: */
   if (zlib_init(&zlib, file->idat, file->chunk, 0/*window bits*/, offset))
   {
      int min_bits, max_bits, rc;

      /* The first run using the existing window bits. */
      rc = zlib_run(&zlib);

      switch (rc)
      {
         case ZLIB_TOO_FAR_BACK:
            /* too far back error */
            file->status_code |= TOO_FAR_BACK;
            min_bits = zlib.window_bits + 1;
            max_bits = 15;
            break;

         case ZLIB_STREAM_END:
            if (!zlib.global->optimize_zlib &&
               zlib.window_bits == zlib.file_bits && !zlib.cksum)
            {
               /* The trivial case where the stream is ok and optimization was
                * not requested.
                */
               zlib_end(&zlib);
               return 1;
            }

            max_bits = max_window_bits(zlib.uncompressed_bytes,
               zlib.uncompressed_digits);
            if (zlib.ok_bits < max_bits)
               max_bits = zlib.ok_bits;
            min_bits = 8;

            /* cksum is set if there is an error in the zlib header checksum
             * calculation in the original file (and this may be the only reason
             * a rewrite is required).  We can't rely on the file window bits in
             * this case, so do the optimization anyway.
             */
            if (zlib.cksum)
               chunk_message(zlib.chunk, "zlib checkum");
            break;


         case ZLIB_OK:
            /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */
            zlib.z.msg = PNGZ_MSG_CAST("[truncated]");
            zlib_message(&zlib, 0/*expected*/);
            /* FALL THROUGH */

         default:
            /* Unrecoverable error; skip the chunk; a zlib_message has already
             * been output.
             */
            zlib_end(&zlib);
            return 0;
      }

      /* Optimize window bits or fix a too-far-back error.  min_bits and
       * max_bits have been set appropriately, ok_bits records the bit value
       * known to work.
       */
      while (min_bits < max_bits || max_bits < zlib.ok_bits/*if 16*/)
      {
         int test_bits = (min_bits + max_bits) >> 1;

         if (zlib_reset(&zlib, test_bits))
         {
            file_setpos(file, &start_pos);
            rc = zlib_run(&zlib);

            switch (rc)
            {
               case ZLIB_TOO_FAR_BACK:
                  min_bits = test_bits+1;
                  if (min_bits > max_bits)
                  {
                     /* This happens when the stream really is damaged and it
                      * contains a distance code that addresses bytes before
                      * the start of the uncompressed data.
                      */
                     assert(test_bits == 15);

                     /* Output the error that wasn't output before: */
                     if (zlib.z.msg == NULL)
                        zlib.z.msg = PNGZ_MSG_CAST(
                           "invalid distance too far back");
                     zlib_message(&zlib, 0/*stream error*/);
                     zlib_end(&zlib);
                     return 0;
                  }
                  break;

               case ZLIB_STREAM_END: /* success */
                  max_bits = test_bits;
                  break;

               default:
                  /* A fatal error; this happens if a too-far-back error was
                   * hiding a more serious error, zlib_advance has already
                   * output a zlib_message.
                   */
                  zlib_end(&zlib);
                  return 0;
            }
         }

         else /* inflateReset2 failed */
         {
            zlib_end(&zlib);
            return 0;
         }
      }

      /* The loop guarantees this */
      assert(zlib.ok_bits == max_bits);
      zlib_end(&zlib);
      return 1;
   }

   else /* zlib initialization failed - skip the chunk */
   {
      zlib_end(&zlib);
      return 0;
   }
}

/***************************** LIBPNG CALLBACKS *******************************/
/* The strategy here is to run a regular libpng PNG file read but examine the
 * input data (from the file) before passing it to libpng so as to be aware of
 * the state we expect libpng to be in.  Warning and error callbacks are also
 * intercepted so that they can be quieted and interpreted.  Interpretation
 * depends on a somewhat risky string match for known error messages; let us
 * hope that this can be fixed in the next version of libpng.
 *
 * The control structure is pointed to by the libpng error pointer.  It contains
 * that set of structures which must persist across multiple read callbacks,
 * which is pretty much everything except the 'zlib' control structure.
 *
 * The file structure is instantiated in the caller of the per-file routine, but
 * the per-file routine contains the chunk and IDAT control structures.
 */
/* The three routines read_chunk, process_chunk and sync_stream can only be
 * called via a call to read_chunk and only exit at a return from process_chunk.
 * These routines could have been written as one confusing large routine,
 * instead this code relies on the compiler to do tail call elimination.  The
 * possible calls are as follows:
 *
 * read_chunk
 *    -> sync_stream
 *       -> process_chunk
 *    -> process_chunk
 *       -> read_chunk
 *       returns
 */
static void read_chunk(struct file *file);
static void
process_chunk(struct file *file, png_uint_32 file_crc, png_uint_32 next_length,
   png_uint_32 next_type)
   /* Called when the chunk data has been read, next_length and next_type
    * will be set for the next chunk (or 0 if this is IEND).
    *
    * When this routine returns, chunk_length and chunk_type will be set for the
    * next chunk to write because if a chunk is skipped this return calls back
    * to read_chunk.
    */
{
   const png_uint_32 type = file->type;

   if (file->global->verbose > 1)
   {
      fputs("  ", stderr);
      type_name(file->type, stderr);
      fprintf(stderr, " %lu 0x%.8x 0x%.8x\n", (unsigned long)file->length,
         file->crc ^ 0xffffffff, file_crc);
   }

   /* The basic structure seems correct but the CRC may not match, in this
    * case assume that it is simply a bad CRC, either wrongly calculated or
    * because of damaged stream data.
    */
   if ((file->crc ^ 0xffffffff) != file_crc)
   {
      /* The behavior is set by the 'skip' setting; if it is anything other
       * than SKIP_BAD_CRC ignore the bad CRC and return the chunk, with a
       * corrected CRC and possibly processed, to libpng.  Otherwise skip the
       * chunk, which will result in a fatal error if the chunk is critical.
       */
      file->status_code |= CRC_ERROR;

      /* Ignore the bad CRC  */
      if (file->global->skip != SKIP_BAD_CRC)
         type_message(file, type, "bad CRC");

      /* This will cause an IEND with a bad CRC to stop */
      else if (CRITICAL(type))
         stop(file, READ_ERROR_CODE, "bad CRC in critical chunk");

      else
      {
         type_message(file, type, "skipped: bad CRC");

         /* NOTE: this cannot be reached for IEND because it is critical. */
         goto skip_chunk;
      }
   }

   /* Check for other 'skip' cases and handle these; these only apply to
    * ancillary chunks (and not tRNS, which should probably have been a critical
    * chunk.)
    */
   if (skip_chunk_type(file->global, type))
      goto skip_chunk;

   /* The chunk may still be skipped if problems are detected in the LZ data,
    * however the LZ data check requires a chunk.  Handle this by instantiating
    * a chunk unless an IDAT is already instantiated (IDAT control structures
    * instantiate their own chunk.)
    */
   if (type != png_IDAT)
      file->alloc(file, 0/*chunk*/);

   else if (file->idat == NULL)
      file->alloc(file, 1/*IDAT*/);

   else
   {
      /* The chunk length must be updated for process_IDAT */
      assert(file->chunk != NULL);
      assert(file->chunk->chunk_type == png_IDAT);
      file->chunk->chunk_length = file->length;
   }

   /* Record the 'next' information too, now that the original values for
    * this chunk have been copied.  Notice that the IDAT chunks only make a
    * copy of the position of the first chunk, this is fine - process_IDAT does
    * not need the position of this chunk.
    */
   file->length = next_length;
   file->type = next_type;
   getpos(file);

   /* Do per-type processing, note that if this code does not return from the
    * function the chunk will be skipped.  The rewrite is cancelled here so that
    * it can be set in the per-chunk processing.
    */
   file->chunk->rewrite_length = 0;
   file->chunk->rewrite_offset = 0;
   switch (type)
   {
      default:
         return;

      case png_IHDR:
         /* Read this now and update the control structure with the information
          * it contains.  The header is validated completely to ensure this is a
          * PNG.
          */
         {
            struct chunk *chunk = file->chunk;

            if (chunk->chunk_length != 13)
               stop_invalid(file, "IHDR length");

            /* Read all the IHDR information and validate it. */
            setpos(chunk);
            file->width = reread_4(file);
            file->height = reread_4(file);
            file->bit_depth = reread_byte(file);
            file->color_type = reread_byte(file);
            file->compression_method = reread_byte(file);
            file->filter_method = reread_byte(file);
            file->interlace_method = reread_byte(file);

            /* This validates all the fields, and calls stop_invalid if
             * there is a problem.
             */
            calc_image_size(file);
         }
         return;

         /* Ancillary chunks that require further processing: */
      case png_zTXt: case png_iCCP:
         if (process_zTXt_iCCP(file))
            return;
         chunk_end(&file->chunk);
         file_setpos(file, &file->data_pos);
         break;

      case png_iTXt:
         if (process_iTXt(file))
            return;
         chunk_end(&file->chunk);
         file_setpos(file, &file->data_pos);
         break;

      case png_IDAT:
         if (process_IDAT(file))
            return;
         /* First pass: */
         assert(next_type == png_IDAT);
         break;
   }

   /* Control reaches this point if the chunk must be skipped.  For chunks other
    * than IDAT this means that the zlib compressed data is fatally damanged and
    * the chunk will not be passed to libpng.  For IDAT it means that the end of
    * the IDAT stream has not yet been reached and we must handle the next
    * (IDAT) chunk.  If the LZ data in an IDAT stream cannot be read 'stop' must
    * be used to halt parsing of the PNG.
    */
   read_chunk(file);
   return;

   /* This is the generic code to skip the current chunk; simply jump to the
    * next one.
    */
skip_chunk:
   file->length = next_length;
   file->type = next_type;
   getpos(file);
   read_chunk(file);
}

static png_uint_32
get32(png_bytep buffer, int offset)
   /* Read a 32-bit value from an 8-byte circular buffer (used only below).
    */
{
   return
      (buffer[ offset    & 7] << 24) +
      (buffer[(offset+1) & 7] << 16) +
      (buffer[(offset+2) & 7] <<  8) +
      (buffer[(offset+3) & 7]      );
}

static void
sync_stream(struct file *file)
   /* The stream seems to be messed up, attempt to resync from the current chunk
    * header.  Executes stop on a fatal error, otherwise calls process_chunk.
    */
{
   png_uint_32 file_crc;

   file->status_code |= STREAM_ERROR;

   if (file->global->verbose)
   {
      fputs(" SYNC ", stderr);
      type_name(file->type, stderr);
      putc('\n', stderr);
   }

   /* Return to the start of the chunk data */
   file_setpos(file, &file->data_pos);
   file->read_count = 8;

   if (read_4(file, &file_crc) == 4) /* else completely truncated */
   {
      /* Ignore the recorded chunk length, proceed through the data looking for
       * a leading sequence of bytes that match the CRC in the following four
       * bytes.  Each time a match is found check the next 8 bytes for a valid
       * length, chunk-type pair.
       */
      png_uint_32 length;
      png_uint_32 type = file->type;
      png_uint_32 crc = crc_init_4(type);
      png_byte buffer[8];
      unsigned int nread = 0, nused = 0;

      for (length=0; length <= 0x7fffffff; ++length)
      {
         int ch;

         if ((crc ^ 0xffffffff) == file_crc)
         {
            /* A match on the CRC; for IEND this is sufficient, but for anything
             * else expect a following chunk header.
             */
            if (type == png_IEND)
            {
               file->length = length;
               process_chunk(file, file_crc, 0, 0);
               return;
            }

            else
            {
               /* Need 8 bytes */
               while (nread < 8+nused)
               {
                  ch = read_byte(file);
                  if (ch == EOF)
                     goto truncated;
                  buffer[(nread++) & 7] = (png_byte)ch;
               }

               /* Prevent overflow */
               nread -= nused & ~7;
               nused -= nused & ~7; /* or, nused &= 7 ;-) */

               /* Examine the 8 bytes for a valid chunk header. */
               {
                  png_uint_32 next_length = get32(buffer, nused);

                  if (next_length < 0x7fffffff)
                  {
                     png_uint_32 next_type = get32(buffer, nused+4);

                     if (chunk_type_valid(next_type))
                     {
                        file->read_count -= 8;
                        process_chunk(file, file_crc, next_length, next_type);
                        return;
                     }
                  }

                  /* Not valid, keep going. */
               }
            }
         }

         /* This catches up with the circular buffer which gets filled above
          * while checking a chunk header.  This code is slightly tricky - if
          * the chunk_type is IEND the buffer will never be used, if it is not
          * the code will always read ahead exactly 8 bytes and pass this on to
          * process_chunk.  So the invariant that IEND leaves the file position
          * after the IEND CRC and other chunk leave it after the *next* chunk
          * header is not broken.
          */
         if (nread <= nused)
         {
            ch = read_byte(file);

            if (ch == EOF)
               goto truncated;
         }

         else
            ch = buffer[(++nused) & 7];

         crc = crc_one_byte(crc, file_crc >> 24);
         file_crc = (file_crc << 8) + ch;
      }

      /* Control gets to here if when 0x7fffffff bytes (plus 8) have been read,
       * ok, treat this as a damaged stream too:
       */
   }

truncated:
   stop(file, READ_ERROR_CODE, "damaged PNG stream");
}

static void
read_chunk(struct file *file)
   /* On entry file::data_pos must be set to the position of the first byte
    * of the chunk data *and* the input file must be at this position.  This
    * routine (via process_chunk) instantiates a chunk or IDAT control structure
    * based on file::length and file::type and also resets these fields and
    * file::data_pos for the chunk after this one.  For an IDAT chunk the whole
    * stream of IDATs will be read, until something other than an IDAT is
    * encountered, and the file fields will be set for the chunk after the end
    * of the stream of IDATs.
    *
    * For IEND the file::type field will be set to 0, and nothing beyond the end
    * of the IEND chunk will have been read.
    */
{
   png_uint_32 length = file->length;
   png_uint_32 type = file->type;

   /* After IEND file::type is set to 0, if libpng attempts to read
    * more data at this point this is a bug in libpng.
    */
   if (type == 0)
      stop(file, UNEXPECTED_ERROR_CODE, "read beyond IEND");

   if (file->global->verbose > 2)
   {
      fputs("   ", stderr);
      type_name(type, stderr);
      fprintf(stderr, " %lu\n", (unsigned long)length);
   }

   /* Start the read_crc calculation with the chunk type, then read to the end
    * of the chunk data (without processing it in any way) to check that it is
    * all there and calculate the CRC.
    */
   file->crc = crc_init_4(type);
   if (crc_read_many(file, length)) /* else it was truncated */
   {
      png_uint_32 file_crc; /* CRC read from file */
      unsigned int nread = read_4(file, &file_crc);

      if (nread == 4)
      {
         if (type != png_IEND) /* do not read beyond IEND */
         {
            png_uint_32 next_length;

            nread += read_4(file, &next_length);
            if (nread == 8 && next_length <= 0x7fffffff)
            {
               png_uint_32 next_type;

               nread += read_4(file, &next_type);

               if (nread == 12 && chunk_type_valid(next_type))
               {
                  /* Adjust the read count back to the correct value for this
                   * chunk.
                   */
                  file->read_count -= 8;
                  process_chunk(file, file_crc, next_length, next_type);
                  return;
               }
            }
         }

         else /* IEND */
         {
            process_chunk(file, file_crc, 0, 0);
            return;
         }
      }
   }

   /* Control gets to here if the the stream seems invalid or damaged in some
    * way.  Either there was a problem reading all the expected data (this
    * chunk's data, its CRC and the length and type of the next chunk) or the
    * next chunk length/type are invalid.  Notice that the cases that end up
    * here all correspond to cases that would otherwise terminate the read of
    * the PNG file.
    */
   sync_stream(file);
}

/* This returns a file* from a png_struct in an implementation specific way. */
static struct file *get_control(png_const_structrp png_ptr);

static void PNGCBAPI
error_handler(png_structp png_ptr, png_const_charp message)
{
   stop(get_control(png_ptr),  LIBPNG_ERROR_CODE, message);
}

static void PNGCBAPI
warning_handler(png_structp png_ptr, png_const_charp message)
{
   struct file *file = get_control(png_ptr);

   if (file->global->warnings)
      emit_error(file, LIBPNG_WARNING_CODE, message);
}

/* Read callback - this is where the work gets done to check the stream before
 * passing it to libpng
 */
static void PNGCBAPI
read_callback(png_structp png_ptr, png_bytep buffer, size_t count)
   /* Return 'count' bytes to libpng in 'buffer' */
{
   struct file *file = get_control(png_ptr);
   png_uint_32 type, length; /* For the chunk be *WRITTEN* */
   struct chunk *chunk;

   /* libpng should always ask for at least one byte */
   if (count == 0)
      stop(file, UNEXPECTED_ERROR_CODE, "read callback for 0 bytes");

   /* The callback always reads ahead by 8 bytes - the signature or chunk header
    * - these bytes are stored in chunk_length and chunk_type.  This block is
    * executed once for the signature and once for the first chunk right at the
    * start.
    */
   if (file->read_count < 8)
   {
      assert(file->read_count == 0);
      assert((file->status_code & TRUNCATED) == 0);

      (void)read_4(file, &file->length);

      if (file->read_count == 4)
         (void)read_4(file, &file->type);

      if (file->read_count < 8)
      {
         assert((file->status_code & TRUNCATED) != 0);
         stop(file, READ_ERROR_CODE, "not a PNG (too short)");
      }

      if (file->state == STATE_SIGNATURE)
      {
         if (file->length != sig1 || file->type != sig2)
            stop(file, LIBPNG_ERROR_CODE, "not a PNG (signature)");

         /* Else write it (this is the initialization of write_count, prior to
          * this it contains CLEAR garbage.)
          */
         file->write_count = 0;
      }

      else
      {
         assert(file->state == STATE_CHUNKS);

         /* The first chunk must be a well formed IHDR (this could be relaxed to
          * use the checks in process_chunk, but that seems unnecessary.)
          */
         if (file->length != 13 || file->type != png_IHDR)
            stop(file, LIBPNG_ERROR_CODE, "not a PNG (IHDR)");

         /* The position of the data must be stored too */
         getpos(file);
      }
   }

   /* Retrieve previous state (because the read callbacks are made pretty much
    * byte-by-byte in the sequential reader prior to 1.7).
    */
   chunk = file->chunk;

   if (chunk != NULL)
   {
      length = chunk->chunk_length;
      type = chunk->chunk_type;
   }

   else
   {
      /* This is the signature case; for IDAT and other chunks these values will
       * be overwritten when read_chunk is called below.
       */
      length = file->length;
      type = file->type;
   }

   do
   {
      png_uint_32 b;

      /* Complete the read of a chunk; as a side effect this also instantiates
       * a chunk control structure and sets the file length/type/data_pos fields
       * for the *NEXT* chunk header.
       *
       * NOTE: at an IDAT any following IDAT chunks will also be read and the
       * next_ fields will refer to the chunk after the last IDAT.
       *
       * NOTE: read_chunk only returns when it has read a chunk that must now be
       * written.
       */
      if (file->state != STATE_SIGNATURE && chunk == NULL)
      {
         assert(file->read_count == 8);
         assert(file->idat == NULL);
         read_chunk(file);
         chunk = file->chunk;
         assert(chunk != NULL);

         /* Do the initialization that was not done before. */
         length = chunk->chunk_length;
         type = chunk->chunk_type;

         /* And start writing the new chunk. */
         file->write_count = 0;
      }

      /* The chunk_ fields describe a chunk that must be written, or hold the
       * signature.  Write the header first.  In the signature case this
       * rewrites the signature.
       */
      switch (file->write_count)
      {
         case 0: b = length >> 24; break;
         case 1: b = length >> 16; break;
         case 2: b = length >>  8; break;
         case 3: b = length      ; break;

         case 4: b = type >> 24; break;
         case 5: b = type >> 16; break;
         case 6: b = type >>  8; break;
         case 7: b = type      ; break;

         case 8:
            /* The header has been written.  If this is really the signature
             * that's all that is required and we can go to normal chunk
             * processing.
             */
            if (file->state == STATE_SIGNATURE)
            {
               /* The signature has been written, the tail call to read_callback
                * below (it's just a goto to the start with a decent compiler)
                * will read the IHDR header ahead and validate it.
                */
               assert(length == sig1 && type == sig2);
               file->read_count = 0; /* Forces a header read */
               file->state = STATE_CHUNKS; /* IHDR: checked above */
               read_callback(png_ptr, buffer, count);
               return;
            }

            else
            {
               assert(chunk != NULL);

               /* Set up for write, notice that repositioning the input stream
                * is only necessary if something is to be read from it.  Also
                * notice that for the IDAT stream this must only happen once -
                * on the first IDAT - to get back to the start of the list and
                * this is done inside process_IDAT:
                */
               chunk->write_crc = crc_init_4(type);
               if (file->state != STATE_IDAT && length > 0)
                  setpos(chunk);
            }
            /* FALL THROUGH */

         default:
            assert(chunk != NULL);

            /* NOTE: the arithmetic below overflows and gives a large positive
             * png_uint_32 value until the whole chunk data has been written.
             */
            switch (file->write_count - length)
            {
               /* Write the chunk data, normally this just comes from
                * the file.  The only exception is for that part of a
                * chunk which is zlib data and which must be rewritten,
                * and IDAT chunks which can be completely
                * reconstructed.
                */
               default:
                  if (file->state == STATE_IDAT)
                  {
                     struct IDAT *idat = file->idat;

                     assert(idat != NULL);

                     /* Read an IDAT byte from the input stream of IDAT chunks.
                      * Because the IDAT stream can be re-chunked this stream is
                      * held in the struct IDAT members.  The chunk members, in
                      * particular chunk_length (and therefore the length local)
                      * refer to the output chunk.
                      */
                     while (idat->idat_index >= idat->idat_length)
                     {
                        /* Advance one chunk */
                        struct IDAT_list *cur = idat->idat_cur;

                        assert(idat->idat_index == idat->idat_length);
                        assert(cur != NULL && cur->count > 0);

                        /* NOTE: IDAT_list::count here, not IDAT_list::length */
                        if (++(idat->idat_count) >= cur->count)
                        {
                           assert(idat->idat_count == cur->count);

                           /* Move on to the next IDAT_list: */
                           cur = cur->next;

                           /* This is an internal error - read beyond the end of
                            * the pre-calculated stream.
                            */
                           if (cur == NULL || cur->count == 0)
                              stop(file, UNEXPECTED_ERROR_CODE,
                                 "read beyond end of IDAT");

                           idat->idat_count = 0;
                           idat->idat_cur = cur;
                        }

                        idat->idat_index = 0;
                        /* Zero length IDAT chunks are permitted, so the length
                         * here may be 0.
                         */
                        idat->idat_length = cur->lengths[idat->idat_count];

                        /* And skip 12 bytes to the next chunk data */
                        skip_12(file);
                     }

                     /* The index is always that of the next byte, the rest of
                      * the information is always the current IDAT chunk and the
                      * current list.
                      */
                     ++(idat->idat_index);
                  }

                  /* Read the byte from the stream. */
                  b = reread_byte(file);

                  /* If the byte must be rewritten handle that here */
                  if (chunk->rewrite_length > 0)
                  {
                     if (chunk->rewrite_offset > 0)
                        --(chunk->rewrite_offset);

                     else
                     {
                        b = chunk->rewrite_buffer[0];
                        memmove(chunk->rewrite_buffer, chunk->rewrite_buffer+1,
                           (sizeof chunk->rewrite_buffer)-
                              (sizeof chunk->rewrite_buffer[0]));

                        --(chunk->rewrite_length);
                     }
                  }

                  chunk->write_crc = crc_one_byte(chunk->write_crc, b);
                  break;

               /* The CRC is written at:
                *
                *    chunk_write == chunk_length+8..chunk_length+11
                *
                * so 8 to 11.  The CRC is not (yet) conditioned.
                */
               case  8: b = chunk->write_crc >> 24; goto write_crc;
               case  9: b = chunk->write_crc >> 16; goto write_crc;
               case 10: b = chunk->write_crc >>  8; goto write_crc;
               case 11:
                  /* This must happen before the chunk_end below: */
                  b = chunk->write_crc;

                  if (file->global->verbose > 2)
                  {
                     fputs("   ", stderr);
                     type_name(type, stderr);
                     fprintf(stderr, " %lu 0x%.8x\n", (unsigned long)length,
                        chunk->write_crc ^ 0xffffffff);
                  }

                  /* The IDAT stream is written without a call to read_chunk
                   * until the end is reached.  rechunk_length() calculates the
                   * length of the output chunks.  Control gets to this point at
                   * the end of an *output* chunk - the length calculated by
                   * rechunk_length.  If this corresponds to the end of the
                   * input stream stop writing IDAT chunks, otherwise continue.
                   */
                  if (file->state == STATE_IDAT &&
                     (file->idat->idat_index < file->idat->idat_length ||
                      1+file->idat->idat_count < file->idat->idat_cur->count ||
                      file->idat->idat_cur != file->idat->idat_list_tail))
                  {
                     /* Write another IDAT chunk.  Call rechunk_length to
                      * calculate the length required.
                      */
                     length = chunk->chunk_length = rechunk_length(file->idat);
                     assert(type == png_IDAT);
                     file->write_count = 0; /* for the new chunk */
                     --(file->write_count); /* fake out the increment below */
                  }

                  else
                  {
                     /* Entered at the end of a non-IDAT chunk and at the end of
                      * the IDAT stream.  The rewrite should have been cleared.
                      */
                     if (chunk->rewrite_length > 0 || chunk->rewrite_offset > 0)
                        stop(file, UNEXPECTED_ERROR_CODE, "pending rewrite");

                     /* This is the last byte so reset chunk_read for the next
                      * chunk and move the input file to the position after the
                      * *next* chunk header if required.
                      */
                     file->read_count = 8;
                     file_setpos(file, &file->data_pos);

                     if (file->idat == NULL)
                        chunk_end(&file->chunk);

                     else
                        IDAT_end(&file->idat);
                  }

               write_crc:
                  b ^= 0xff; /* conditioning */
                  break;
            }
            break;
      }

      /* Write one byte */
      b &= 0xff;
      *buffer++ = (png_byte)b;
      --count;
      write_byte(file, (png_byte)b); /* increments chunk_write */
   }
   while (count > 0);
}

/* Bundle the file and an uninitialized chunk and IDAT control structure
 * together to allow implementation of the chunk/IDAT allocate routine.
 */
struct control
{
   struct file  file;
   struct chunk chunk;
   struct IDAT  idat;
};

static int
control_end(struct control *control)
{
   return file_end(&control->file);
}

static struct file *
get_control(png_const_structrp png_ptr)
{
   /* This just returns the (file*).  The chunk and idat control structures
    * don't always exist.
    */
   struct control *control = voidcast(struct control*,
      png_get_error_ptr(png_ptr));
   return &control->file;
}

static void
allocate(struct file *file, int allocate_idat)
{
   struct control *control = voidcast(struct control*, file->alloc_ptr);

   if (allocate_idat)
   {
      assert(file->idat == NULL);
      IDAT_init(&control->idat, file);
   }

   else /* chunk */
   {
      assert(file->chunk == NULL);
      chunk_init(&control->chunk, file);
   }
}

static int
control_init(struct control *control, struct global *global,
   const char *file_name, const char *out_name)
   /* This wraps file_init(&control::file) and simply returns the result from
    * file_init.
    */
{
   return file_init(&control->file, global, file_name, out_name, control,
      allocate);
}

static int
read_png(struct control *control)
   /* Read a PNG, return 0 on success else an error (status) code; a bit mask as
    * defined for file::status_code as above.
    */
{
   png_structp png_ptr;
   png_infop info_ptr = NULL;
   volatile int rc;

   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, control,
      error_handler, warning_handler);

   if (png_ptr == NULL)
   {
      /* This is not really expected. */
      log_error(&control->file, LIBPNG_ERROR_CODE, "OOM allocating png_struct");
      control->file.status_code |= INTERNAL_ERROR;
      return LIBPNG_ERROR_CODE;
   }

   rc = setjmp(control->file.jmpbuf);
   if (rc == 0)
   {
#     ifdef PNG_SET_USER_LIMITS_SUPPORTED
         /* Remove any limits on the size of PNG files that can be read,
          * without this we may reject files based on built-in safety
          * limits.
          */
         png_set_user_limits(png_ptr, 0x7fffffff, 0x7fffffff);
         png_set_chunk_cache_max(png_ptr, 0);
         png_set_chunk_malloc_max(png_ptr, 0);
#     endif

      png_set_read_fn(png_ptr, control, read_callback);

      info_ptr = png_create_info_struct(png_ptr);
      if (info_ptr == NULL)
         png_error(png_ptr, "OOM allocating info structure");

      if (control->file.global->verbose)
         fprintf(stderr, " INFO\n");

      png_read_info(png_ptr, info_ptr);

      {
        png_uint_32 height = png_get_image_height(png_ptr, info_ptr);
        int passes = png_set_interlace_handling(png_ptr);
        int pass;

        png_start_read_image(png_ptr);

        for (pass = 0; pass < passes; ++pass)
        {
           png_uint_32 y = height;

           /* NOTE: this skips asking libpng to return either version of
            * the image row, but libpng still reads the rows.
            */
           while (y-- > 0)
              png_read_row(png_ptr, NULL, NULL);
        }
      }

      if (control->file.global->verbose)
         fprintf(stderr, " END\n");

      /* Make sure to read to the end of the file: */
      png_read_end(png_ptr, info_ptr);
   }

   png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
   return rc;
}

static int
one_file(struct global *global, const char *file_name, const char *out_name)
{
   int rc;
   struct control control;

   if (global->verbose)
      fprintf(stderr, "FILE %s -> %s\n", file_name,
         out_name ? out_name : "<none>");

   /* Although control_init can return a failure code the structure is always
    * initialized, so control_end can be used to accumulate any status codes.
    */
   rc = control_init(&control, global, file_name, out_name);

   if (rc == 0)
      rc = read_png(&control);

   rc |= control_end(&control);

   return rc;
}

static void
usage(const char *prog)
{
   /* ANSI C-90 limits strings to 509 characters, so use a string array: */
   size_t i;
   static const char *usage_string[] = {
"  Tests, optimizes and optionally fixes the zlib header in PNG files.",
"  Optionally, when fixing, strips ancilliary chunks from the file.",
0,
"OPTIONS",
"  OPERATION",
"      By default files are just checked for readability with a summary of the",
"      of zlib issues founds for each compressed chunk and the IDAT stream in",
"      the file.",
"    --optimize (-o):",
"      Find the smallest deflate window size for the compressed data.",
"    --strip=[none|crc|unsafe|unused|transform|color|all]:",
"        none (default):   Retain all chunks.",
"        crc:    Remove chunks with a bad CRC.",
"        unsafe: Remove chunks that may be unsafe to retain if the image data",
"                is modified.  This is set automatically if --max is given but",
"                may be cancelled by a later --strip=none.",
"        unused: Remove chunks not used by libpng when decoding an image.",
"                This retains any chunks that might be used by libpng image",
"                transformations.",
"        transform: unused+bKGD.",
"        color:  transform+iCCP and cHRM.",
"        all:    color+gAMA and sRGB.",
"      Only ancillary chunks are ever removed.  In addition the tRNS and sBIT",
"      chunks are never removed as they affect exact interpretation of the",
"      image pixel values.  The following known chunks are treated specially",
"      by the above options:",
"        gAMA, sRGB [all]: These specify the gamma encoding used for the pixel",
"            values.",
"        cHRM, iCCP [color]: These specify how colors are encoded.  iCCP also",
"            specifies the exact encoding of a pixel value; however, in",
"            practice most programs will ignore it.",
"        bKGD [transform]: This is used by libpng transforms."
"    --max=<number>:",
"      Use IDAT chunks sized <number>.  If no number is given the the IDAT",
"      chunks will be the maximum size permitted; 2^31-1 bytes.  If the option",
"      is omitted the original chunk sizes will not be changed.  When the",
"      option is given --strip=unsafe is set automatically. This may be",
"      cancelled if you know that all unknown unsafe-to-copy chunks really are",
"      safe to copy across an IDAT size change.  This is true of all chunks",
"      that have ever been formally proposed as PNG extensions.",
"  MESSAGES",
"      By default the program only outputs summaries for each file.",
"    --quiet (-q):",
"      Do not output the summaries except for files that cannot be read. With",
"      two --quiets these are not output either.",
"    --errors (-e):",
"      Output errors from libpng and the program (except too-far-back).",
"    --warnings (-w):",
"      Output warnings from libpng.",
"  OUTPUT",
"      By default nothing is written.",
"    --out=<file>:",
"      Write the optimized/corrected version of the next PNG to <file>.  This",
"      overrides the following two options",
"    --suffix=<suffix>:",
"      Set --out=<name><suffix> for all following files unless overridden on",
"      a per-file basis by explicit --out.",
"    --prefix=<prefix>:",
"      Set --out=<prefix><name> for all the following files unless overridden",
"      on a per-file basis by explicit --out.",
"      These two options can be used together to produce a suffix and prefix.",
"  INTERNAL OPTIONS",
#if 0 /*NYI*/
#ifdef PNG_MAXIMUM_INFLATE_WINDOW
"    --test:",
"      Test the PNG_MAXIMUM_INFLATE_WINDOW option.  Setting this disables",
"      output as this would produce a broken file.",
#endif
#endif
0,
"EXIT CODES",
"  *** SUBJECT TO CHANGE ***",
"  The program exit code is value in the range 0..127 holding a bit mask of",
"  the following codes.  Notice that the results for each file are combined",
"  together - check one file at a time to get a meaningful error code!",
"    0x01: The zlib too-far-back error existed in at least one chunk.",
"    0x02: At least one chunk had a CRC error.",
"    0x04: A chunk length was incorrect.",
"    0x08: The file was truncated.",
"  Errors less than 16 are potentially recoverable, for a single file if the",
"  exit code is less than 16 the file could be read (with corrections if a",
"  non-zero code is returned).",
"    0x10: The file could not be read, even with corrections.",
"    0x20: The output file could not be written.",
"    0x40: An unexpected, potentially internal, error occurred.",
"  If the command line arguments are incorrect the program exits with exit",
"  255.  Some older operating systems only support 7-bit exit codes, on those",
"  systems it is suggested that this program is first tested by supplying",
"  invalid arguments.",
0,
"DESCRIPTION",
"  " PROGRAM_NAME ":",
"  checks each PNG file on the command line for errors.  By default errors are",
"  not output and the program just returns an exit code and prints a summary.",
"  With the --quiet (-q) option the summaries are suppressed too and the",
"  program only outputs unexpected errors (internal errors and file open",
"  errors).",
"  Various known problems in PNG files are fixed while the file is being read",
"  The exit code says what problems were fixed.  In particular the zlib error:",
0,
"        \"invalid distance too far back\"",
0,
"  caused by an incorrect optimization of a zlib stream is fixed in any",
"  compressed chunk in which it is encountered.  An integrity problem of the",
"  PNG stream caused by a bug in libpng which wrote an incorrect chunk length",
"  is also fixed.  Chunk CRC errors are automatically fixed up.",
0,
"  Setting one of the \"OUTPUT\" options causes the possibly modified file to",
"  be written to a new file.",
0,
"  Notice that some PNG files with the zlib optimization problem can still be",
"  read by libpng under some circumstances.  This program will still detect",
"  and, if requested, correct the error.",
0,
"  The program will reliably process all files on the command line unless",
"  either an invalid argument causes the usage message (this message) to be",
"  produced or the program crashes.",
0,
"  The summary lines describe issues encountered with the zlib compressed",
"  stream of a chunk.  They have the following format, which is SUBJECT TO",
"  CHANGE in the future:",
0,
"     chunk reason comp-level p1 p2 p3 p4 file",
0,
"  p1 through p4 vary according to the 'reason'.  There are always 8 space",
"  separated fields.  Reasons specific formats are:",
0,
"     chunk ERR status code read-errno write-errno message file",
"     chunk SKP comp-level file-bits zlib-rc compressed message file",
"     chunk ??? comp-level file-bits ok-bits compressed uncompress file",
0,
"  The various fields are",
0,
"$1 chunk:      The chunk type of a chunk in the file or 'HEAD' if a problem",
"               is reported by libpng at the start of the IDAT stream.",
"$2 reason:     One of:",
"          CHK: A zlib header checksum was detected and fixed.",
"          TFB: The zlib too far back error was detected and fixed.",
"          OK : No errors were detected in the zlib stream and optimization",
"               was not requested, or was not possible.",
"          OPT: The zlib stream window bits value could be improved (and was).",
"          SKP: The chunk was skipped because of a zlib issue (zlib-rc) with",
"               explanation 'message'",
"          ERR: The read of the file was aborted.  The parameters explain why.",
"$3 status:     For 'ERR' the accumulated status code from 'EXIT CODES' above.",
"               This is printed as a 2 digit hexadecimal value",
"   comp-level: The recorded compression level (FLEVEL) of a zlib stream",
"               expressed as a string {supfast,stdfast,default,maximum}",
"$4 code:       The file exit code; where stop was called, as a fairly terse",
"               string {warning,libpng,zlib,invalid,read,write,unexpected}.",
"   file-bits:  The zlib window bits recorded in the file.",
"$5 read-errno: A system errno value from a read translated by strerror(3).",
"   zlib-rc:    A zlib return code as a string (see zlib.h).",
"   ok-bits:    The smallest zlib window bits value that works.",
"$6 write-errno:A system errno value from a write translated by strerror(3).",
"   compressed: The count of compressed bytes in the zlib stream, when the",
"               reason is 'SKP'; this is a count of the bytes read from the",
"               stream when the fatal error was encountered.",
"$7 message:    An error message (spaces replaced by _, as in all parameters),",
"   uncompress: The count of bytes from uncompressing the zlib stream; this",
"               may not be the same as the number of bytes in the image.",
"$8 file:       The name of the file (this may contain spaces).",
};

   fprintf(stderr, "Usage: %s {[options] png-file}\n", prog);

   for (i=0; i < (sizeof usage_string)/(sizeof usage_string[0]); ++i)
   {
      if (usage_string[i] != 0)
         fputs(usage_string[i], stderr);

      fputc('\n', stderr);
   }

   exit(255);
}

int
main(int argc, const char **argv)
{
   char temp_name[FILENAME_MAX+1];
   const char *  prog = *argv;
   const char *  outfile = NULL;
   const char *  suffix = NULL;
   const char *  prefix = NULL;
   int           done = 0; /* if at least one file is processed */
   struct global global;

   global_init(&global);

   while (--argc > 0)
   {
      ++argv;

      if (strcmp(*argv, "--debug") == 0)
      {
         /* To help debugging problems: */
         global.errors = global.warnings = 1;
         global.quiet = 0;
         global.verbose = 7;
      }

      else if (strncmp(*argv, "--max=", 6) == 0)
      {
         global.idat_max = (png_uint_32)atol(6+*argv);

         if (global.skip < SKIP_UNSAFE)
            global.skip = SKIP_UNSAFE;
      }

      else if (strcmp(*argv, "--max") == 0)
      {
         global.idat_max = 0x7fffffff;

         if (global.skip < SKIP_UNSAFE)
            global.skip = SKIP_UNSAFE;
      }

      else if (strcmp(*argv, "--optimize") == 0 || strcmp(*argv, "-o") == 0)
         global.optimize_zlib = 1;

      else if (strncmp(*argv, "--out=", 6) == 0)
         outfile = 6+*argv;

      else if (strncmp(*argv, "--suffix=", 9) == 0)
         suffix = 9+*argv;

      else if (strncmp(*argv, "--prefix=", 9) == 0)
         prefix = 9+*argv;

      else if (strcmp(*argv, "--strip=none") == 0)
         global.skip = SKIP_NONE;

      else if (strcmp(*argv, "--strip=crc") == 0)
         global.skip = SKIP_BAD_CRC;

      else if (strcmp(*argv, "--strip=unsafe") == 0)
         global.skip = SKIP_UNSAFE;

      else if (strcmp(*argv, "--strip=unused") == 0)
         global.skip = SKIP_UNUSED;

      else if (strcmp(*argv, "--strip=transform") == 0)
         global.skip = SKIP_TRANSFORM;

      else if (strcmp(*argv, "--strip=color") == 0)
         global.skip = SKIP_COLOR;

      else if (strcmp(*argv, "--strip=all") == 0)
         global.skip = SKIP_ALL;

      else if (strcmp(*argv, "--errors") == 0 || strcmp(*argv, "-e") == 0)
         global.errors = 1;

      else if (strcmp(*argv, "--warnings") == 0 || strcmp(*argv, "-w") == 0)
         global.warnings = 1;

      else if (strcmp(*argv, "--quiet") == 0 || strcmp(*argv, "-q") == 0)
      {
         if (global.quiet)
            global.quiet = 2;

         else
            global.quiet = 1;
      }

      else if (strcmp(*argv, "--verbose") == 0 || strcmp(*argv, "-v") == 0)
         ++global.verbose;

#if 0
      /* NYI */
#     ifdef PNG_MAXIMUM_INFLATE_WINDOW
         else if (strcmp(*argv, "--test") == 0)
            ++set_option;
#     endif
#endif

      else if ((*argv)[0] == '-')
         usage(prog);

      else
      {
         size_t outlen = strlen(*argv);

         if (outfile == NULL) /* else this takes precedence */
         {
            /* Consider the prefix/suffix options */
            if (prefix != NULL)
            {
               size_t prefixlen = strlen(prefix);

               if (prefixlen+outlen > FILENAME_MAX)
               {
                  fprintf(stderr, "%s: output file name too long: %s%s%s\n",
                     prog, prefix, *argv, suffix ? suffix : "");
                  global.status_code |= WRITE_ERROR;
                  continue;
               }

               memcpy(temp_name, prefix, prefixlen);
               memcpy(temp_name+prefixlen, *argv, outlen);
               outlen += prefixlen;
               outfile = temp_name;
            }

            else if (suffix != NULL)
               memcpy(temp_name, *argv, outlen);

            temp_name[outlen] = 0;

            if (suffix != NULL)
            {
               size_t suffixlen = strlen(suffix);

               if (outlen+suffixlen > FILENAME_MAX)
               {
                  fprintf(stderr, "%s: output file name too long: %s%s\n",
                     prog, *argv, suffix);
                  global.status_code |= WRITE_ERROR;
                  continue;
               }

               memcpy(temp_name+outlen, suffix, suffixlen);
               outlen += suffixlen;
               temp_name[outlen] = 0;
               outfile = temp_name;
            }
         }

         (void)one_file(&global, *argv, outfile);
         ++done;
         outfile = NULL;
      }
   }

   if (!done)
      usage(prog);

   return global_end(&global);
}

#else /* ZLIB_VERNUM < 0x1240 */
int
main(void)
{
   fprintf(stderr,
      "pngfix needs libpng with a zlib >=1.2.4 (not 0x%x)\n",
      ZLIB_VERNUM);
   return 77;
}
#endif /* ZLIB_VERNUM */

#else /* No read support */

int
main(void)
{
   fprintf(stderr, "pngfix does not work without read deinterlace support\n");
   return 77;
}
#endif /* PNG_READ_SUPPORTED && PNG_EASY_ACCESS_SUPPORTED */
#else /* No setjmp support */
int
main(void)
{
   fprintf(stderr, "pngfix does not work without setjmp support\n");
   return 77;
}
#endif /* PNG_SETJMP_SUPPORTED */

