/* pngimage.c
 *
 * Copyright (c) 2014 John Cunningham Bowler
 *
 * Last changed in libpng 1.6.10 [March 6, 2014]
 *
 * This code is released under the libpng license.
 * For conditions of distribution and use, see the disclaimer
 * and license in png.h
 *
 * Test the png_read_png and png_write_png interfaces.  Given a PNG file load it
 * using png_read_png and then write with png_write_png.  Test all possible
 * transforms.
 */
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <assert.h>

#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
#  include <config.h>
#endif

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

#ifndef PNG_SETJMP_SUPPORTED
#  include <setjmp.h> /* because png.h did *not* include this */
#endif

#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)
/* If a transform is valid on both read and write this implies that if the
 * transform is applied to read it must also be applied on write to produce
 * meaningful data.  This is because these transforms when performed on read
 * produce data with a memory format that does not correspond to a PNG format.
 *
 * Most of these transforms are invertible; after applying the transform on
 * write the result is the original PNG data that would have would have been
 * read if no transform were applied.
 *
 * The exception is _SHIFT, which destroys the low order bits marked as not
 * significant in a PNG with the sBIT chunk.
 *
 * The following table lists, for each transform, the conditions under which it
 * is expected to do anything.  Conditions are defined as follows:
 *
 * 1) Color mask bits required - simply a mask to AND with color_type; one of
 *    these must be present for the transform to fire, except that 0 means
 *    'always'.
 * 2) Color mask bits which must be absent - another mask - none of these must
 *    be present.
 * 3) Bit depths - a mask of component bit depths for the transform to fire.
 * 4) 'read' - the transform works in png_read_png.
 * 5) 'write' - the transform works in png_write_png.
 * 6) PNG_INFO_chunk; a mask of the chunks that must be present for the
 *    transform to fire.  All must be present - the requirement is that
 *    png_get_valid() & mask == mask, so if mask is 0 there is no requirement.
 *
 * The condition refers to the original image state - if multiple transforms are
 * used together it is possible to cause a transform that wouldn't fire on the
 * original image to fire.
 */
static struct transform_info
{
   const char *name;
   int         transform;
   png_uint_32 valid_chunks;
#     define CHUNK_NONE 0
#     define CHUNK_sBIT PNG_INFO_sBIT
#     define CHUNK_tRNS PNG_INFO_tRNS
   png_byte    color_mask_required;
   png_byte    color_mask_absent;
#     define COLOR_MASK_X   0
#     define COLOR_MASK_P   PNG_COLOR_MASK_PALETTE
#     define COLOR_MASK_C   PNG_COLOR_MASK_COLOR
#     define COLOR_MASK_A   PNG_COLOR_MASK_ALPHA
#     define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA)  /* absent = gray, no alpha */
   png_byte    bit_depths;
#     define BD_ALL  (1 + 2 + 4 + 8 + 16)
#     define BD_PAL  (1 + 2 + 4 + 8)
#     define BD_LOW  (1 + 2 + 4)
#     define BD_16   16
#     define BD_TRUE (8+16) /* i.e. true-color depths */
   png_byte    when;
#     define TRANSFORM_R  1
#     define TRANSFORM_W  2
#     define TRANSFORM_RW 3
   png_byte    tested; /* the transform was tested somewhere */
} transform_info[] =
{
   /* List ALL the PNG_TRANSFORM_ macros here.  Check for support using the READ
    * macros; even if the transform is supported on write it cannot be tested
    * without the read support.
    */
#  define T(name,chunk,cm_required,cm_absent,bd,when)\
   {  #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\
      COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\
      TRANSFORM_ ## when, 0/*!tested*/ }

#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
   T(STRIP_16,            NONE, X,   X,   16,  R),
      /* drops the bottom 8 bits when bit depth is 16 */
#endif
#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   T(STRIP_ALPHA,         NONE, A,   X,  ALL,  R),
      /* removes the alpha channel if present */
#endif
#ifdef PNG_WRITE_PACK_SUPPORTED
#  define TRANSFORM_RW_PACK TRANSFORM_RW
#else
#  define TRANSFORM_RW_PACK TRANSFORM_R
#endif
#ifdef PNG_READ_PACK_SUPPORTED
   T(PACKING,             NONE, X,   X,  LOW, RW_PACK),
      /* unpacks low-bit-depth components into 1 byte per component on read,
       * reverses this on write.
       */
#endif
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
#  define TRANSFORM_RW_PACKSWAP TRANSFORM_RW
#else
#  define TRANSFORM_RW_PACKSWAP TRANSFORM_R
#endif
#ifdef PNG_READ_PACKSWAP_SUPPORTED
   T(PACKSWAP,            NONE, X,   X,  LOW, RW_PACKSWAP),
      /* reverses the order of low-bit-depth components packed into a byte */
#endif
#ifdef PNG_READ_EXPAND_SUPPORTED
   T(EXPAND,              NONE, P,   X,  ALL,  R),
      /* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) *
       * Note that the 'EXPAND' transform does lots of different things: */
   T(EXPAND,              NONE, X,   C,  ALL,  R),
      /* expands grayscale PNG files to RGB, or RGBA */
   T(EXPAND,              tRNS, X,   A,  ALL,  R),
      /* expands the tRNS chunk in files without alpha */
#endif
#ifdef PNG_WRITE_INVERT_SUPPORTED
#  define TRANSFORM_RW_INVERT TRANSFORM_RW
#else
#  define TRANSFORM_RW_INVERT TRANSFORM_R
#endif
#ifdef PNG_READ_INVERT_SUPPORTED
   T(INVERT_MONO,         NONE, X,   C,  ALL, RW_INVERT),
      /* converts gray-scale components to 1..0 from 0..1 */
#endif
#ifdef PNG_WRITE_SHIFT_SUPPORTED
#  define TRANSFORM_RW_SHIFT TRANSFORM_RW
#else
#  define TRANSFORM_RW_SHIFT TRANSFORM_R
#endif
#ifdef PNG_READ_SHIFT_SUPPORTED
   T(SHIFT,               sBIT, X,   X,  ALL, RW_SHIFT),
      /* reduces component values to the original range based on the sBIT chunk,
       * this is only partially reversible - the low bits are lost and cannot be
       * recovered on write.  In fact write code replicates the bits to generate
       * new low-order bits.
       */
#endif
#ifdef PNG_WRITE_BGR_SUPPORTED
#  define TRANSFORM_RW_BGR TRANSFORM_RW
#else
#  define TRANSFORM_RW_BGR TRANSFORM_R
#endif
#ifdef PNG_READ_BGR_SUPPORTED
   T(BGR,                 NONE, C,   P, TRUE, RW_BGR),
      /* reverses the rgb component values of true-color pixels */
#endif
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
#  define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW
#else
#  define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R
#endif
#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   T(SWAP_ALPHA,          NONE, A,   X, TRUE, RW_SWAP_ALPHA),
      /* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or
       * AG, on write reverses the process.
       */
#endif
#ifdef PNG_WRITE_SWAP_SUPPORTED
#  define TRANSFORM_RW_SWAP TRANSFORM_RW
#else
#  define TRANSFORM_RW_SWAP TRANSFORM_R
#endif
#ifdef PNG_READ_SWAP_SUPPORTED
   T(SWAP_ENDIAN,         NONE, X,   P,   16, RW_SWAP),
      /* byte-swaps 16-bit component values */
#endif
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
#  define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW
#else
#  define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R
#endif
#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   T(INVERT_ALPHA,        NONE, A,   X, TRUE, RW_INVERT_ALPHA),
      /* converts an alpha channel from 0..1 to 1..0 */
#endif
#ifdef PNG_WRITE_FILLER_SUPPORTED
   T(STRIP_FILLER_BEFORE, NONE, A,   P, TRUE,  W), /* 'A' for a filler! */
      /* on write skips a leading filler channel; testing requires data with a
       * filler channel so this is produced from RGBA or GA images by removing
       * the 'alpha' flag from the color type in place.
       */
   T(STRIP_FILLER_AFTER,  NONE, A,   P, TRUE,  W),
      /* on write strips a trailing filler channel */
#endif
#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   T(GRAY_TO_RGB,         NONE, X,   C,  ALL,  R),
      /* expands grayscale images to RGB, also causes the palette part of
       * 'EXPAND' to happen.  Low bit depth grayscale images are expanded to
       * 8-bits per component and no attempt is made to convert the image to a
       * palette image.  While this transform is partially reversible
       * png_write_png does not currently support this.
       */
   T(GRAY_TO_RGB,         NONE, P,   X,  ALL,  R),
      /* The 'palette' side effect mentioned above; a bit bogus but this is the
       * way the libpng code works.
       */
#endif
#ifdef PNG_READ_EXPAND_16_SUPPORTED
   T(EXPAND_16,           NONE, X,   X,  PAL,  R),
      /* expands images to 16-bits per component, as a side effect expands
       * palette images to RGB and expands the tRNS chunk if present, so it can
       * modify 16-bit per component images as well:
       */
   T(EXPAND_16,           tRNS, X,   A,   16,  R),
      /* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit
       * image.
       */
#endif
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   T(SCALE_16,            NONE, X,   X,   16,  R)
      /* scales 16-bit components to 8-bits. */
#endif

#undef T
};

#define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0]))
#define TTABLE_SIZE ARRAY_SIZE(transform_info)

/* Some combinations of options that should be reversible are not; these cases
 * are bugs.
 */
static int known_bad_combos[][2] =
{
   /* problem, antidote */
   { PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ }
};

static int
is_combo(int transforms)
{
   return transforms & (transforms-1); /* non-zero if more than one set bit */
}

static int
first_transform(int transforms)
{
   return transforms & -transforms; /* lowest set bit */
}

static int
is_bad_combo(int transforms)
{
   unsigned int i;

   for (i=0; i<ARRAY_SIZE(known_bad_combos); ++i)
   {
      int combo = known_bad_combos[i][0];

      if ((combo & transforms) == combo &&
         (transforms & known_bad_combos[i][1]) == 0)
         return 1;
   }

   return 0; /* combo is ok */
}

static const char *
transform_name(int t)
   /* The name, if 't' has multiple bits set the name of the lowest set bit is
    * returned.
    */
{
   unsigned int i;

   t &= -t; /* first set bit */

   for (i=0; i<TTABLE_SIZE; ++i)
   {
      if ((transform_info[i].transform & t) != 0)
         return transform_info[i].name;
   }

   return "invalid transform";
}

/* Variables calculated by validate_T below and used to record all the supported
 * transforms.  Need (unsigned int) here because of the places where these
 * values are used (unsigned compares in the 'exhaustive' iterator.)
 */
static unsigned int read_transforms, write_transforms, rw_transforms;

static void
validate_T(void)
   /* Validate the above table - this just builds the above values */
{
   unsigned int i;

   for (i=0; i<TTABLE_SIZE; ++i)
   {
      if (transform_info[i].when & TRANSFORM_R)
         read_transforms |= transform_info[i].transform;

      if (transform_info[i].when & TRANSFORM_W)
         write_transforms |= transform_info[i].transform;
   }

   /* Reversible transforms are those which are supported on both read and
    * write.
    */
   rw_transforms = read_transforms & write_transforms;
}

/* FILE DATA HANDLING
 *    The original file is cached in memory.  During write the output file is
 *    written to memory.
 *
 *    In both cases the file data is held in a linked list of buffers - not all
 *    of these are in use at any time.
 */
struct buffer_list
{
   struct buffer_list *next;         /* next buffer in list */
   png_byte            buffer[1024]; /* the actual buffer */
};

struct buffer
{
   struct buffer_list  *last;       /* last buffer in use */
   size_t               end_count;  /* bytes in the last buffer */
   struct buffer_list  *current;    /* current buffer being read */
   size_t               read_count; /* count of bytes read from current */
   struct buffer_list   first;      /* the very first buffer */
};

static void
buffer_init(struct buffer *buffer)
   /* Call this only once for a given buffer */
{
   buffer->first.next = NULL;
   buffer->last = NULL;
   buffer->current = NULL;
}

#ifdef PNG_WRITE_SUPPORTED
static void
buffer_start_write(struct buffer *buffer)
{
   buffer->last = &buffer->first;
   buffer->end_count = 0;
   buffer->current = NULL;
}
#endif

static void
buffer_start_read(struct buffer *buffer)
{
   buffer->current = &buffer->first;
   buffer->read_count = 0;
}

#ifdef ENOMEM /* required by POSIX 1003.1 */
#  define MEMORY ENOMEM
#else
#  define MEMORY ERANGE /* required by ANSI-C */
#endif
static struct buffer *
get_buffer(png_structp pp)
   /* Used from libpng callbacks to get the current buffer */
{
   return (struct buffer*)png_get_io_ptr(pp);
}

#define NEW(type) ((type *)malloc(sizeof (type)))

static struct buffer_list *
buffer_extend(struct buffer_list *current)
{
   struct buffer_list *add;

   assert(current->next == NULL);

   add = NEW(struct buffer_list);
   if (add == NULL)
      return NULL;

   add->next = NULL;
   current->next = add;

   return add;
}

/* Load a buffer from a file; does the equivalent of buffer_start_write.  On a
 * read error returns an errno value, else returns 0.
 */
static int
buffer_from_file(struct buffer *buffer, FILE *fp)
{
   struct buffer_list *last = &buffer->first;
   size_t count = 0;

   for (;;)
   {
      size_t r = fread(last->buffer+count, 1/*size*/,
         (sizeof last->buffer)-count, fp);

      if (r > 0)
      {
         count += r;

         if (count >= sizeof last->buffer)
         {
            assert(count == sizeof last->buffer);
            count = 0;

            if (last->next == NULL)
            {
               last = buffer_extend(last);
               if (last == NULL)
                  return MEMORY;
            }

            else
               last = last->next;
         }
      }

      else /* fread failed - probably end of file */
      {
         if (feof(fp))
         {
            buffer->last = last;
            buffer->end_count = count;
            return 0; /* no error */
         }

         /* Some kind of funky error; errno should be non-zero */
         return errno == 0 ? ERANGE : errno;
      }
   }
}

/* This structure is used to control the test of a single file. */
typedef enum
{
   VERBOSE,        /* switches on all messages */
   INFORMATION,
   WARNINGS,       /* switches on warnings */
   LIBPNG_WARNING,
   APP_WARNING,
   ERRORS,         /* just errors */
   APP_FAIL,       /* continuable error - no need to longjmp */
   LIBPNG_ERROR,   /* this and higher cause a longjmp */
   LIBPNG_BUG,     /* erroneous behavior in libpng */
   APP_ERROR,      /* such as out-of-memory in a callback */
   QUIET,          /* no normal messages */
   USER_ERROR,     /* such as file-not-found */
   INTERNAL_ERROR
} error_level;
#define LEVEL_MASK      0xf   /* where the level is in 'options' */

#define EXHAUSTIVE      0x010 /* Test all combinations of active options */
#define STRICT          0x020 /* Fail on warnings as well as errors */
#define LOG             0x040 /* Log pass/fail to stdout */
#define CONTINUE        0x080 /* Continue on APP_FAIL errors */
#define SKIP_BUGS       0x100 /* Skip over known bugs */
#define LOG_SKIPPED     0x200 /* Log skipped bugs */
#define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */

/* Result masks apply to the result bits in the 'results' field below; these
 * bits are simple 1U<<error_level.  A pass requires either nothing worse than
 * warnings (--relaxes) or nothing worse than information (--strict)
 */
#define RESULT_STRICT(r)   (((r) & ~((1U<<WARNINGS)-1)) == 0)
#define RESULT_RELAXED(r)  (((r) & ~((1U<<ERRORS)-1)) == 0)

struct display
{
   jmp_buf        error_return;      /* Where to go to on error */

   const char    *filename;          /* The name of the original file */
   const char    *operation;         /* Operation being performed */
   int            transforms;        /* Transform used in operation */
   png_uint_32    options;           /* See display_log below */
   png_uint_32    results;           /* A mask of errors seen */


   png_structp    original_pp;       /* used on the original read */
   png_infop      original_ip;       /* set by the original read */

   png_size_t     original_rowbytes; /* of the original rows: */
   png_bytepp     original_rows;     /* from the original read */

   /* Original chunks valid */
   png_uint_32    chunks;

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

   /* Derived information for the original image. */
   int            active_transforms;  /* transforms that do something on read */
   int            ignored_transforms; /* transforms that should do nothing */

   /* Used on a read, both the original read and when validating a written
    * image.
    */
   png_structp    read_pp;
   png_infop      read_ip;

#  ifdef PNG_WRITE_SUPPORTED
      /* Used to write a new image (the original info_ptr is used) */
      png_structp   write_pp;
      struct buffer written_file;   /* where the file gets written */
#  endif

   struct buffer  original_file;     /* Data read from the original file */
};

static void
display_init(struct display *dp)
   /* Call this only once right at the start to initialize the control
    * structure, the (struct buffer) lists are maintained across calls - the
    * memory is not freed.
    */
{
   memset(dp, 0, sizeof *dp);
   dp->options = WARNINGS; /* default to !verbose, !quiet */
   dp->filename = NULL;
   dp->operation = NULL;
   dp->original_pp = NULL;
   dp->original_ip = NULL;
   dp->original_rows = NULL;
   dp->read_pp = NULL;
   dp->read_ip = NULL;
   buffer_init(&dp->original_file);

#  ifdef PNG_WRITE_SUPPORTED
      dp->write_pp = NULL;
      buffer_init(&dp->written_file);
#  endif
}

static void
display_clean_read(struct display *dp)
{
   if (dp->read_pp != NULL)
      png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
}

#ifdef PNG_WRITE_SUPPORTED
static void
display_clean_write(struct display *dp)
{
      if (dp->write_pp != NULL)
         png_destroy_write_struct(&dp->write_pp, NULL);
}
#endif

static void
display_clean(struct display *dp)
{
#  ifdef PNG_WRITE_SUPPORTED
      display_clean_write(dp);
#  endif
   display_clean_read(dp);

   dp->original_rowbytes = 0;
   dp->original_rows = NULL;
   dp->chunks = 0;

   png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL);
   /* leave the filename for error detection */
   dp->results = 0; /* reset for next time */
}

static struct display *
get_dp(png_structp pp)
   /* The display pointer is always stored in the png_struct error pointer */
{
   struct display *dp = (struct display*)png_get_error_ptr(pp);

   if (dp == NULL)
   {
      fprintf(stderr, "pngimage: internal error (no display)\n");
      exit(99); /* prevents a crash */
   }

   return dp;
}

/* error handling */
#ifdef __GNUC__
#  define VGATTR __attribute__((__format__ (__printf__,3,4)))
   /* Required to quiet GNUC warnings when the compiler sees a stdarg function
    * that calls one of the stdio v APIs.
    */
#else
#  define VGATTR
#endif
static void VGATTR
display_log(struct display *dp, error_level level, const char *fmt, ...)
   /* 'level' is as above, fmt is a stdio style format string.  This routine
    * does not return if level is above LIBPNG_WARNING
    */
{
   dp->results |= 1U << level;

   if (level > (error_level)(dp->options & LEVEL_MASK))
   {
      const char *lp;
      va_list ap;

      switch (level)
      {
         case INFORMATION:    lp = "information"; break;
         case LIBPNG_WARNING: lp = "warning(libpng)"; break;
         case APP_WARNING:    lp = "warning(pngimage)"; break;
         case APP_FAIL:       lp = "error(continuable)"; break;
         case LIBPNG_ERROR:   lp = "error(libpng)"; break;
         case LIBPNG_BUG:     lp = "bug(libpng)"; break;
         case APP_ERROR:      lp = "error(pngimage)"; break;
         case USER_ERROR:     lp = "error(user)"; break;

         case INTERNAL_ERROR: /* anything unexpected is an internal error: */
         case VERBOSE: case WARNINGS: case ERRORS: case QUIET:
         default:             lp = "bug(pngimage)"; break;
      }

      fprintf(stderr, "%s: %s: %s",
         dp->filename != NULL ? dp->filename : "<stdin>", lp, dp->operation);

      if (dp->transforms != 0)
      {
         int tr = dp->transforms;

         if (is_combo(tr))
            fprintf(stderr, "(0x%x)", tr);

         else
            fprintf(stderr, "(%s)", transform_name(tr));
      }

      fprintf(stderr, ": ");

      va_start(ap, fmt);
      vfprintf(stderr, fmt, ap);
      va_end(ap);

      fputc('\n', stderr);
   }
   /* else do not output any message */

   /* Errors cause this routine to exit to the fail code */
   if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE)))
      longjmp(dp->error_return, level);
}

/* error handler callbacks for libpng */
static void PNGCBAPI
display_warning(png_structp pp, png_const_charp warning)
{
   display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning);
}

static void PNGCBAPI
display_error(png_structp pp, png_const_charp error)
{
   struct display *dp = get_dp(pp);

   display_log(dp, LIBPNG_ERROR, "%s", error);
}

static void
display_cache_file(struct display *dp, const char *filename)
   /* Does the initial cache of the file. */
{
   FILE *fp;
   int ret;

   dp->filename = filename;

   if (filename != NULL)
   {
      fp = fopen(filename, "rb");
      if (fp == NULL)
         display_log(dp, USER_ERROR, "open failed: %s", strerror(errno));
   }

   else
      fp = stdin;

   ret = buffer_from_file(&dp->original_file, fp);

   fclose(fp);

   if (ret != 0)
      display_log(dp, APP_ERROR, "read failed: %s", strerror(ret));
}

static void
buffer_read(struct display *dp, struct buffer *bp, png_bytep data,
   png_size_t size)
{
   struct buffer_list *last = bp->current;
   size_t read_count = bp->read_count;

   while (size > 0)
   {
      size_t avail;

      if (last == NULL ||
         (last == bp->last && read_count >= bp->end_count))
      {
         display_log(dp, USER_ERROR, "file truncated (%lu bytes)",
            (unsigned long)size);
         /*NOTREACHED*/
         break;
      }

      else if (read_count >= sizeof last->buffer)
      {
         /* Move to the next buffer: */
         last = last->next;
         read_count = 0;
         bp->current = last; /* Avoid update outside the loop */

         /* And do a sanity check (the EOF case is caught above) */
         if (last == NULL)
         {
            display_log(dp, INTERNAL_ERROR, "damaged buffer list");
            /*NOTREACHED*/
            break;
         }
      }

      avail = (sizeof last->buffer) - read_count;
      if (avail > size)
         avail = size;

      memcpy(data, last->buffer + read_count, avail);
      read_count += avail;
      size -= avail;
      data += avail;
   }

   bp->read_count = read_count;
}

static void PNGCBAPI
read_function(png_structp pp, png_bytep data, png_size_t size)
{
   buffer_read(get_dp(pp), get_buffer(pp), data, size);
}

static void
read_png(struct display *dp, struct buffer *bp, const char *operation,
   int transforms)
{
   png_structp pp;
   png_infop   ip;

   /* This cleans out any previous read and sets operation and transforms to
    * empty.
    */
   display_clean_read(dp);

   if (operation != NULL) /* else this is a verify and do not overwrite info */
   {
      dp->operation = operation;
      dp->transforms = transforms;
   }

   dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp,
      display_error, display_warning);
   if (pp == NULL)
      display_log(dp, LIBPNG_ERROR, "failed to create read struct");

   /* The png_read_png API requires us to make the info struct, but it does the
    * call to png_read_info.
    */
   dp->read_ip = ip = png_create_info_struct(pp);
   if (ip == NULL)
      display_log(dp, LIBPNG_ERROR, "failed to create info struct");

#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
      /* Remove the user limits, if any */
      png_set_user_limits(pp, 0x7fffffff, 0x7fffffff);
#  endif

   /* Set the IO handling */
   buffer_start_read(bp);
   png_set_read_fn(pp, bp, read_function);

   png_read_png(pp, ip, transforms, NULL/*params*/);

#if 0 /* crazy debugging */
   {
      png_bytep pr = png_get_rows(pp, ip)[0];
      size_t rb = png_get_rowbytes(pp, ip);
      size_t cb;
      char c = ' ';

      fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb);

      for (cb=0; cb<rb; ++cb)
         fputc(c, stderr), fprintf(stderr, "%.2x", pr[cb]), c='.';

      fputc('\n', stderr);
   }
#endif
}

static void
update_display(struct display *dp)
   /* called once after the first read to update all the info, original_pp and
    * original_ip must have been filled in.
    */
{
   png_structp pp;
   png_infop   ip;

   /* Now perform the initial read with a 0 tranform. */
   read_png(dp, &dp->original_file, "original read", 0/*no transform*/);

   /* Move the result to the 'original' fields */
   dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL;
   dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL;

   dp->original_rowbytes = png_get_rowbytes(pp, ip);
   if (dp->original_rowbytes == 0)
      display_log(dp, LIBPNG_BUG, "png_get_rowbytes returned 0");

   dp->chunks = png_get_valid(pp, ip, 0xffffffff);
   if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */
      display_log(dp, LIBPNG_BUG, "png_read_png did not set IDAT flag");

   dp->original_rows = png_get_rows(pp, ip);
   if (dp->original_rows == NULL)
      display_log(dp, LIBPNG_BUG, "png_read_png did not create row buffers");

   if (!png_get_IHDR(pp, ip,
      &dp->width, &dp->height, &dp->bit_depth, &dp->color_type,
      &dp->interlace_method, &dp->compression_method, &dp->filter_method))
      display_log(dp, LIBPNG_BUG, "png_get_IHDR failed");

   /* 'active' transforms are discovered based on the original image format;
    * running one active transform can activate others.  At present the code
    * does not attempt to determine the closure.
    */
   {
      png_uint_32 chunks = dp->chunks;
      int active = 0, inactive = 0;
      int ct = dp->color_type;
      int bd = dp->bit_depth;
      unsigned int i;

      for (i=0; i<TTABLE_SIZE; ++i)
      {
         int transform = transform_info[i].transform;

         if ((transform_info[i].valid_chunks == 0 ||
               (transform_info[i].valid_chunks & chunks) != 0) &&
            (transform_info[i].color_mask_required & ct) == 
               transform_info[i].color_mask_required &&
            (transform_info[i].color_mask_absent & ct) == 0 &&
            (transform_info[i].bit_depths & bd) != 0 &&
            (transform_info[i].when & TRANSFORM_R) != 0)
            active |= transform;

         else if ((transform_info[i].when & TRANSFORM_R) != 0)
            inactive |= transform;
      }

      /* Some transforms appear multiple times in the table; the 'active' status
       * is the logical OR of these and the inactive status must be adjusted to
       * take this into account.
       */
      inactive &= ~active;

      dp->active_transforms = active;
      dp->ignored_transforms = inactive; /* excluding write-only transforms */

      if (active == 0)
         display_log(dp, INTERNAL_ERROR, "bad transform table");
   }
}

static int
compare_read(struct display *dp, int applied_transforms)
{
   /* Compare the png_info from read_ip with original_info */
   size_t rowbytes;
   png_uint_32 width, height;
   int bit_depth, color_type;
   int interlace_method, compression_method, filter_method;
   const char *e = NULL;

   png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth,
      &color_type, &interlace_method, &compression_method, &filter_method);

#  define C(item) if (item != dp->item) \
      display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\
         (unsigned long)dp->item, (unsigned long)item), e = #item

   /* The IHDR should be identical: */
   C(width);
   C(height);
   C(bit_depth);
   C(color_type);
   C(interlace_method);
   C(compression_method);
   C(filter_method);

   /* 'e' remains set to the name of the last thing changed: */
   if (e)
      display_log(dp, APP_ERROR, "IHDR changed (%s)", e);

   /* All the chunks from the original PNG should be preserved in the output PNG
    * because the PNG format has not been changed.
    */
   {
      unsigned long chunks =
         png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff);
      
      if (chunks != dp->chunks)
         display_log(dp, APP_FAIL, "PNG chunks changed from 0x%lx to 0x%lx",
            (unsigned long)dp->chunks, chunks);
   }

   /* rowbytes should be the same */
   rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip);

   /* NOTE: on 64-bit systems this may trash the top bits of rowbytes,
    * which could lead to weird error messages.
    */
   if (rowbytes != dp->original_rowbytes)
      display_log(dp, APP_ERROR, "PNG rowbytes changed from %lu to %lu",
         (unsigned long)dp->original_rowbytes, (unsigned long)rowbytes);

   /* The rows should be the same too, unless the applied transforms includes
    * the shift transform, in which case low bits may have been lost.
    */
   {
      png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip);
      unsigned int mask;  /* mask (if not zero) for the final byte */

      if (bit_depth < 8)
      {
         /* Need the stray bits at the end, this depends only on the low bits
          * of the image width; overflow does not matter.  If the width is an
          * exact multiple of 8 bits this gives a mask of 0, not 0xff.
          */
         mask = 0xff & (0xff00 >> ((bit_depth * width) & 7));
      }

      else
         mask = 0;

      if (rows == NULL)
         display_log(dp, LIBPNG_BUG, "png_get_rows returned NULL");

      if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
         (dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 ||
         color_type == PNG_COLOR_TYPE_PALETTE)
      {
         unsigned long y;

         for (y=0; y<height; ++y)
         {
            png_bytep row = rows[y];
            png_bytep orig = dp->original_rows[y];

            if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 &&
               ((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask))))
            {
               size_t x;

               /* Find the first error */
               for (x=0; x<rowbytes-1; ++x) if (row[x] != orig[x])
                  break;

               display_log(dp, APP_FAIL,
                  "byte(%lu,%lu) changed 0x%.2x -> 0x%.2x",
                  (unsigned long)x, (unsigned long)y, orig[x], row[x]);
               return 0; /* don't keep reporting failed rows on 'continue' */
            }
         }
      }

      else
      {
         unsigned long y;
         int bpp;   /* bits-per-pixel then bytes-per-pixel */
         /* components are up to 8 bytes in size */
         png_byte sig_bits[8];
         png_color_8p sBIT;

         if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT)
            display_log(dp, INTERNAL_ERROR,
               "active shift transform but no sBIT in file");

         switch (color_type)
         {
            case PNG_COLOR_TYPE_GRAY:
               sig_bits[0] = sBIT->gray;
               bpp = bit_depth;
               break;

            case PNG_COLOR_TYPE_GA:
               sig_bits[0] = sBIT->gray;
               sig_bits[1] = sBIT->alpha;
               bpp = 2 * bit_depth;
               break;

            case PNG_COLOR_TYPE_RGB:
               sig_bits[0] = sBIT->red;
               sig_bits[1] = sBIT->green;
               sig_bits[2] = sBIT->blue;
               bpp = 3 * bit_depth;
               break;

            case PNG_COLOR_TYPE_RGBA:
               sig_bits[0] = sBIT->red;
               sig_bits[1] = sBIT->green;
               sig_bits[2] = sBIT->blue;
               sig_bits[3] = sBIT->alpha;
               bpp = 4 * bit_depth;
               break;

            default:
               display_log(dp, LIBPNG_ERROR, "invalid colour type %d",
                  color_type);
               /*NOTREACHED*/
               bpp = 0;
               break;
         }

         {
            int b;

            for (b=0; 8*b<bpp; ++b)
            {
               /* libpng should catch this; if not there is a security issue
                * because an app (like this one) may overflow an array. In fact
                * libpng doesn't catch this at present.
                */
               if (sig_bits[b] == 0 || sig_bits[b] > bit_depth/*!palette*/)
                  display_log(dp, LIBPNG_BUG,
                     "invalid sBIT[%u]  value %d returned for PNG bit depth %d",
                     b, sig_bits[b], bit_depth);
            }
         }

         if (bpp < 8 && bpp != bit_depth)
         {
            /* sanity check; this is a grayscale PNG; something is wrong in the
             * code above.
             */
            display_log(dp, INTERNAL_ERROR, "invalid bpp %u for bit_depth %u",
               bpp, bit_depth);
         }

         switch (bit_depth)
         {
            int b;

            case 16: /* Two bytes per component, bit-endian */
               for (b = (bpp >> 4); b > 0; )
               {
                  unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]);

                  sig_bits[2*b+1] = (png_byte)sig;
                  sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */
               }
               break;

            case 8: /* One byte per component */
               for (b=0; b*8 < bpp; ++b)
                  sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]);
               break;

            case 1: /* allowed, but dumb */
               /* Value is 1 */
               sig_bits[0] = 0xff;
               break;

            case 2: /* Replicate 4 times */
               /* Value is 1 or 2 */
               b = 0x3 & ((0x3<<2) >> sig_bits[0]);
               b |= b << 2;
               b |= b << 4;
               sig_bits[0] = (png_byte)b;
               break;

            case 4: /* Relicate twice */
               /* Value is 1, 2, 3 or 4 */
               b = 0xf & ((0xf << 4) >> sig_bits[0]);
               b |= b << 4;
               sig_bits[0] = (png_byte)b;
               break;

            default:
               display_log(dp, LIBPNG_BUG, "invalid bit depth %d", bit_depth);
               break;
         }

         /* Convert bpp to bytes; this gives '1' for low-bit depth grayscale,
          * where there are multiple pixels per byte.
          */
         bpp = (bpp+7) >> 3;

         /* The mask can be combined with sig_bits[0] */
         if (mask != 0)
         {
            mask &= sig_bits[0];

            if (bpp != 1 || mask == 0)
               display_log(dp, INTERNAL_ERROR, "mask calculation error %u, %u",
                  bpp, mask);
         }

         for (y=0; y<height; ++y)
         {
            png_bytep row = rows[y];
            png_bytep orig = dp->original_rows[y];
            unsigned long x;

            for (x=0; x<(width-(mask!=0)); ++x)
            {
               int b;

               for (b=0; b<bpp; ++b)
               {
                  if ((*row++ & sig_bits[b]) != (*orig++ & sig_bits[b]))
                  {
                     display_log(dp, APP_FAIL,
                        "significant bits at (%lu[%u],%lu) changed %.2x->%.2x",
                        x, b, y, orig[-1], row[-1]);
                     return 0;
                  }
               }
            }

            if (mask != 0 && (*row & mask) != (*orig & mask))
            {
               display_log(dp, APP_FAIL,
                  "significant bits at (%lu[end],%lu) changed", x, y);
               return 0;
            }
         } /* for y */
      }
   }

   return 1; /* compare succeeded */
}

#ifdef PNG_WRITE_SUPPORTED
static void
buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
   png_size_t size)
   /* Generic write function used both from the write callback provided to
    * libpng and from the generic read code.
    */
{
   /* Write the data into the buffer, adding buffers as required */
   struct buffer_list *last = buffer->last;
   size_t end_count = buffer->end_count;

   while (size > 0)
   {
      size_t avail;

      if (end_count >= sizeof last->buffer)
      {
         if (last->next == NULL)
         {
            last = buffer_extend(last);

            if (last == NULL)
               display_log(dp, APP_ERROR, "out of memory saving file");
         }

         else
            last = last->next;

         buffer->last = last; /* avoid the need to rewrite every time */
         end_count = 0;
      }

      avail = (sizeof last->buffer) - end_count;
      if (avail > size)
         avail = size;

      memcpy(last->buffer + end_count, data, avail);
      end_count += avail;
      size -= avail;
      data += avail;
   }

   buffer->end_count = end_count;
}

static void PNGCBAPI
write_function(png_structp pp, png_bytep data, png_size_t size)
{
   buffer_write(get_dp(pp), get_buffer(pp), data, size);
}

static void
write_png(struct display *dp, png_infop ip, int transforms)
{
   display_clean_write(dp); /* safety */

   buffer_start_write(&dp->written_file);
   dp->operation = "write";
   dp->transforms = transforms;

   dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp,
      display_error, display_warning);

   if (dp->write_pp == NULL)
      display_log(dp, APP_ERROR, "failed to create write png_struct");

   png_set_write_fn(dp->write_pp, &dp->written_file, write_function,
      NULL/*flush*/);

#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
      /* Remove the user limits, if any */
      png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff);
#  endif

   /* Certain transforms require the png_info to be zapped to allow the
    * transform to work correctly.
    */
   if (transforms & (PNG_TRANSFORM_PACKING|
                     PNG_TRANSFORM_STRIP_FILLER|
                     PNG_TRANSFORM_STRIP_FILLER_BEFORE))
   {
      int ct = dp->color_type;

      if (transforms & (PNG_TRANSFORM_STRIP_FILLER|
                        PNG_TRANSFORM_STRIP_FILLER_BEFORE))
         ct &= ~PNG_COLOR_MASK_ALPHA;

      png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct,
         dp->interlace_method, dp->compression_method, dp->filter_method);
   }

   png_write_png(dp->write_pp, ip, transforms, NULL/*params*/);

   /* Clean it on the way out - if control returns to the caller then the
    * written_file contains the required data.
    */
   display_clean_write(dp);
}
#endif /* WRITE_SUPPORTED */

static int
skip_transform(struct display *dp, int tr)
   /* Helper to test for a bad combo and log it if it is skipped */
{
   if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr))
   {
      /* Log this to stdout if logging is on, otherwise just do an information
       * display_log.
       */
      if ((dp->options & LOG_SKIPPED) != 0)
      {
         printf("SKIP: %s transforms ", dp->filename);

         while (tr != 0)
         {
            int next = first_transform(tr);
            tr &= ~next;

            printf("%s", transform_name(next));
            if (tr != 0)
               putchar('+');
         }

         putchar('\n');
      }

      else
         display_log(dp, INFORMATION, "%s: skipped known bad combo 0x%x",
            dp->filename, tr);

      return 1; /* skip */
   }

   return 0; /* don't skip */
}

static void
test_one_file(struct display *dp, const char *filename)
{
   /* First cache the file and update the display original file
    * information for the new file.
    */
   dp->operation = "cache file";
   dp->transforms = 0;
   display_cache_file(dp, filename);
   update_display(dp);

   /* First test: if there are options that should be ignored for this file
    * verify that they really are ignored.
    */
   if (dp->ignored_transforms != 0)
   {
      read_png(dp, &dp->original_file, "ignored transforms",
         dp->ignored_transforms);

      /* The result should be identical to the original_rows */
      if (!compare_read(dp, 0/*transforms applied*/))
         return; /* no point testing more */
   }

#ifdef PNG_WRITE_SUPPORTED
   /* Second test: write the original PNG data out to a new file (to test the
    * write side) then read the result back in and make sure that it hasn't
    * changed.
    */
   dp->operation = "write";
   write_png(dp, dp->original_ip, 0/*transforms*/);
   read_png(dp, &dp->written_file, NULL, 0/*transforms*/);
   if (!compare_read(dp, 0/*transforms applied*/))
      return;
#endif

   /* Third test: the active options.  Test each in turn, or, with the
    * EXHAUSTIVE option, test all possible combinations.
    */
   {
      /* Use unsigned int here because the code below to increment through all
       * the possibilities exhaustively has to use a compare and that must be
       * unsigned, because some transforms are negative on a 16-bit system.
       */
      unsigned int active = dp->active_transforms;
      const int exhaustive = (dp->options & EXHAUSTIVE) != 0;
      unsigned int current = first_transform(active);
      unsigned int bad_transforms = 0;
      unsigned int bad_combo = ~0U;    /* bitwise AND of failing transforms */
      unsigned int bad_combo_list = 0; /* bitwise OR of failures */

      for (;;)
      {
         read_png(dp, &dp->original_file, "active transforms", current);

         /* If this involved any irreversible transformations then if we write
          * it out with just the reversible transformations and read it in again
          * with the same transforms we should get the same thing.  At present
          * this isn't done - it just seems like a waste of time and it would
          * require two sets of read png_struct/png_info.
          *
          * If there were no irreversible transformations then if we write it
          * out and read it back in again (without the reversible transforms)
          * we should get back to the place where we started.
          */
#ifdef PNG_WRITE_SUPPORTED
         if ((current & write_transforms) == current)
         {
            /* All transforms reversible: write the PNG with the transformations
             * reversed, then read it back in with no transformations.  The
             * result should be the same as the original apart from the loss of
             * low order bits because of the SHIFT/sBIT transform.
             */
            dp->operation = "reversible transforms";
            write_png(dp, dp->read_ip, current);

            /* And if this is read back in, because all the transformations were
             * reversible, the result should be the same.
             */
            read_png(dp, &dp->written_file, NULL, 0);
            if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/))
            {
               /* This set of transforms failed.  If a single bit is set - if
                * there is just one transform - don't include this in further
                * 'exhaustive' tests.  Notice that each transform is tested on
                * its own before testing combos in the exhaustive case.
                */
               if (is_combo(current))
               {
                  bad_combo &= current;
                  bad_combo_list |= current;
               }

               else
                  bad_transforms |= current;
            }
         }
#endif

         /* Now move to the next transform */
         if (exhaustive) /* all combinations */
         {
            unsigned int next = current;

            do
            {
               if (next == read_transforms) /* Everything tested */
                  goto combo;

               ++next;
            }  /* skip known bad combos if the relevant option is set; skip
                * combos involving known bad single transforms in all cases.
                */
            while (  (next & read_transforms) <= current
                  || (next & active) == 0 /* skip cases that do nothing */
                  || (next & bad_transforms) != 0
                  || skip_transform(dp, next));

            assert((next & read_transforms) == next);
            current = next;
         }

         else /* one at a time */
         {
            active &= ~current;

            if (active == 0)
               goto combo;

            current = first_transform(active);
         }
      }

combo:
      if (dp->options & FIND_BAD_COMBOS)
      {
         /* bad_combos identifies the combos that occur in all failing cases;
          * bad_combo_list identifies transforms that do not prevent the
          * failure.
          */
         if (bad_combo != ~0U)
            printf("%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\n",
               dp->filename, active, bad_combo, bad_combo_list,
               rw_transforms & ~bad_combo_list);

         else
            printf("%s: no %sbad combos found\n", dp->filename,
               (dp->options & SKIP_BUGS) ? "additional " : "");
      }
   }
}

static int
do_test(struct display *dp, const char *file)
   /* Exists solely to isolate the setjmp clobbers */
{
   int ret = setjmp(dp->error_return);

   if (ret == 0)
   {
      test_one_file(dp, file);
      return 0;
   }

   else if (ret < ERRORS) /* shouldn't longjmp on warnings */
      display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret);

   return ret;
}

int
main(const int argc, const char * const * const argv)
{
   /* For each file on the command line test it with a range of transforms */
   int option_end, ilog = 0;
   struct display d;

   validate_T();
   display_init(&d);

   for (option_end=1; option_end<argc; ++option_end)
   {
      const char *name = argv[option_end];

      if (strcmp(name, "--verbose") == 0)
         d.options = (d.options & ~LEVEL_MASK) | VERBOSE;

      else if (strcmp(name, "--warnings") == 0)
         d.options = (d.options & ~LEVEL_MASK) | WARNINGS;

      else if (strcmp(name, "--errors") == 0)
         d.options = (d.options & ~LEVEL_MASK) | ERRORS;

      else if (strcmp(name, "--quiet") == 0)
         d.options = (d.options & ~LEVEL_MASK) | QUIET;

      else if (strcmp(name, "--exhaustive") == 0)
         d.options |= EXHAUSTIVE;

      else if (strcmp(name, "--fast") == 0)
         d.options &= ~EXHAUSTIVE;

      else if (strcmp(name, "--strict") == 0)
         d.options |= STRICT;

      else if (strcmp(name, "--relaxed") == 0)
         d.options &= ~STRICT;

      else if (strcmp(name, "--log") == 0)
      {
         ilog = option_end; /* prevent display */
         d.options |= LOG;
      }

      else if (strcmp(name, "--nolog") == 0)
         d.options &= ~LOG;

      else if (strcmp(name, "--continue") == 0)
         d.options |= CONTINUE;

      else if (strcmp(name, "--stop") == 0)
         d.options &= ~CONTINUE;

      else if (strcmp(name, "--skip-bugs") == 0)
         d.options |= SKIP_BUGS;

      else if (strcmp(name, "--test-all") == 0)
         d.options &= ~SKIP_BUGS;

      else if (strcmp(name, "--log-skipped") == 0)
         d.options |= LOG_SKIPPED;

      else if (strcmp(name, "--nolog-skipped") == 0)
         d.options &= ~LOG_SKIPPED;

      else if (strcmp(name, "--find-bad-combos") == 0)
         d.options |= FIND_BAD_COMBOS;

      else if (strcmp(name, "--nofind-bad-combos") == 0)
         d.options &= ~FIND_BAD_COMBOS;

      else if (name[0] == '-' && name[1] == '-')
      {
         fprintf(stderr, "pngimage: %s: unknown option\n", name);
         return 99;
      }

      else
         break; /* Not an option */
   }

   {
      int i;
      int errors = 0;

      for (i=option_end; i<argc; ++i)
      {
         {
            int ret = do_test(&d, argv[i]);

            if (ret > QUIET) /* abort on user or internal error */
               return 99;
         }

         /* Here on any return, including failures, except user/internal issues
          */
         {
            const int pass = (d.options & STRICT) ?
               RESULT_STRICT(d.results) : RESULT_RELAXED(d.results);

            if (!pass)
               ++errors;

            if (d.options & LOG)
            {
               int j;

               printf("%s: pngimage ", pass ? "PASS" : "FAIL");

               for (j=1; j<option_end; ++j) if (j != ilog)
                  printf("%s ", argv[j]);

               printf("%s\n", d.filename);
            }
         }

         display_clean(&d);
      }

      return errors != 0;
   }
}
#else /* !PNG_INFO_IMAGE_SUPPORTED || !PNG_READ_SUPPORTED */
int
main(void)
{
   fprintf(stderr, "pngimage: no support for png_read/write_image\n");
   return 77;
}
#endif
