Home | History | Annotate | Download | only in libtests
      1 
      2 /* pngvalid.c - validate libpng by constructing then reading png files.
      3  *
      4  * Last changed in libpng 1.6.22 [(PENDING RELEASE)]
      5  * Copyright (c) 2014-2016 Glenn Randers-Pehrson
      6  * Written by John Cunningham Bowler
      7  *
      8  * This code is released under the libpng license.
      9  * For conditions of distribution and use, see the disclaimer
     10  * and license in png.h
     11  *
     12  * NOTES:
     13  *   This is a C program that is intended to be linked against libpng.  It
     14  *   generates bitmaps internally, stores them as PNG files (using the
     15  *   sequential write code) then reads them back (using the sequential
     16  *   read code) and validates that the result has the correct data.
     17  *
     18  *   The program can be modified and extended to test the correctness of
     19  *   transformations performed by libpng.
     20  */
     21 
     22 #define _POSIX_SOURCE 1
     23 #define _ISOC99_SOURCE 1 /* For floating point */
     24 #define _GNU_SOURCE 1 /* For the floating point exception extension */
     25 
     26 #include <signal.h>
     27 #include <stdio.h>
     28 
     29 #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
     30 #  include <config.h>
     31 #endif
     32 
     33 #ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */
     34 #  include <fenv.h>
     35 #endif
     36 
     37 #ifndef FE_DIVBYZERO
     38 #  define FE_DIVBYZERO 0
     39 #endif
     40 #ifndef FE_INVALID
     41 #  define FE_INVALID 0
     42 #endif
     43 #ifndef FE_OVERFLOW
     44 #  define FE_OVERFLOW 0
     45 #endif
     46 
     47 /* Define the following to use this test against your installed libpng, rather
     48  * than the one being built here:
     49  */
     50 #ifdef PNG_FREESTANDING_TESTS
     51 #  include <png.h>
     52 #else
     53 #  include "../../png.h"
     54 #endif
     55 
     56 #ifdef PNG_ZLIB_HEADER
     57 #  include PNG_ZLIB_HEADER
     58 #else
     59 #  include <zlib.h>   /* For crc32 */
     60 #endif
     61 
     62 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate
     63  * a skipped test, in earlier versions we need to succeed on a skipped test, so:
     64  */
     65 #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
     66 #  define SKIP 77
     67 #else
     68 #  define SKIP 0
     69 #endif
     70 
     71 /* pngvalid requires write support and one of the fixed or floating point APIs.
     72  */
     73 #if defined(PNG_WRITE_SUPPORTED) &&\
     74    (defined(PNG_FIXED_POINT_SUPPORTED) || defined(PNG_FLOATING_POINT_SUPPORTED))
     75 
     76 #if PNG_LIBPNG_VER < 10500
     77 /* This deliberately lacks the const. */
     78 typedef png_byte *png_const_bytep;
     79 
     80 /* This is copied from 1.5.1 png.h: */
     81 #define PNG_INTERLACE_ADAM7_PASSES 7
     82 #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7)
     83 #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7)
     84 #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
     85 #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
     86 #define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
     87    -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
     88 #define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
     89    -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
     90 #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \
     91    (((yIn)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
     92 #define PNG_COL_FROM_PASS_COL(xIn, pass) \
     93    (((xIn)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
     94 #define PNG_PASS_MASK(pass,off) ( \
     95    ((0x110145AFU>>(((7-(off))-(pass))<<2)) & 0xFU) | \
     96    ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U))
     97 #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
     98    ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
     99 #define PNG_COL_IN_INTERLACE_PASS(x, pass) \
    100    ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
    101 
    102 /* These are needed too for the default build: */
    103 #define PNG_WRITE_16BIT_SUPPORTED
    104 #define PNG_READ_16BIT_SUPPORTED
    105 
    106 /* This comes from pnglibconf.h afer 1.5: */
    107 #define PNG_FP_1 100000
    108 #define PNG_GAMMA_THRESHOLD_FIXED\
    109    ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1))
    110 #endif
    111 
    112 #if PNG_LIBPNG_VER < 10600
    113    /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be
    114     * compiled against earlier versions.
    115     */
    116 #  define png_const_structp png_structp
    117 #endif
    118 
    119 #ifndef RELEASE_BUILD
    120    /* RELEASE_BUILD is true for releases and release candidates: */
    121 #  define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
    122 #endif
    123 #if RELEASE_BUILD
    124 #   define debugonly(something)
    125 #else /* !RELEASE_BUILD */
    126 #   define debugonly(something) something
    127 #endif /* !RELEASE_BUILD */
    128 
    129 #include <float.h>  /* For floating point constants */
    130 #include <stdlib.h> /* For malloc */
    131 #include <string.h> /* For memcpy, memset */
    132 #include <math.h>   /* For floor */
    133 
    134 /* Unused formal parameter errors are removed using the following macro which is
    135  * expected to have no bad effects on performance.
    136  */
    137 #ifndef UNUSED
    138 #  if defined(__GNUC__) || defined(_MSC_VER)
    139 #     define UNUSED(param) (void)param;
    140 #  else
    141 #     define UNUSED(param)
    142 #  endif
    143 #endif
    144 
    145 /***************************** EXCEPTION HANDLING *****************************/
    146 #ifdef PNG_FREESTANDING_TESTS
    147 #  include <cexcept.h>
    148 #else
    149 #  include "../visupng/cexcept.h"
    150 #endif
    151 
    152 #ifdef __cplusplus
    153 #  define this not_the_cpp_this
    154 #  define new not_the_cpp_new
    155 #  define voidcast(type, value) static_cast<type>(value)
    156 #else
    157 #  define voidcast(type, value) (value)
    158 #endif /* __cplusplus */
    159 
    160 struct png_store;
    161 define_exception_type(struct png_store*);
    162 
    163 /* The following are macros to reduce typing everywhere where the well known
    164  * name 'the_exception_context' must be defined.
    165  */
    166 #define anon_context(ps) struct exception_context *the_exception_context = \
    167    &(ps)->exception_context
    168 #define context(ps,fault) anon_context(ps); png_store *fault
    169 
    170 /* This macro returns the number of elements in an array as an (unsigned int),
    171  * it is necessary to avoid the inability of certain versions of GCC to use
    172  * the value of a compile-time constant when performing range checks.  It must
    173  * be passed an array name.
    174  */
    175 #define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0])))
    176 
    177 /* GCC BUG 66447 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66447) requires
    178  * some broken GCC versions to be fixed up to avoid invalid whining about auto
    179  * variables that are *not* changed within the scope of a setjmp being changed.
    180  *
    181  * Feel free to extend the list of broken versions.
    182  */
    183 #define is_gnu(major,minor)\
    184    (defined __GNUC__) && __GNUC__ == (major) && __GNUC_MINOR__ == (minor)
    185 #define is_gnu_patch(major,minor,patch)\
    186    is_gnu(major,minor) && __GNUC_PATCHLEVEL__ == 0
    187 /* For the moment just do it always; all versions of GCC seem to be broken: */
    188 #ifdef __GNUC__
    189    const void * volatile make_volatile_for_gnu;
    190 #  define gnu_volatile(x) make_volatile_for_gnu = &x;
    191 #else /* !GNUC broken versions */
    192 #  define gnu_volatile(x)
    193 #endif /* !GNUC broken versions */
    194 
    195 /******************************* UTILITIES ************************************/
    196 /* Error handling is particularly problematic in production code - error
    197  * handlers often themselves have bugs which lead to programs that detect
    198  * minor errors crashing.  The following functions deal with one very
    199  * common class of errors in error handlers - attempting to format error or
    200  * warning messages into buffers that are too small.
    201  */
    202 static size_t safecat(char *buffer, size_t bufsize, size_t pos,
    203    const char *cat)
    204 {
    205    while (pos < bufsize && cat != NULL && *cat != 0)
    206       buffer[pos++] = *cat++;
    207 
    208    if (pos >= bufsize)
    209       pos = bufsize-1;
    210 
    211    buffer[pos] = 0;
    212    return pos;
    213 }
    214 
    215 static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n)
    216 {
    217    char number[64];
    218    sprintf(number, "%d", n);
    219    return safecat(buffer, bufsize, pos, number);
    220 }
    221 
    222 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    223 static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d,
    224     int precision)
    225 {
    226    char number[64];
    227    sprintf(number, "%.*f", precision, d);
    228    return safecat(buffer, bufsize, pos, number);
    229 }
    230 #endif
    231 
    232 static const char invalid[] = "invalid";
    233 static const char sep[] = ": ";
    234 
    235 static const char *colour_types[8] =
    236 {
    237    "grayscale", invalid, "truecolour", "indexed-colour",
    238    "grayscale with alpha", invalid, "truecolour with alpha", invalid
    239 };
    240 
    241 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    242 /* Convert a double precision value to fixed point. */
    243 static png_fixed_point
    244 fix(double d)
    245 {
    246    d = floor(d * PNG_FP_1 + .5);
    247    return (png_fixed_point)d;
    248 }
    249 #endif /* PNG_READ_SUPPORTED */
    250 
    251 /* Generate random bytes.  This uses a boring repeatable algorithm and it
    252  * is implemented here so that it gives the same set of numbers on every
    253  * architecture.  It's a linear congruential generator (Knuth or Sedgewick
    254  * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
    255  * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise
    256  * Generation.)
    257  */
    258 static void
    259 make_random_bytes(png_uint_32* seed, void* pv, size_t size)
    260 {
    261    png_uint_32 u0 = seed[0], u1 = seed[1];
    262    png_bytep bytes = voidcast(png_bytep, pv);
    263 
    264    /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
    265     * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.
    266     */
    267    size_t i;
    268    for (i=0; i<size; ++i)
    269    {
    270       /* First generate 8 new bits then shift them in at the end. */
    271       png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
    272       u1 <<= 8;
    273       u1 |= u0 >> 24;
    274       u0 <<= 8;
    275       u0 |= u;
    276       *bytes++ = (png_byte)u;
    277    }
    278 
    279    seed[0] = u0;
    280    seed[1] = u1;
    281 }
    282 
    283 static void
    284 make_four_random_bytes(png_uint_32* seed, png_bytep bytes)
    285 {
    286    make_random_bytes(seed, bytes, 4);
    287 }
    288 
    289 #if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\
    290     defined PNG_WRITE_FILTER_SUPPORTED
    291 static void
    292 randomize(void *pv, size_t size)
    293 {
    294    static png_uint_32 random_seed[2] = {0x56789abc, 0xd};
    295    make_random_bytes(random_seed, pv, size);
    296 }
    297 
    298 #define R8(this) randomize(&(this), sizeof (this))
    299 
    300 static void r16(png_uint_16p p16, size_t count)
    301 {
    302    size_t i;
    303 
    304    for (i=0; i<count; ++i)
    305    {
    306       unsigned char b2[2];
    307       randomize(b2, sizeof b2);
    308       *p16++ = png_get_uint_16(b2);
    309    }
    310 }
    311 
    312 #define R16(this) r16(&(this), (sizeof (this))/(sizeof (png_uint_16)))
    313 #define R16_1(this) r16(&(this), (size_t) 1U)
    314 
    315 #if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\
    316     defined PNG_READ_FILLER_SUPPORTED
    317 static void r32(png_uint_32p p32, size_t count)
    318 {
    319    size_t i;
    320 
    321    for (i=0; i<count; ++i)
    322    {
    323       unsigned char b4[4];
    324       randomize(b4, sizeof b4);
    325       *p32++ = png_get_uint_32(b4);
    326    }
    327 }
    328 
    329 #define R32(this) r32(&(this), (sizeof (this))/(sizeof (png_uint_32)))
    330 #define R32_1(this) r32(&(this), (size_t) 1U)
    331 
    332 #endif /* READ_FILLER || READ_RGB_TO_GRAY */
    333 
    334 #endif /* READ || WRITE_tRNS || WRITE_FILTER */
    335 
    336 #if defined PNG_READ_TRANSFORMS_SUPPORTED ||\
    337     defined PNG_WRITE_FILTER_SUPPORTED
    338 static unsigned int
    339 random_mod(unsigned int max)
    340 {
    341    png_uint_16 x;
    342 
    343    R16_1(x);
    344 
    345    return x % max; /* 0 .. max-1 */
    346 }
    347 #endif /* READ_TRANSFORMS || WRITE_FILTER */
    348 
    349 #if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\
    350     (defined PNG_READ_FILLER_SUPPORTED)
    351 static int
    352 random_choice(void)
    353 {
    354    unsigned char x;
    355 
    356    R8(x);
    357 
    358    return x & 1;
    359 }
    360 #endif /* READ_RGB_TO_GRAY || READ_FILLER */
    361 
    362 /* A numeric ID based on PNG file characteristics.  The 'do_interlace' field
    363  * simply records whether pngvalid did the interlace itself or whether it
    364  * was done by libpng.  Width and height must be less than 256.  'palette' is an
    365  * index of the palette to use for formats with a palette otherwise a boolean
    366  * indicating if a tRNS chunk was generated.
    367  */
    368 #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \
    369    ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \
    370     (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24)))
    371 
    372 #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U))
    373 #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU))
    374 #define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f)
    375 #define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3))
    376 #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1))
    377 #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff)
    378 #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff)
    379 
    380 /* Utility to construct a standard name for a standard image. */
    381 static size_t
    382 standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type,
    383     int bit_depth, unsigned int npalette, int interlace_type,
    384     png_uint_32 w, png_uint_32 h, int do_interlace)
    385 {
    386    pos = safecat(buffer, bufsize, pos, colour_types[colour_type]);
    387    if (colour_type == 3) /* must have a palette */
    388    {
    389       pos = safecat(buffer, bufsize, pos, "[");
    390       pos = safecatn(buffer, bufsize, pos, npalette);
    391       pos = safecat(buffer, bufsize, pos, "]");
    392    }
    393 
    394    else if (npalette != 0)
    395       pos = safecat(buffer, bufsize, pos, "+tRNS");
    396 
    397    pos = safecat(buffer, bufsize, pos, " ");
    398    pos = safecatn(buffer, bufsize, pos, bit_depth);
    399    pos = safecat(buffer, bufsize, pos, " bit");
    400 
    401    if (interlace_type != PNG_INTERLACE_NONE)
    402    {
    403       pos = safecat(buffer, bufsize, pos, " interlaced");
    404       if (do_interlace)
    405          pos = safecat(buffer, bufsize, pos, "(pngvalid)");
    406       else
    407          pos = safecat(buffer, bufsize, pos, "(libpng)");
    408    }
    409 
    410    if (w > 0 || h > 0)
    411    {
    412       pos = safecat(buffer, bufsize, pos, " ");
    413       pos = safecatn(buffer, bufsize, pos, w);
    414       pos = safecat(buffer, bufsize, pos, "x");
    415       pos = safecatn(buffer, bufsize, pos, h);
    416    }
    417 
    418    return pos;
    419 }
    420 
    421 static size_t
    422 standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id)
    423 {
    424    return standard_name(buffer, bufsize, pos, COL_FROM_ID(id),
    425       DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id),
    426       WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id));
    427 }
    428 
    429 /* Convenience API and defines to list valid formats.  Note that 16 bit read and
    430  * write support is required to do 16 bit read tests (we must be able to make a
    431  * 16 bit image to test!)
    432  */
    433 #ifdef PNG_WRITE_16BIT_SUPPORTED
    434 #  define WRITE_BDHI 4
    435 #  ifdef PNG_READ_16BIT_SUPPORTED
    436 #     define READ_BDHI 4
    437 #     define DO_16BIT
    438 #  endif
    439 #else
    440 #  define WRITE_BDHI 3
    441 #endif
    442 #ifndef DO_16BIT
    443 #  define READ_BDHI 3
    444 #endif
    445 
    446 /* The following defines the number of different palettes to generate for
    447  * each log bit depth of a colour type 3 standard image.
    448  */
    449 #define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U)
    450 
    451 static int
    452 next_format(png_bytep colour_type, png_bytep bit_depth,
    453    unsigned int* palette_number, int low_depth_gray, int tRNS)
    454 {
    455    if (*bit_depth == 0)
    456    {
    457       *colour_type = 0;
    458       if (low_depth_gray)
    459          *bit_depth = 1;
    460       else
    461          *bit_depth = 8;
    462       *palette_number = 0;
    463       return 1;
    464    }
    465 
    466    if  (*colour_type < 4/*no alpha channel*/)
    467    {
    468       /* Add multiple palettes for colour type 3, one image with tRNS
    469        * and one without for other non-alpha formats:
    470        */
    471       unsigned int pn = ++*palette_number;
    472       png_byte ct = *colour_type;
    473 
    474       if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) ||
    475           (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth)))
    476          return 1;
    477 
    478       /* No: next bit depth */
    479       *palette_number = 0;
    480    }
    481 
    482    *bit_depth = (png_byte)(*bit_depth << 1);
    483 
    484    /* Palette images are restricted to 8 bit depth */
    485    if (*bit_depth <= 8
    486 #ifdef DO_16BIT
    487          || (*colour_type != 3 && *bit_depth <= 16)
    488 #endif
    489       )
    490       return 1;
    491 
    492    /* Move to the next color type, or return 0 at the end. */
    493    switch (*colour_type)
    494    {
    495       case 0:
    496          *colour_type = 2;
    497          *bit_depth = 8;
    498          return 1;
    499 
    500       case 2:
    501          *colour_type = 3;
    502          *bit_depth = 1;
    503          return 1;
    504 
    505       case 3:
    506          *colour_type = 4;
    507          *bit_depth = 8;
    508          return 1;
    509 
    510       case 4:
    511          *colour_type = 6;
    512          *bit_depth = 8;
    513          return 1;
    514 
    515       default:
    516          return 0;
    517    }
    518 }
    519 
    520 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    521 static unsigned int
    522 sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth,
    523     png_uint_32 x, unsigned int sample_index, int swap16, int littleendian)
    524 {
    525    png_uint_32 bit_index, result;
    526 
    527    /* Find a sample index for the desired sample: */
    528    x *= bit_depth;
    529    bit_index = x;
    530 
    531    if ((colour_type & 1) == 0) /* !palette */
    532    {
    533       if (colour_type & 2)
    534          bit_index *= 3;
    535 
    536       if (colour_type & 4)
    537          bit_index += x; /* Alpha channel */
    538 
    539       /* Multiple channels; select one: */
    540       if (colour_type & (2+4))
    541          bit_index += sample_index * bit_depth;
    542    }
    543 
    544    /* Return the sample from the row as an integer. */
    545    row += bit_index >> 3;
    546    result = *row;
    547 
    548    if (bit_depth == 8)
    549       return result;
    550 
    551    else if (bit_depth > 8)
    552    {
    553       if (swap16)
    554          return (*++row << 8) + result;
    555       else
    556          return (result << 8) + *++row;
    557    }
    558 
    559    /* Less than 8 bits per sample.  By default PNG has the big end of
    560     * the egg on the left of the screen, but if littleendian is set
    561     * then the big end is on the right.
    562     */
    563    bit_index &= 7;
    564 
    565    if (!littleendian)
    566       bit_index = 8-bit_index-bit_depth;
    567 
    568    return (result >> bit_index) & ((1U<<bit_depth)-1);
    569 }
    570 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
    571 
    572 /* Copy a single pixel, of a given size, from one buffer to another -
    573  * while this is basically bit addressed there is an implicit assumption
    574  * that pixels 8 or more bits in size are byte aligned and that pixels
    575  * do not otherwise cross byte boundaries.  (This is, so far as I know,
    576  * universally true in bitmap computer graphics.  [JCB 20101212])
    577  *
    578  * NOTE: The to and from buffers may be the same.
    579  */
    580 static void
    581 pixel_copy(png_bytep toBuffer, png_uint_32 toIndex,
    582    png_const_bytep fromBuffer, png_uint_32 fromIndex, unsigned int pixelSize,
    583    int littleendian)
    584 {
    585    /* Assume we can multiply by 'size' without overflow because we are
    586     * just working in a single buffer.
    587     */
    588    toIndex *= pixelSize;
    589    fromIndex *= pixelSize;
    590    if (pixelSize < 8) /* Sub-byte */
    591    {
    592       /* Mask to select the location of the copied pixel: */
    593       unsigned int destMask = ((1U<<pixelSize)-1) <<
    594          (littleendian ? toIndex&7 : 8-pixelSize-(toIndex&7));
    595       /* The following read the entire pixels and clears the extra: */
    596       unsigned int destByte = toBuffer[toIndex >> 3] & ~destMask;
    597       unsigned int sourceByte = fromBuffer[fromIndex >> 3];
    598 
    599       /* Don't rely on << or >> supporting '0' here, just in case: */
    600       fromIndex &= 7;
    601       if (littleendian)
    602       {
    603          if (fromIndex > 0) sourceByte >>= fromIndex;
    604          if ((toIndex & 7) > 0) sourceByte <<= toIndex & 7;
    605       }
    606 
    607       else
    608       {
    609          if (fromIndex > 0) sourceByte <<= fromIndex;
    610          if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7;
    611       }
    612 
    613       toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask));
    614    }
    615    else /* One or more bytes */
    616       memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3);
    617 }
    618 
    619 #ifdef PNG_READ_SUPPORTED
    620 /* Copy a complete row of pixels, taking into account potential partial
    621  * bytes at the end.
    622  */
    623 static void
    624 row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth,
    625       int littleendian)
    626 {
    627    memcpy(toBuffer, fromBuffer, bitWidth >> 3);
    628 
    629    if ((bitWidth & 7) != 0)
    630    {
    631       unsigned int mask;
    632 
    633       toBuffer += bitWidth >> 3;
    634       fromBuffer += bitWidth >> 3;
    635       if (littleendian)
    636          mask = 0xff << (bitWidth & 7);
    637       else
    638          mask = 0xff >> (bitWidth & 7);
    639       *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask));
    640    }
    641 }
    642 
    643 /* Compare pixels - they are assumed to start at the first byte in the
    644  * given buffers.
    645  */
    646 static int
    647 pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width)
    648 {
    649 #if PNG_LIBPNG_VER < 10506
    650    if (memcmp(pa, pb, bit_width>>3) == 0)
    651    {
    652       png_uint_32 p;
    653 
    654       if ((bit_width & 7) == 0) return 0;
    655 
    656       /* Ok, any differences? */
    657       p = pa[bit_width >> 3];
    658       p ^= pb[bit_width >> 3];
    659 
    660       if (p == 0) return 0;
    661 
    662       /* There are, but they may not be significant, remove the bits
    663        * after the end (the low order bits in PNG.)
    664        */
    665       bit_width &= 7;
    666       p >>= 8-bit_width;
    667 
    668       if (p == 0) return 0;
    669    }
    670 #else
    671    /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing
    672     * bits too:
    673     */
    674    if (memcmp(pa, pb, (bit_width+7)>>3) == 0)
    675       return 0;
    676 #endif
    677 
    678    /* Return the index of the changed byte. */
    679    {
    680       png_uint_32 where = 0;
    681 
    682       while (pa[where] == pb[where]) ++where;
    683       return 1+where;
    684    }
    685 }
    686 #endif /* PNG_READ_SUPPORTED */
    687 
    688 /*************************** BASIC PNG FILE WRITING ***************************/
    689 /* A png_store takes data from the sequential writer or provides data
    690  * to the sequential reader.  It can also store the result of a PNG
    691  * write for later retrieval.
    692  */
    693 #define STORE_BUFFER_SIZE 500 /* arbitrary */
    694 typedef struct png_store_buffer
    695 {
    696    struct png_store_buffer*  prev;    /* NOTE: stored in reverse order */
    697    png_byte                  buffer[STORE_BUFFER_SIZE];
    698 } png_store_buffer;
    699 
    700 #define FILE_NAME_SIZE 64
    701 
    702 typedef struct store_palette_entry /* record of a single palette entry */
    703 {
    704    png_byte red;
    705    png_byte green;
    706    png_byte blue;
    707    png_byte alpha;
    708 } store_palette_entry, store_palette[256];
    709 
    710 typedef struct png_store_file
    711 {
    712    struct png_store_file*  next;      /* as many as you like... */
    713    char                    name[FILE_NAME_SIZE];
    714    png_uint_32             id;        /* must be correct (see FILEID) */
    715    png_size_t              datacount; /* In this (the last) buffer */
    716    png_store_buffer        data;      /* Last buffer in file */
    717    int                     npalette;  /* Number of entries in palette */
    718    store_palette_entry*    palette;   /* May be NULL */
    719 } png_store_file;
    720 
    721 /* The following is a pool of memory allocated by a single libpng read or write
    722  * operation.
    723  */
    724 typedef struct store_pool
    725 {
    726    struct png_store    *store;   /* Back pointer */
    727    struct store_memory *list;    /* List of allocated memory */
    728    png_byte             mark[4]; /* Before and after data */
    729 
    730    /* Statistics for this run. */
    731    png_alloc_size_t     max;     /* Maximum single allocation */
    732    png_alloc_size_t     current; /* Current allocation */
    733    png_alloc_size_t     limit;   /* Highest current allocation */
    734    png_alloc_size_t     total;   /* Total allocation */
    735 
    736    /* Overall statistics (retained across successive runs). */
    737    png_alloc_size_t     max_max;
    738    png_alloc_size_t     max_limit;
    739    png_alloc_size_t     max_total;
    740 } store_pool;
    741 
    742 typedef struct png_store
    743 {
    744    /* For cexcept.h exception handling - simply store one of these;
    745     * the context is a self pointer but it may point to a different
    746     * png_store (in fact it never does in this program.)
    747     */
    748    struct exception_context
    749                       exception_context;
    750 
    751    unsigned int       verbose :1;
    752    unsigned int       treat_warnings_as_errors :1;
    753    unsigned int       expect_error :1;
    754    unsigned int       expect_warning :1;
    755    unsigned int       saw_warning :1;
    756    unsigned int       speed :1;
    757    unsigned int       progressive :1; /* use progressive read */
    758    unsigned int       validated :1;   /* used as a temporary flag */
    759    int                nerrors;
    760    int                nwarnings;
    761    int                noptions;       /* number of options below: */
    762    struct {
    763       unsigned char   option;         /* option number, 0..30 */
    764       unsigned char   setting;        /* setting (unset,invalid,on,off) */
    765    }                  options[16];
    766    char               test[128];      /* Name of test */
    767    char               error[256];
    768 
    769    /* Read fields */
    770    png_structp        pread;    /* Used to read a saved file */
    771    png_infop          piread;
    772    png_store_file*    current;  /* Set when reading */
    773    png_store_buffer*  next;     /* Set when reading */
    774    png_size_t         readpos;  /* Position in *next */
    775    png_byte*          image;    /* Buffer for reading interlaced images */
    776    png_size_t         cb_image; /* Size of this buffer */
    777    png_size_t         cb_row;   /* Row size of the image(s) */
    778    png_uint_32        image_h;  /* Number of rows in a single image */
    779    store_pool         read_memory_pool;
    780 
    781    /* Write fields */
    782    png_store_file*    saved;
    783    png_structp        pwrite;   /* Used when writing a new file */
    784    png_infop          piwrite;
    785    png_size_t         writepos; /* Position in .new */
    786    char               wname[FILE_NAME_SIZE];
    787    png_store_buffer   new;      /* The end of the new PNG file being written. */
    788    store_pool         write_memory_pool;
    789    store_palette_entry* palette;
    790    int                  npalette;
    791 } png_store;
    792 
    793 /* Initialization and cleanup */
    794 static void
    795 store_pool_mark(png_bytep mark)
    796 {
    797    static png_uint_32 store_seed[2] = { 0x12345678, 1};
    798 
    799    make_four_random_bytes(store_seed, mark);
    800 }
    801 
    802 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    803 /* Use this for random 32 bit values; this function makes sure the result is
    804  * non-zero.
    805  */
    806 static png_uint_32
    807 random_32(void)
    808 {
    809 
    810    for (;;)
    811    {
    812       png_byte mark[4];
    813       png_uint_32 result;
    814 
    815       store_pool_mark(mark);
    816       result = png_get_uint_32(mark);
    817 
    818       if (result != 0)
    819          return result;
    820    }
    821 }
    822 #endif /* PNG_READ_SUPPORTED */
    823 
    824 static void
    825 store_pool_init(png_store *ps, store_pool *pool)
    826 {
    827    memset(pool, 0, sizeof *pool);
    828 
    829    pool->store = ps;
    830    pool->list = NULL;
    831    pool->max = pool->current = pool->limit = pool->total = 0;
    832    pool->max_max = pool->max_limit = pool->max_total = 0;
    833    store_pool_mark(pool->mark);
    834 }
    835 
    836 static void
    837 store_init(png_store* ps)
    838 {
    839    memset(ps, 0, sizeof *ps);
    840    init_exception_context(&ps->exception_context);
    841    store_pool_init(ps, &ps->read_memory_pool);
    842    store_pool_init(ps, &ps->write_memory_pool);
    843    ps->verbose = 0;
    844    ps->treat_warnings_as_errors = 0;
    845    ps->expect_error = 0;
    846    ps->expect_warning = 0;
    847    ps->saw_warning = 0;
    848    ps->speed = 0;
    849    ps->progressive = 0;
    850    ps->validated = 0;
    851    ps->nerrors = ps->nwarnings = 0;
    852    ps->pread = NULL;
    853    ps->piread = NULL;
    854    ps->saved = ps->current = NULL;
    855    ps->next = NULL;
    856    ps->readpos = 0;
    857    ps->image = NULL;
    858    ps->cb_image = 0;
    859    ps->cb_row = 0;
    860    ps->image_h = 0;
    861    ps->pwrite = NULL;
    862    ps->piwrite = NULL;
    863    ps->writepos = 0;
    864    ps->new.prev = NULL;
    865    ps->palette = NULL;
    866    ps->npalette = 0;
    867    ps->noptions = 0;
    868 }
    869 
    870 static void
    871 store_freebuffer(png_store_buffer* psb)
    872 {
    873    if (psb->prev)
    874    {
    875       store_freebuffer(psb->prev);
    876       free(psb->prev);
    877       psb->prev = NULL;
    878    }
    879 }
    880 
    881 static void
    882 store_freenew(png_store *ps)
    883 {
    884    store_freebuffer(&ps->new);
    885    ps->writepos = 0;
    886    if (ps->palette != NULL)
    887    {
    888       free(ps->palette);
    889       ps->palette = NULL;
    890       ps->npalette = 0;
    891    }
    892 }
    893 
    894 static void
    895 store_storenew(png_store *ps)
    896 {
    897    png_store_buffer *pb;
    898 
    899    if (ps->writepos != STORE_BUFFER_SIZE)
    900       png_error(ps->pwrite, "invalid store call");
    901 
    902    pb = voidcast(png_store_buffer*, malloc(sizeof *pb));
    903 
    904    if (pb == NULL)
    905       png_error(ps->pwrite, "store new: OOM");
    906 
    907    *pb = ps->new;
    908    ps->new.prev = pb;
    909    ps->writepos = 0;
    910 }
    911 
    912 static void
    913 store_freefile(png_store_file **ppf)
    914 {
    915    if (*ppf != NULL)
    916    {
    917       store_freefile(&(*ppf)->next);
    918 
    919       store_freebuffer(&(*ppf)->data);
    920       (*ppf)->datacount = 0;
    921       if ((*ppf)->palette != NULL)
    922       {
    923          free((*ppf)->palette);
    924          (*ppf)->palette = NULL;
    925          (*ppf)->npalette = 0;
    926       }
    927       free(*ppf);
    928       *ppf = NULL;
    929    }
    930 }
    931 
    932 /* Main interface to file storeage, after writing a new PNG file (see the API
    933  * below) call store_storefile to store the result with the given name and id.
    934  */
    935 static void
    936 store_storefile(png_store *ps, png_uint_32 id)
    937 {
    938    png_store_file *pf = voidcast(png_store_file*, malloc(sizeof *pf));
    939    if (pf == NULL)
    940       png_error(ps->pwrite, "storefile: OOM");
    941    safecat(pf->name, sizeof pf->name, 0, ps->wname);
    942    pf->id = id;
    943    pf->data = ps->new;
    944    pf->datacount = ps->writepos;
    945    ps->new.prev = NULL;
    946    ps->writepos = 0;
    947    pf->palette = ps->palette;
    948    pf->npalette = ps->npalette;
    949    ps->palette = 0;
    950    ps->npalette = 0;
    951 
    952    /* And save it. */
    953    pf->next = ps->saved;
    954    ps->saved = pf;
    955 }
    956 
    957 /* Generate an error message (in the given buffer) */
    958 static size_t
    959 store_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize,
    960    size_t pos, const char *msg)
    961 {
    962    if (pp != NULL && pp == ps->pread)
    963    {
    964       /* Reading a file */
    965       pos = safecat(buffer, bufsize, pos, "read: ");
    966 
    967       if (ps->current != NULL)
    968       {
    969          pos = safecat(buffer, bufsize, pos, ps->current->name);
    970          pos = safecat(buffer, bufsize, pos, sep);
    971       }
    972    }
    973 
    974    else if (pp != NULL && pp == ps->pwrite)
    975    {
    976       /* Writing a file */
    977       pos = safecat(buffer, bufsize, pos, "write: ");
    978       pos = safecat(buffer, bufsize, pos, ps->wname);
    979       pos = safecat(buffer, bufsize, pos, sep);
    980    }
    981 
    982    else
    983    {
    984       /* Neither reading nor writing (or a memory error in struct delete) */
    985       pos = safecat(buffer, bufsize, pos, "pngvalid: ");
    986    }
    987 
    988    if (ps->test[0] != 0)
    989    {
    990       pos = safecat(buffer, bufsize, pos, ps->test);
    991       pos = safecat(buffer, bufsize, pos, sep);
    992    }
    993    pos = safecat(buffer, bufsize, pos, msg);
    994    return pos;
    995 }
    996 
    997 /* Verbose output to the error stream: */
    998 static void
    999 store_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix,
   1000    png_const_charp message)
   1001 {
   1002    char buffer[512];
   1003 
   1004    if (prefix)
   1005       fputs(prefix, stderr);
   1006 
   1007    (void)store_message(ps, pp, buffer, sizeof buffer, 0, message);
   1008    fputs(buffer, stderr);
   1009    fputc('\n', stderr);
   1010 }
   1011 
   1012 /* Log an error or warning - the relevant count is always incremented. */
   1013 static void
   1014 store_log(png_store* ps, png_const_structp pp, png_const_charp message,
   1015    int is_error)
   1016 {
   1017    /* The warning is copied to the error buffer if there are no errors and it is
   1018     * the first warning.  The error is copied to the error buffer if it is the
   1019     * first error (overwriting any prior warnings).
   1020     */
   1021    if (is_error ? (ps->nerrors)++ == 0 :
   1022        (ps->nwarnings)++ == 0 && ps->nerrors == 0)
   1023       store_message(ps, pp, ps->error, sizeof ps->error, 0, message);
   1024 
   1025    if (ps->verbose)
   1026       store_verbose(ps, pp, is_error ? "error: " : "warning: ", message);
   1027 }
   1028 
   1029 #ifdef PNG_READ_SUPPORTED
   1030 /* Internal error function, called with a png_store but no libpng stuff. */
   1031 static void
   1032 internal_error(png_store *ps, png_const_charp message)
   1033 {
   1034    store_log(ps, NULL, message, 1 /* error */);
   1035 
   1036    /* And finally throw an exception. */
   1037    {
   1038       struct exception_context *the_exception_context = &ps->exception_context;
   1039       Throw ps;
   1040    }
   1041 }
   1042 #endif /* PNG_READ_SUPPORTED */
   1043 
   1044 /* Functions to use as PNG callbacks. */
   1045 static void PNGCBAPI
   1046 store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */
   1047 {
   1048    png_const_structp pp = ppIn;
   1049    png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
   1050 
   1051    if (!ps->expect_error)
   1052       store_log(ps, pp, message, 1 /* error */);
   1053 
   1054    /* And finally throw an exception. */
   1055    {
   1056       struct exception_context *the_exception_context = &ps->exception_context;
   1057       Throw ps;
   1058    }
   1059 }
   1060 
   1061 static void PNGCBAPI
   1062 store_warning(png_structp ppIn, png_const_charp message)
   1063 {
   1064    png_const_structp pp = ppIn;
   1065    png_store *ps = voidcast(png_store*, png_get_error_ptr(pp));
   1066 
   1067    if (!ps->expect_warning)
   1068       store_log(ps, pp, message, 0 /* warning */);
   1069    else
   1070       ps->saw_warning = 1;
   1071 }
   1072 
   1073 /* These somewhat odd functions are used when reading an image to ensure that
   1074  * the buffer is big enough, the png_structp is for errors.
   1075  */
   1076 /* Return a single row from the correct image. */
   1077 static png_bytep
   1078 store_image_row(const png_store* ps, png_const_structp pp, int nImage,
   1079    png_uint_32 y)
   1080 {
   1081    png_size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2;
   1082 
   1083    if (ps->image == NULL)
   1084       png_error(pp, "no allocated image");
   1085 
   1086    if (coffset + ps->cb_row + 3 > ps->cb_image)
   1087       png_error(pp, "image too small");
   1088 
   1089    return ps->image + coffset;
   1090 }
   1091 
   1092 static void
   1093 store_image_free(png_store *ps, png_const_structp pp)
   1094 {
   1095    if (ps->image != NULL)
   1096    {
   1097       png_bytep image = ps->image;
   1098 
   1099       if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
   1100       {
   1101          if (pp != NULL)
   1102             png_error(pp, "png_store image overwrite (1)");
   1103          else
   1104             store_log(ps, NULL, "png_store image overwrite (2)", 1);
   1105       }
   1106 
   1107       ps->image = NULL;
   1108       ps->cb_image = 0;
   1109       --image;
   1110       free(image);
   1111    }
   1112 }
   1113 
   1114 static void
   1115 store_ensure_image(png_store *ps, png_const_structp pp, int nImages,
   1116    png_size_t cbRow, png_uint_32 cRows)
   1117 {
   1118    png_size_t cb = nImages * cRows * (cbRow + 5);
   1119 
   1120    if (ps->cb_image < cb)
   1121    {
   1122       png_bytep image;
   1123 
   1124       store_image_free(ps, pp);
   1125 
   1126       /* The buffer is deliberately mis-aligned. */
   1127       image = voidcast(png_bytep, malloc(cb+2));
   1128       if (image == NULL)
   1129       {
   1130          /* Called from the startup - ignore the error for the moment. */
   1131          if (pp == NULL)
   1132             return;
   1133 
   1134          png_error(pp, "OOM allocating image buffer");
   1135       }
   1136 
   1137       /* These magic tags are used to detect overwrites above. */
   1138       ++image;
   1139       image[-1] = 0xed;
   1140       image[cb] = 0xfe;
   1141 
   1142       ps->image = image;
   1143       ps->cb_image = cb;
   1144    }
   1145 
   1146    /* We have an adequate sized image; lay out the rows.  There are 2 bytes at
   1147     * the start and three at the end of each (this ensures that the row
   1148     * alignment starts out odd - 2+1 and changes for larger images on each row.)
   1149     */
   1150    ps->cb_row = cbRow;
   1151    ps->image_h = cRows;
   1152 
   1153    /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178).
   1154     * This deliberately doesn't match the bits in the size test image which are
   1155     * outside the image; these are set to 0xff (all 1).  To make the row
   1156     * comparison work in the 'size' test case the size rows are pre-initialized
   1157     * to the same value prior to calling 'standard_row'.
   1158     */
   1159    memset(ps->image, 178, cb);
   1160 
   1161    /* Then put in the marks. */
   1162    while (--nImages >= 0)
   1163    {
   1164       png_uint_32 y;
   1165 
   1166       for (y=0; y<cRows; ++y)
   1167       {
   1168          png_bytep row = store_image_row(ps, pp, nImages, y);
   1169 
   1170          /* The markers: */
   1171          row[-2] = 190;
   1172          row[-1] = 239;
   1173          row[cbRow] = 222;
   1174          row[cbRow+1] = 173;
   1175          row[cbRow+2] = 17;
   1176       }
   1177    }
   1178 }
   1179 
   1180 #ifdef PNG_READ_SUPPORTED
   1181 static void
   1182 store_image_check(const png_store* ps, png_const_structp pp, int iImage)
   1183 {
   1184    png_const_bytep image = ps->image;
   1185 
   1186    if (image[-1] != 0xed || image[ps->cb_image] != 0xfe)
   1187       png_error(pp, "image overwrite");
   1188    else
   1189    {
   1190       png_size_t cbRow = ps->cb_row;
   1191       png_uint_32 rows = ps->image_h;
   1192 
   1193       image += iImage * (cbRow+5) * ps->image_h;
   1194 
   1195       image += 2; /* skip image first row markers */
   1196 
   1197       while (rows-- > 0)
   1198       {
   1199          if (image[-2] != 190 || image[-1] != 239)
   1200             png_error(pp, "row start overwritten");
   1201 
   1202          if (image[cbRow] != 222 || image[cbRow+1] != 173 ||
   1203             image[cbRow+2] != 17)
   1204             png_error(pp, "row end overwritten");
   1205 
   1206          image += cbRow+5;
   1207       }
   1208    }
   1209 }
   1210 #endif /* PNG_READ_SUPPORTED */
   1211 
   1212 static void PNGCBAPI
   1213 store_write(png_structp ppIn, png_bytep pb, png_size_t st)
   1214 {
   1215    png_const_structp pp = ppIn;
   1216    png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
   1217 
   1218    if (ps->pwrite != pp)
   1219       png_error(pp, "store state damaged");
   1220 
   1221    while (st > 0)
   1222    {
   1223       size_t cb;
   1224 
   1225       if (ps->writepos >= STORE_BUFFER_SIZE)
   1226          store_storenew(ps);
   1227 
   1228       cb = st;
   1229 
   1230       if (cb > STORE_BUFFER_SIZE - ps->writepos)
   1231          cb = STORE_BUFFER_SIZE - ps->writepos;
   1232 
   1233       memcpy(ps->new.buffer + ps->writepos, pb, cb);
   1234       pb += cb;
   1235       st -= cb;
   1236       ps->writepos += cb;
   1237    }
   1238 }
   1239 
   1240 static void PNGCBAPI
   1241 store_flush(png_structp ppIn)
   1242 {
   1243    UNUSED(ppIn) /*DOES NOTHING*/
   1244 }
   1245 
   1246 #ifdef PNG_READ_SUPPORTED
   1247 static size_t
   1248 store_read_buffer_size(png_store *ps)
   1249 {
   1250    /* Return the bytes available for read in the current buffer. */
   1251    if (ps->next != &ps->current->data)
   1252       return STORE_BUFFER_SIZE;
   1253 
   1254    return ps->current->datacount;
   1255 }
   1256 
   1257 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   1258 /* Return total bytes available for read. */
   1259 static size_t
   1260 store_read_buffer_avail(png_store *ps)
   1261 {
   1262    if (ps->current != NULL && ps->next != NULL)
   1263    {
   1264       png_store_buffer *next = &ps->current->data;
   1265       size_t cbAvail = ps->current->datacount;
   1266 
   1267       while (next != ps->next && next != NULL)
   1268       {
   1269          next = next->prev;
   1270          cbAvail += STORE_BUFFER_SIZE;
   1271       }
   1272 
   1273       if (next != ps->next)
   1274          png_error(ps->pread, "buffer read error");
   1275 
   1276       if (cbAvail > ps->readpos)
   1277          return cbAvail - ps->readpos;
   1278    }
   1279 
   1280    return 0;
   1281 }
   1282 #endif
   1283 
   1284 static int
   1285 store_read_buffer_next(png_store *ps)
   1286 {
   1287    png_store_buffer *pbOld = ps->next;
   1288    png_store_buffer *pbNew = &ps->current->data;
   1289    if (pbOld != pbNew)
   1290    {
   1291       while (pbNew != NULL && pbNew->prev != pbOld)
   1292          pbNew = pbNew->prev;
   1293 
   1294       if (pbNew != NULL)
   1295       {
   1296          ps->next = pbNew;
   1297          ps->readpos = 0;
   1298          return 1;
   1299       }
   1300 
   1301       png_error(ps->pread, "buffer lost");
   1302    }
   1303 
   1304    return 0; /* EOF or error */
   1305 }
   1306 
   1307 /* Need separate implementation and callback to allow use of the same code
   1308  * during progressive read, where the io_ptr is set internally by libpng.
   1309  */
   1310 static void
   1311 store_read_imp(png_store *ps, png_bytep pb, png_size_t st)
   1312 {
   1313    if (ps->current == NULL || ps->next == NULL)
   1314       png_error(ps->pread, "store state damaged");
   1315 
   1316    while (st > 0)
   1317    {
   1318       size_t cbAvail = store_read_buffer_size(ps) - ps->readpos;
   1319 
   1320       if (cbAvail > 0)
   1321       {
   1322          if (cbAvail > st) cbAvail = st;
   1323          memcpy(pb, ps->next->buffer + ps->readpos, cbAvail);
   1324          st -= cbAvail;
   1325          pb += cbAvail;
   1326          ps->readpos += cbAvail;
   1327       }
   1328 
   1329       else if (!store_read_buffer_next(ps))
   1330          png_error(ps->pread, "read beyond end of file");
   1331    }
   1332 }
   1333 
   1334 static void PNGCBAPI
   1335 store_read(png_structp ppIn, png_bytep pb, png_size_t st)
   1336 {
   1337    png_const_structp pp = ppIn;
   1338    png_store *ps = voidcast(png_store*, png_get_io_ptr(pp));
   1339 
   1340    if (ps == NULL || ps->pread != pp)
   1341       png_error(pp, "bad store read call");
   1342 
   1343    store_read_imp(ps, pb, st);
   1344 }
   1345 
   1346 static void
   1347 store_progressive_read(png_store *ps, png_structp pp, png_infop pi)
   1348 {
   1349    /* Notice that a call to store_read will cause this function to fail because
   1350     * readpos will be set.
   1351     */
   1352    if (ps->pread != pp || ps->current == NULL || ps->next == NULL)
   1353       png_error(pp, "store state damaged (progressive)");
   1354 
   1355    do
   1356    {
   1357       if (ps->readpos != 0)
   1358          png_error(pp, "store_read called during progressive read");
   1359 
   1360       png_process_data(pp, pi, ps->next->buffer, store_read_buffer_size(ps));
   1361    }
   1362    while (store_read_buffer_next(ps));
   1363 }
   1364 #endif /* PNG_READ_SUPPORTED */
   1365 
   1366 /* The caller must fill this in: */
   1367 static store_palette_entry *
   1368 store_write_palette(png_store *ps, int npalette)
   1369 {
   1370    if (ps->pwrite == NULL)
   1371       store_log(ps, NULL, "attempt to write palette without write stream", 1);
   1372 
   1373    if (ps->palette != NULL)
   1374       png_error(ps->pwrite, "multiple store_write_palette calls");
   1375 
   1376    /* This function can only return NULL if called with '0'! */
   1377    if (npalette > 0)
   1378    {
   1379       ps->palette = voidcast(store_palette_entry*, malloc(npalette *
   1380          sizeof *ps->palette));
   1381 
   1382       if (ps->palette == NULL)
   1383          png_error(ps->pwrite, "store new palette: OOM");
   1384 
   1385       ps->npalette = npalette;
   1386    }
   1387 
   1388    return ps->palette;
   1389 }
   1390 
   1391 #ifdef PNG_READ_SUPPORTED
   1392 static store_palette_entry *
   1393 store_current_palette(png_store *ps, int *npalette)
   1394 {
   1395    /* This is an internal error (the call has been made outside a read
   1396     * operation.)
   1397     */
   1398    if (ps->current == NULL)
   1399    {
   1400       store_log(ps, ps->pread, "no current stream for palette", 1);
   1401       return NULL;
   1402    }
   1403 
   1404    /* The result may be null if there is no palette. */
   1405    *npalette = ps->current->npalette;
   1406    return ps->current->palette;
   1407 }
   1408 #endif /* PNG_READ_SUPPORTED */
   1409 
   1410 /***************************** MEMORY MANAGEMENT*** ***************************/
   1411 #ifdef PNG_USER_MEM_SUPPORTED
   1412 /* A store_memory is simply the header for an allocated block of memory.  The
   1413  * pointer returned to libpng is just after the end of the header block, the
   1414  * allocated memory is followed by a second copy of the 'mark'.
   1415  */
   1416 typedef struct store_memory
   1417 {
   1418    store_pool          *pool;    /* Originating pool */
   1419    struct store_memory *next;    /* Singly linked list */
   1420    png_alloc_size_t     size;    /* Size of memory allocated */
   1421    png_byte             mark[4]; /* ID marker */
   1422 } store_memory;
   1423 
   1424 /* Handle a fatal error in memory allocation.  This calls png_error if the
   1425  * libpng struct is non-NULL, else it outputs a message and returns.  This means
   1426  * that a memory problem while libpng is running will abort (png_error) the
   1427  * handling of particular file while one in cleanup (after the destroy of the
   1428  * struct has returned) will simply keep going and free (or attempt to free)
   1429  * all the memory.
   1430  */
   1431 static void
   1432 store_pool_error(png_store *ps, png_const_structp pp, const char *msg)
   1433 {
   1434    if (pp != NULL)
   1435       png_error(pp, msg);
   1436 
   1437    /* Else we have to do it ourselves.  png_error eventually calls store_log,
   1438     * above.  store_log accepts a NULL png_structp - it just changes what gets
   1439     * output by store_message.
   1440     */
   1441    store_log(ps, pp, msg, 1 /* error */);
   1442 }
   1443 
   1444 static void
   1445 store_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory)
   1446 {
   1447    /* Note that pp may be NULL (see store_pool_delete below), the caller has
   1448     * found 'memory' in pool->list *and* unlinked this entry, so this is a valid
   1449     * pointer (for sure), but the contents may have been trashed.
   1450     */
   1451    if (memory->pool != pool)
   1452       store_pool_error(pool->store, pp, "memory corrupted (pool)");
   1453 
   1454    else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0)
   1455       store_pool_error(pool->store, pp, "memory corrupted (start)");
   1456 
   1457    /* It should be safe to read the size field now. */
   1458    else
   1459    {
   1460       png_alloc_size_t cb = memory->size;
   1461 
   1462       if (cb > pool->max)
   1463          store_pool_error(pool->store, pp, "memory corrupted (size)");
   1464 
   1465       else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark)
   1466          != 0)
   1467          store_pool_error(pool->store, pp, "memory corrupted (end)");
   1468 
   1469       /* Finally give the library a chance to find problems too: */
   1470       else
   1471          {
   1472          pool->current -= cb;
   1473          free(memory);
   1474          }
   1475    }
   1476 }
   1477 
   1478 static void
   1479 store_pool_delete(png_store *ps, store_pool *pool)
   1480 {
   1481    if (pool->list != NULL)
   1482    {
   1483       fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test,
   1484          pool == &ps->read_memory_pool ? "read" : "write",
   1485          pool == &ps->read_memory_pool ? (ps->current != NULL ?
   1486             ps->current->name : "unknown file") : ps->wname);
   1487       ++ps->nerrors;
   1488 
   1489       do
   1490       {
   1491          store_memory *next = pool->list;
   1492          pool->list = next->next;
   1493          next->next = NULL;
   1494 
   1495          fprintf(stderr, "\t%lu bytes @ %p\n",
   1496              (unsigned long)next->size, (const void*)(next+1));
   1497          /* The NULL means this will always return, even if the memory is
   1498           * corrupted.
   1499           */
   1500          store_memory_free(NULL, pool, next);
   1501       }
   1502       while (pool->list != NULL);
   1503    }
   1504 
   1505    /* And reset the other fields too for the next time. */
   1506    if (pool->max > pool->max_max) pool->max_max = pool->max;
   1507    pool->max = 0;
   1508    if (pool->current != 0) /* unexpected internal error */
   1509       fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n",
   1510          ps->test, pool == &ps->read_memory_pool ? "read" : "write",
   1511          pool == &ps->read_memory_pool ? (ps->current != NULL ?
   1512             ps->current->name : "unknown file") : ps->wname);
   1513    pool->current = 0;
   1514 
   1515    if (pool->limit > pool->max_limit)
   1516       pool->max_limit = pool->limit;
   1517 
   1518    pool->limit = 0;
   1519 
   1520    if (pool->total > pool->max_total)
   1521       pool->max_total = pool->total;
   1522 
   1523    pool->total = 0;
   1524 
   1525    /* Get a new mark too. */
   1526    store_pool_mark(pool->mark);
   1527 }
   1528 
   1529 /* The memory callbacks: */
   1530 static png_voidp PNGCBAPI
   1531 store_malloc(png_structp ppIn, png_alloc_size_t cb)
   1532 {
   1533    png_const_structp pp = ppIn;
   1534    store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
   1535    store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) +
   1536       (sizeof pool->mark)));
   1537 
   1538    if (new != NULL)
   1539    {
   1540       if (cb > pool->max)
   1541          pool->max = cb;
   1542 
   1543       pool->current += cb;
   1544 
   1545       if (pool->current > pool->limit)
   1546          pool->limit = pool->current;
   1547 
   1548       pool->total += cb;
   1549 
   1550       new->size = cb;
   1551       memcpy(new->mark, pool->mark, sizeof new->mark);
   1552       memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark);
   1553       new->pool = pool;
   1554       new->next = pool->list;
   1555       pool->list = new;
   1556       ++new;
   1557    }
   1558 
   1559    else
   1560    {
   1561       /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed
   1562        * other than to retrieve the allocation pointer!  libpng calls the
   1563        * store_malloc callback in two basic cases:
   1564        *
   1565        * 1) From png_malloc; png_malloc will do a png_error itself if NULL is
   1566        *    returned.
   1567        * 2) From png_struct or png_info structure creation; png_malloc is
   1568        *    to return so cleanup can be performed.
   1569        *
   1570        * To handle this store_malloc can log a message, but can't do anything
   1571        * else.
   1572        */
   1573       store_log(pool->store, pp, "out of memory", 1 /* is_error */);
   1574    }
   1575 
   1576    return new;
   1577 }
   1578 
   1579 static void PNGCBAPI
   1580 store_free(png_structp ppIn, png_voidp memory)
   1581 {
   1582    png_const_structp pp = ppIn;
   1583    store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp));
   1584    store_memory *this = voidcast(store_memory*, memory), **test;
   1585 
   1586    /* Because libpng calls store_free with a dummy png_struct when deleting
   1587     * png_struct or png_info via png_destroy_struct_2 it is necessary to check
   1588     * the passed in png_structp to ensure it is valid, and not pass it to
   1589     * png_error if it is not.
   1590     */
   1591    if (pp != pool->store->pread && pp != pool->store->pwrite)
   1592       pp = NULL;
   1593 
   1594    /* First check that this 'memory' really is valid memory - it must be in the
   1595     * pool list.  If it is, use the shared memory_free function to free it.
   1596     */
   1597    --this;
   1598    for (test = &pool->list; *test != this; test = &(*test)->next)
   1599    {
   1600       if (*test == NULL)
   1601       {
   1602          store_pool_error(pool->store, pp, "bad pointer to free");
   1603          return;
   1604       }
   1605    }
   1606 
   1607    /* Unlink this entry, *test == this. */
   1608    *test = this->next;
   1609    this->next = NULL;
   1610    store_memory_free(pp, pool, this);
   1611 }
   1612 #endif /* PNG_USER_MEM_SUPPORTED */
   1613 
   1614 /* Setup functions. */
   1615 /* Cleanup when aborting a write or after storing the new file. */
   1616 static void
   1617 store_write_reset(png_store *ps)
   1618 {
   1619    if (ps->pwrite != NULL)
   1620    {
   1621       anon_context(ps);
   1622 
   1623       Try
   1624          png_destroy_write_struct(&ps->pwrite, &ps->piwrite);
   1625 
   1626       Catch_anonymous
   1627       {
   1628          /* memory corruption: continue. */
   1629       }
   1630 
   1631       ps->pwrite = NULL;
   1632       ps->piwrite = NULL;
   1633    }
   1634 
   1635    /* And make sure that all the memory has been freed - this will output
   1636     * spurious errors in the case of memory corruption above, but this is safe.
   1637     */
   1638 #  ifdef PNG_USER_MEM_SUPPORTED
   1639       store_pool_delete(ps, &ps->write_memory_pool);
   1640 #  endif
   1641 
   1642    store_freenew(ps);
   1643 }
   1644 
   1645 /* The following is the main write function, it returns a png_struct and,
   1646  * optionally, a png_info suitable for writiing a new PNG file.  Use
   1647  * store_storefile above to record this file after it has been written.  The
   1648  * returned libpng structures as destroyed by store_write_reset above.
   1649  */
   1650 static png_structp
   1651 set_store_for_write(png_store *ps, png_infopp ppi, const char *name)
   1652 {
   1653    anon_context(ps);
   1654 
   1655    Try
   1656    {
   1657       if (ps->pwrite != NULL)
   1658          png_error(ps->pwrite, "write store already in use");
   1659 
   1660       store_write_reset(ps);
   1661       safecat(ps->wname, sizeof ps->wname, 0, name);
   1662 
   1663       /* Don't do the slow memory checks if doing a speed test, also if user
   1664        * memory is not supported we can't do it anyway.
   1665        */
   1666 #     ifdef PNG_USER_MEM_SUPPORTED
   1667          if (!ps->speed)
   1668             ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING,
   1669                ps, store_error, store_warning, &ps->write_memory_pool,
   1670                store_malloc, store_free);
   1671 
   1672          else
   1673 #     endif
   1674          ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING,
   1675             ps, store_error, store_warning);
   1676 
   1677       png_set_write_fn(ps->pwrite, ps, store_write, store_flush);
   1678 
   1679 #     ifdef PNG_SET_OPTION_SUPPORTED
   1680          {
   1681             int opt;
   1682             for (opt=0; opt<ps->noptions; ++opt)
   1683                if (png_set_option(ps->pwrite, ps->options[opt].option,
   1684                   ps->options[opt].setting) == PNG_OPTION_INVALID)
   1685                   png_error(ps->pwrite, "png option invalid");
   1686          }
   1687 #     endif
   1688 
   1689       if (ppi != NULL)
   1690          *ppi = ps->piwrite = png_create_info_struct(ps->pwrite);
   1691    }
   1692 
   1693    Catch_anonymous
   1694       return NULL;
   1695 
   1696    return ps->pwrite;
   1697 }
   1698 
   1699 /* Cleanup when finished reading (either due to error or in the success case).
   1700  * This routine exists even when there is no read support to make the code
   1701  * tidier (avoid a mass of ifdefs) and so easier to maintain.
   1702  */
   1703 static void
   1704 store_read_reset(png_store *ps)
   1705 {
   1706 #  ifdef PNG_READ_SUPPORTED
   1707       if (ps->pread != NULL)
   1708       {
   1709          anon_context(ps);
   1710 
   1711          Try
   1712             png_destroy_read_struct(&ps->pread, &ps->piread, NULL);
   1713 
   1714          Catch_anonymous
   1715          {
   1716             /* error already output: continue */
   1717          }
   1718 
   1719          ps->pread = NULL;
   1720          ps->piread = NULL;
   1721       }
   1722 #  endif
   1723 
   1724 #  ifdef PNG_USER_MEM_SUPPORTED
   1725       /* Always do this to be safe. */
   1726       store_pool_delete(ps, &ps->read_memory_pool);
   1727 #  endif
   1728 
   1729    ps->current = NULL;
   1730    ps->next = NULL;
   1731    ps->readpos = 0;
   1732    ps->validated = 0;
   1733 }
   1734 
   1735 #ifdef PNG_READ_SUPPORTED
   1736 static void
   1737 store_read_set(png_store *ps, png_uint_32 id)
   1738 {
   1739    png_store_file *pf = ps->saved;
   1740 
   1741    while (pf != NULL)
   1742    {
   1743       if (pf->id == id)
   1744       {
   1745          ps->current = pf;
   1746          ps->next = NULL;
   1747          store_read_buffer_next(ps);
   1748          return;
   1749       }
   1750 
   1751       pf = pf->next;
   1752    }
   1753 
   1754    {
   1755       size_t pos;
   1756       char msg[FILE_NAME_SIZE+64];
   1757 
   1758       pos = standard_name_from_id(msg, sizeof msg, 0, id);
   1759       pos = safecat(msg, sizeof msg, pos, ": file not found");
   1760       png_error(ps->pread, msg);
   1761    }
   1762 }
   1763 
   1764 /* The main interface for reading a saved file - pass the id number of the file
   1765  * to retrieve.  Ids must be unique or the earlier file will be hidden.  The API
   1766  * returns a png_struct and, optionally, a png_info.  Both of these will be
   1767  * destroyed by store_read_reset above.
   1768  */
   1769 static png_structp
   1770 set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id,
   1771    const char *name)
   1772 {
   1773    /* Set the name for png_error */
   1774    safecat(ps->test, sizeof ps->test, 0, name);
   1775 
   1776    if (ps->pread != NULL)
   1777       png_error(ps->pread, "read store already in use");
   1778 
   1779    store_read_reset(ps);
   1780 
   1781    /* Both the create APIs can return NULL if used in their default mode
   1782     * (because there is no other way of handling an error because the jmp_buf
   1783     * by default is stored in png_struct and that has not been allocated!)
   1784     * However, given that store_error works correctly in these circumstances
   1785     * we don't ever expect NULL in this program.
   1786     */
   1787 #  ifdef PNG_USER_MEM_SUPPORTED
   1788       if (!ps->speed)
   1789          ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps,
   1790              store_error, store_warning, &ps->read_memory_pool, store_malloc,
   1791              store_free);
   1792 
   1793       else
   1794 #  endif
   1795    ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error,
   1796       store_warning);
   1797 
   1798    if (ps->pread == NULL)
   1799    {
   1800       struct exception_context *the_exception_context = &ps->exception_context;
   1801 
   1802       store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)",
   1803          1 /*error*/);
   1804 
   1805       Throw ps;
   1806    }
   1807 
   1808 #  ifdef PNG_SET_OPTION_SUPPORTED
   1809       {
   1810          int opt;
   1811          for (opt=0; opt<ps->noptions; ++opt)
   1812             if (png_set_option(ps->pread, ps->options[opt].option,
   1813                ps->options[opt].setting) == PNG_OPTION_INVALID)
   1814                   png_error(ps->pread, "png option invalid");
   1815       }
   1816 #  endif
   1817 
   1818    store_read_set(ps, id);
   1819 
   1820    if (ppi != NULL)
   1821       *ppi = ps->piread = png_create_info_struct(ps->pread);
   1822 
   1823    return ps->pread;
   1824 }
   1825 #endif /* PNG_READ_SUPPORTED */
   1826 
   1827 /* The overall cleanup of a store simply calls the above then removes all the
   1828  * saved files.  This does not delete the store itself.
   1829  */
   1830 static void
   1831 store_delete(png_store *ps)
   1832 {
   1833    store_write_reset(ps);
   1834    store_read_reset(ps);
   1835    store_freefile(&ps->saved);
   1836    store_image_free(ps, NULL);
   1837 }
   1838 
   1839 /*********************** PNG FILE MODIFICATION ON READ ************************/
   1840 /* Files may be modified on read.  The following structure contains a complete
   1841  * png_store together with extra members to handle modification and a special
   1842  * read callback for libpng.  To use this the 'modifications' field must be set
   1843  * to a list of png_modification structures that actually perform the
   1844  * modification, otherwise a png_modifier is functionally equivalent to a
   1845  * png_store.  There is a special read function, set_modifier_for_read, which
   1846  * replaces set_store_for_read.
   1847  */
   1848 typedef enum modifier_state
   1849 {
   1850    modifier_start,                        /* Initial value */
   1851    modifier_signature,                    /* Have a signature */
   1852    modifier_IHDR                          /* Have an IHDR */
   1853 } modifier_state;
   1854 
   1855 typedef struct CIE_color
   1856 {
   1857    /* A single CIE tristimulus value, representing the unique response of a
   1858     * standard observer to a variety of light spectra.  The observer recognizes
   1859     * all spectra that produce this response as the same color, therefore this
   1860     * is effectively a description of a color.
   1861     */
   1862    double X, Y, Z;
   1863 } CIE_color;
   1864 
   1865 typedef struct color_encoding
   1866 {
   1867    /* A description of an (R,G,B) encoding of color (as defined above); this
   1868     * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and
   1869     * (0,0,1) plus an encoding value that is used to encode the linear
   1870     * components R, G and B to give the actual values R^gamma, G^gamma and
   1871     * B^gamma that are stored.
   1872     */
   1873    double    gamma;            /* Encoding (file) gamma of space */
   1874    CIE_color red, green, blue; /* End points */
   1875 } color_encoding;
   1876 
   1877 #ifdef PNG_READ_SUPPORTED
   1878 #if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED
   1879 static double
   1880 chromaticity_x(CIE_color c)
   1881 {
   1882    return c.X / (c.X + c.Y + c.Z);
   1883 }
   1884 
   1885 static double
   1886 chromaticity_y(CIE_color c)
   1887 {
   1888    return c.Y / (c.X + c.Y + c.Z);
   1889 }
   1890 
   1891 static CIE_color
   1892 white_point(const color_encoding *encoding)
   1893 {
   1894    CIE_color white;
   1895 
   1896    white.X = encoding->red.X + encoding->green.X + encoding->blue.X;
   1897    white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y;
   1898    white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z;
   1899 
   1900    return white;
   1901 }
   1902 #endif /* READ_TRANSFORMS && READ_cHRM */
   1903 
   1904 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   1905 static void
   1906 normalize_color_encoding(color_encoding *encoding)
   1907 {
   1908    const double whiteY = encoding->red.Y + encoding->green.Y +
   1909       encoding->blue.Y;
   1910 
   1911    if (whiteY != 1)
   1912    {
   1913       encoding->red.X /= whiteY;
   1914       encoding->red.Y /= whiteY;
   1915       encoding->red.Z /= whiteY;
   1916       encoding->green.X /= whiteY;
   1917       encoding->green.Y /= whiteY;
   1918       encoding->green.Z /= whiteY;
   1919       encoding->blue.X /= whiteY;
   1920       encoding->blue.Y /= whiteY;
   1921       encoding->blue.Z /= whiteY;
   1922    }
   1923 }
   1924 #endif
   1925 
   1926 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   1927 static size_t
   1928 safecat_color_encoding(char *buffer, size_t bufsize, size_t pos,
   1929    const color_encoding *e, double encoding_gamma)
   1930 {
   1931    if (e != 0)
   1932    {
   1933       if (encoding_gamma != 0)
   1934          pos = safecat(buffer, bufsize, pos, "(");
   1935       pos = safecat(buffer, bufsize, pos, "R(");
   1936       pos = safecatd(buffer, bufsize, pos, e->red.X, 4);
   1937       pos = safecat(buffer, bufsize, pos, ",");
   1938       pos = safecatd(buffer, bufsize, pos, e->red.Y, 4);
   1939       pos = safecat(buffer, bufsize, pos, ",");
   1940       pos = safecatd(buffer, bufsize, pos, e->red.Z, 4);
   1941       pos = safecat(buffer, bufsize, pos, "),G(");
   1942       pos = safecatd(buffer, bufsize, pos, e->green.X, 4);
   1943       pos = safecat(buffer, bufsize, pos, ",");
   1944       pos = safecatd(buffer, bufsize, pos, e->green.Y, 4);
   1945       pos = safecat(buffer, bufsize, pos, ",");
   1946       pos = safecatd(buffer, bufsize, pos, e->green.Z, 4);
   1947       pos = safecat(buffer, bufsize, pos, "),B(");
   1948       pos = safecatd(buffer, bufsize, pos, e->blue.X, 4);
   1949       pos = safecat(buffer, bufsize, pos, ",");
   1950       pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4);
   1951       pos = safecat(buffer, bufsize, pos, ",");
   1952       pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4);
   1953       pos = safecat(buffer, bufsize, pos, ")");
   1954       if (encoding_gamma != 0)
   1955          pos = safecat(buffer, bufsize, pos, ")");
   1956    }
   1957 
   1958    if (encoding_gamma != 0)
   1959    {
   1960       pos = safecat(buffer, bufsize, pos, "^");
   1961       pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5);
   1962    }
   1963 
   1964    return pos;
   1965 }
   1966 #endif /* READ_TRANSFORMS */
   1967 #endif /* PNG_READ_SUPPORTED */
   1968 
   1969 typedef struct png_modifier
   1970 {
   1971    png_store               this;             /* I am a png_store */
   1972    struct png_modification *modifications;   /* Changes to make */
   1973 
   1974    modifier_state           state;           /* My state */
   1975 
   1976    /* Information from IHDR: */
   1977    png_byte                 bit_depth;       /* From IHDR */
   1978    png_byte                 colour_type;     /* From IHDR */
   1979 
   1980    /* While handling PLTE, IDAT and IEND these chunks may be pended to allow
   1981     * other chunks to be inserted.
   1982     */
   1983    png_uint_32              pending_len;
   1984    png_uint_32              pending_chunk;
   1985 
   1986    /* Test values */
   1987    double                   *gammas;
   1988    unsigned int              ngammas;
   1989    unsigned int              ngamma_tests;     /* Number of gamma tests to run*/
   1990    double                    current_gamma;    /* 0 if not set */
   1991    const color_encoding *encodings;
   1992    unsigned int              nencodings;
   1993    const color_encoding *current_encoding; /* If an encoding has been set */
   1994    unsigned int              encoding_counter; /* For iteration */
   1995    int                       encoding_ignored; /* Something overwrote it */
   1996 
   1997    /* Control variables used to iterate through possible encodings, the
   1998     * following must be set to 0 and tested by the function that uses the
   1999     * png_modifier because the modifier only sets it to 1 (true.)
   2000     */
   2001    unsigned int              repeat :1;   /* Repeat this transform test. */
   2002    unsigned int              test_uses_encoding :1;
   2003 
   2004    /* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */
   2005    png_byte                 sbitlow;
   2006 
   2007    /* Error control - these are the limits on errors accepted by the gamma tests
   2008     * below.
   2009     */
   2010    double                   maxout8;  /* Maximum output value error */
   2011    double                   maxabs8;  /* Absolute sample error 0..1 */
   2012    double                   maxcalc8; /* Absolute sample error 0..1 */
   2013    double                   maxpc8;   /* Percentage sample error 0..100% */
   2014    double                   maxout16; /* Maximum output value error */
   2015    double                   maxabs16; /* Absolute sample error 0..1 */
   2016    double                   maxcalc16;/* Absolute sample error 0..1 */
   2017    double                   maxcalcG; /* Absolute sample error 0..1 */
   2018    double                   maxpc16;  /* Percentage sample error 0..100% */
   2019 
   2020    /* This is set by transforms that need to allow a higher limit, it is an
   2021     * internal check on pngvalid to ensure that the calculated error limits are
   2022     * not ridiculous; without this it is too easy to make a mistake in pngvalid
   2023     * that allows any value through.
   2024     *
   2025     * NOTE: this is not checked in release builds.
   2026     */
   2027    double                   limit;    /* limit on error values, normally 4E-3 */
   2028 
   2029    /* Log limits - values above this are logged, but not necessarily
   2030     * warned.
   2031     */
   2032    double                   log8;     /* Absolute error in 8 bits to log */
   2033    double                   log16;    /* Absolute error in 16 bits to log */
   2034 
   2035    /* Logged 8 and 16 bit errors ('output' values): */
   2036    double                   error_gray_2;
   2037    double                   error_gray_4;
   2038    double                   error_gray_8;
   2039    double                   error_gray_16;
   2040    double                   error_color_8;
   2041    double                   error_color_16;
   2042    double                   error_indexed;
   2043 
   2044    /* Flags: */
   2045    /* Whether to call png_read_update_info, not png_read_start_image, and how
   2046     * many times to call it.
   2047     */
   2048    int                      use_update_info;
   2049 
   2050    /* Whether or not to interlace. */
   2051    int                      interlace_type :9; /* int, but must store '1' */
   2052 
   2053    /* Run the standard tests? */
   2054    unsigned int             test_standard :1;
   2055 
   2056    /* Run the odd-sized image and interlace read/write tests? */
   2057    unsigned int             test_size :1;
   2058 
   2059    /* Run tests on reading with a combination of transforms, */
   2060    unsigned int             test_transform :1;
   2061    unsigned int             test_tRNS :1; /* Includes tRNS images */
   2062 
   2063    /* When to use the use_input_precision option, this controls the gamma
   2064     * validation code checks.  If set any value that is within the transformed
   2065     * range input-.5 to input+.5 will be accepted, otherwise the value must be
   2066     * within the normal limits.  It should not be necessary to set this; the
   2067     * result should always be exact within the permitted error limits.
   2068     */
   2069    unsigned int             use_input_precision :1;
   2070    unsigned int             use_input_precision_sbit :1;
   2071    unsigned int             use_input_precision_16to8 :1;
   2072 
   2073    /* If set assume that the calculation bit depth is set by the input
   2074     * precision, not the output precision.
   2075     */
   2076    unsigned int             calculations_use_input_precision :1;
   2077 
   2078    /* If set assume that the calculations are done in 16 bits even if the sample
   2079     * depth is 8 bits.
   2080     */
   2081    unsigned int             assume_16_bit_calculations :1;
   2082 
   2083    /* Which gamma tests to run: */
   2084    unsigned int             test_gamma_threshold :1;
   2085    unsigned int             test_gamma_transform :1; /* main tests */
   2086    unsigned int             test_gamma_sbit :1;
   2087    unsigned int             test_gamma_scale16 :1;
   2088    unsigned int             test_gamma_background :1;
   2089    unsigned int             test_gamma_alpha_mode :1;
   2090    unsigned int             test_gamma_expand16 :1;
   2091    unsigned int             test_exhaustive :1;
   2092 
   2093    /* Whether or not to run the low-bit-depth grayscale tests.  This fails on
   2094     * gamma images in some cases because of gross inaccuracies in the grayscale
   2095     * gamma handling for low bit depth.
   2096     */
   2097    unsigned int             test_lbg :1;
   2098    unsigned int             test_lbg_gamma_threshold :1;
   2099    unsigned int             test_lbg_gamma_transform :1;
   2100    unsigned int             test_lbg_gamma_sbit :1;
   2101    unsigned int             test_lbg_gamma_composition :1;
   2102 
   2103    unsigned int             log :1;   /* Log max error */
   2104 
   2105    /* Buffer information, the buffer size limits the size of the chunks that can
   2106     * be modified - they must fit (including header and CRC) into the buffer!
   2107     */
   2108    size_t                   flush;           /* Count of bytes to flush */
   2109    size_t                   buffer_count;    /* Bytes in buffer */
   2110    size_t                   buffer_position; /* Position in buffer */
   2111    png_byte                 buffer[1024];
   2112 } png_modifier;
   2113 
   2114 /* This returns true if the test should be stopped now because it has already
   2115  * failed and it is running silently.
   2116   */
   2117 static int fail(png_modifier *pm)
   2118 {
   2119    return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 ||
   2120        (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0));
   2121 }
   2122 
   2123 static void
   2124 modifier_init(png_modifier *pm)
   2125 {
   2126    memset(pm, 0, sizeof *pm);
   2127    store_init(&pm->this);
   2128    pm->modifications = NULL;
   2129    pm->state = modifier_start;
   2130    pm->sbitlow = 1U;
   2131    pm->ngammas = 0;
   2132    pm->ngamma_tests = 0;
   2133    pm->gammas = 0;
   2134    pm->current_gamma = 0;
   2135    pm->encodings = 0;
   2136    pm->nencodings = 0;
   2137    pm->current_encoding = 0;
   2138    pm->encoding_counter = 0;
   2139    pm->encoding_ignored = 0;
   2140    pm->repeat = 0;
   2141    pm->test_uses_encoding = 0;
   2142    pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0;
   2143    pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0;
   2144    pm->maxcalcG = 0;
   2145    pm->limit = 4E-3;
   2146    pm->log8 = pm->log16 = 0; /* Means 'off' */
   2147    pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0;
   2148    pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0;
   2149    pm->error_indexed = 0;
   2150    pm->use_update_info = 0;
   2151    pm->interlace_type = PNG_INTERLACE_NONE;
   2152    pm->test_standard = 0;
   2153    pm->test_size = 0;
   2154    pm->test_transform = 0;
   2155 #  ifdef PNG_WRITE_tRNS_SUPPORTED
   2156       pm->test_tRNS = 1;
   2157 #  else
   2158       pm->test_tRNS = 0;
   2159 #  endif
   2160    pm->use_input_precision = 0;
   2161    pm->use_input_precision_sbit = 0;
   2162    pm->use_input_precision_16to8 = 0;
   2163    pm->calculations_use_input_precision = 0;
   2164    pm->assume_16_bit_calculations = 0;
   2165    pm->test_gamma_threshold = 0;
   2166    pm->test_gamma_transform = 0;
   2167    pm->test_gamma_sbit = 0;
   2168    pm->test_gamma_scale16 = 0;
   2169    pm->test_gamma_background = 0;
   2170    pm->test_gamma_alpha_mode = 0;
   2171    pm->test_gamma_expand16 = 0;
   2172    pm->test_lbg = 1;
   2173    pm->test_lbg_gamma_threshold = 1;
   2174    pm->test_lbg_gamma_transform = 1;
   2175    pm->test_lbg_gamma_sbit = 1;
   2176    pm->test_lbg_gamma_composition = 1;
   2177    pm->test_exhaustive = 0;
   2178    pm->log = 0;
   2179 
   2180    /* Rely on the memset for all the other fields - there are no pointers */
   2181 }
   2182 
   2183 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   2184 
   2185 /* This controls use of checks that explicitly know how libpng digitizes the
   2186  * samples in calculations; setting this circumvents simple error limit checking
   2187  * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5
   2188  * algorithm.
   2189  */
   2190 #define DIGITIZE PNG_LIBPNG_VER < 10700
   2191 
   2192 /* If pm->calculations_use_input_precision is set then operations will happen
   2193  * with the precision of the input, not the precision of the output depth.
   2194  *
   2195  * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16
   2196  * bit precision.  This only affects those of the following limits that pertain
   2197  * to a calculation - not a digitization operation - unless the following API is
   2198  * called directly.
   2199  */
   2200 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   2201 #if DIGITIZE
   2202 static double digitize(double value, int depth, int do_round)
   2203 {
   2204    /* 'value' is in the range 0 to 1, the result is the same value rounded to a
   2205     * multiple of the digitization factor - 8 or 16 bits depending on both the
   2206     * sample depth and the 'assume' setting.  Digitization is normally by
   2207     * rounding and 'do_round' should be 1, if it is 0 the digitized value will
   2208     * be truncated.
   2209     */
   2210    const unsigned int digitization_factor = (1U << depth) -1;
   2211 
   2212    /* Limiting the range is done as a convenience to the caller - it's easier to
   2213     * do it once here than every time at the call site.
   2214     */
   2215    if (value <= 0)
   2216       value = 0;
   2217 
   2218    else if (value >= 1)
   2219       value = 1;
   2220 
   2221    value *= digitization_factor;
   2222    if (do_round) value += .5;
   2223    return floor(value)/digitization_factor;
   2224 }
   2225 #endif
   2226 #endif /* RGB_TO_GRAY */
   2227 
   2228 #ifdef PNG_READ_GAMMA_SUPPORTED
   2229 static double abserr(const png_modifier *pm, int in_depth, int out_depth)
   2230 {
   2231    /* Absolute error permitted in linear values - affected by the bit depth of
   2232     * the calculations.
   2233     */
   2234    if (pm->assume_16_bit_calculations ||
   2235       (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
   2236       return pm->maxabs16;
   2237    else
   2238       return pm->maxabs8;
   2239 }
   2240 
   2241 static double calcerr(const png_modifier *pm, int in_depth, int out_depth)
   2242 {
   2243    /* Error in the linear composition arithmetic - only relevant when
   2244     * composition actually happens (0 < alpha < 1).
   2245     */
   2246    if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
   2247       return pm->maxcalc16;
   2248    else if (pm->assume_16_bit_calculations)
   2249       return pm->maxcalcG;
   2250    else
   2251       return pm->maxcalc8;
   2252 }
   2253 
   2254 static double pcerr(const png_modifier *pm, int in_depth, int out_depth)
   2255 {
   2256    /* Percentage error permitted in the linear values.  Note that the specified
   2257     * value is a percentage but this routine returns a simple number.
   2258     */
   2259    if (pm->assume_16_bit_calculations ||
   2260       (pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
   2261       return pm->maxpc16 * .01;
   2262    else
   2263       return pm->maxpc8 * .01;
   2264 }
   2265 
   2266 /* Output error - the error in the encoded value.  This is determined by the
   2267  * digitization of the output so can be +/-0.5 in the actual output value.  In
   2268  * the expand_16 case with the current code in libpng the expand happens after
   2269  * all the calculations are done in 8 bit arithmetic, so even though the output
   2270  * depth is 16 the output error is determined by the 8 bit calculation.
   2271  *
   2272  * This limit is not determined by the bit depth of internal calculations.
   2273  *
   2274  * The specified parameter does *not* include the base .5 digitization error but
   2275  * it is added here.
   2276  */
   2277 static double outerr(const png_modifier *pm, int in_depth, int out_depth)
   2278 {
   2279    /* There is a serious error in the 2 and 4 bit grayscale transform because
   2280     * the gamma table value (8 bits) is simply shifted, not rounded, so the
   2281     * error in 4 bit grayscale gamma is up to the value below.  This is a hack
   2282     * to allow pngvalid to succeed:
   2283     *
   2284     * TODO: fix this in libpng
   2285     */
   2286    if (out_depth == 2)
   2287       return .73182-.5;
   2288 
   2289    if (out_depth == 4)
   2290       return .90644-.5;
   2291 
   2292    if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
   2293       return pm->maxout16;
   2294 
   2295    /* This is the case where the value was calculated at 8-bit precision then
   2296     * scaled to 16 bits.
   2297     */
   2298    else if (out_depth == 16)
   2299       return pm->maxout8 * 257;
   2300 
   2301    else
   2302       return pm->maxout8;
   2303 }
   2304 
   2305 /* This does the same thing as the above however it returns the value to log,
   2306  * rather than raising a warning.  This is useful for debugging to track down
   2307  * exactly what set of parameters cause high error values.
   2308  */
   2309 static double outlog(const png_modifier *pm, int in_depth, int out_depth)
   2310 {
   2311    /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535)
   2312     * and so must be adjusted for low bit depth grayscale:
   2313     */
   2314    if (out_depth <= 8)
   2315    {
   2316       if (pm->log8 == 0) /* switched off */
   2317          return 256;
   2318 
   2319       if (out_depth < 8)
   2320          return pm->log8 / 255 * ((1<<out_depth)-1);
   2321 
   2322       return pm->log8;
   2323    }
   2324 
   2325    if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16)
   2326    {
   2327       if (pm->log16 == 0)
   2328          return 65536;
   2329 
   2330       return pm->log16;
   2331    }
   2332 
   2333    /* This is the case where the value was calculated at 8-bit precision then
   2334     * scaled to 16 bits.
   2335     */
   2336    if (pm->log8 == 0)
   2337       return 65536;
   2338 
   2339    return pm->log8 * 257;
   2340 }
   2341 
   2342 /* This complements the above by providing the appropriate quantization for the
   2343  * final value.  Normally this would just be quantization to an integral value,
   2344  * but in the 8 bit calculation case it's actually quantization to a multiple of
   2345  * 257!
   2346  */
   2347 static int output_quantization_factor(const png_modifier *pm, int in_depth,
   2348    int out_depth)
   2349 {
   2350    if (out_depth == 16 && in_depth != 16 &&
   2351       pm->calculations_use_input_precision)
   2352       return 257;
   2353    else
   2354       return 1;
   2355 }
   2356 #endif /* PNG_READ_GAMMA_SUPPORTED */
   2357 
   2358 /* One modification structure must be provided for each chunk to be modified (in
   2359  * fact more than one can be provided if multiple separate changes are desired
   2360  * for a single chunk.)  Modifications include adding a new chunk when a
   2361  * suitable chunk does not exist.
   2362  *
   2363  * The caller of modify_fn will reset the CRC of the chunk and record 'modified'
   2364  * or 'added' as appropriate if the modify_fn returns 1 (true).  If the
   2365  * modify_fn is NULL the chunk is simply removed.
   2366  */
   2367 typedef struct png_modification
   2368 {
   2369    struct png_modification *next;
   2370    png_uint_32              chunk;
   2371 
   2372    /* If the following is NULL all matching chunks will be removed: */
   2373    int                    (*modify_fn)(struct png_modifier *pm,
   2374                                struct png_modification *me, int add);
   2375 
   2376    /* If the following is set to PLTE, IDAT or IEND and the chunk has not been
   2377     * found and modified (and there is a modify_fn) the modify_fn will be called
   2378     * to add the chunk before the relevant chunk.
   2379     */
   2380    png_uint_32              add;
   2381    unsigned int             modified :1;     /* Chunk was modified */
   2382    unsigned int             added    :1;     /* Chunk was added */
   2383    unsigned int             removed  :1;     /* Chunk was removed */
   2384 } png_modification;
   2385 
   2386 static void
   2387 modification_reset(png_modification *pmm)
   2388 {
   2389    if (pmm != NULL)
   2390    {
   2391       pmm->modified = 0;
   2392       pmm->added = 0;
   2393       pmm->removed = 0;
   2394       modification_reset(pmm->next);
   2395    }
   2396 }
   2397 
   2398 static void
   2399 modification_init(png_modification *pmm)
   2400 {
   2401    memset(pmm, 0, sizeof *pmm);
   2402    pmm->next = NULL;
   2403    pmm->chunk = 0;
   2404    pmm->modify_fn = NULL;
   2405    pmm->add = 0;
   2406    modification_reset(pmm);
   2407 }
   2408 
   2409 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   2410 static void
   2411 modifier_current_encoding(const png_modifier *pm, color_encoding *ce)
   2412 {
   2413    if (pm->current_encoding != 0)
   2414       *ce = *pm->current_encoding;
   2415 
   2416    else
   2417       memset(ce, 0, sizeof *ce);
   2418 
   2419    ce->gamma = pm->current_gamma;
   2420 }
   2421 #endif
   2422 
   2423 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   2424 static size_t
   2425 safecat_current_encoding(char *buffer, size_t bufsize, size_t pos,
   2426    const png_modifier *pm)
   2427 {
   2428    pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding,
   2429       pm->current_gamma);
   2430 
   2431    if (pm->encoding_ignored)
   2432       pos = safecat(buffer, bufsize, pos, "[overridden]");
   2433 
   2434    return pos;
   2435 }
   2436 #endif
   2437 
   2438 /* Iterate through the usefully testable color encodings.  An encoding is one
   2439  * of:
   2440  *
   2441  * 1) Nothing (no color space, no gamma).
   2442  * 2) Just a gamma value from the gamma array (including 1.0)
   2443  * 3) A color space from the encodings array with the corresponding gamma.
   2444  * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations)
   2445  *
   2446  * The iterator selects these in turn, the randomizer selects one at random,
   2447  * which is used depends on the setting of the 'test_exhaustive' flag.  Notice
   2448  * that this function changes the colour space encoding so it must only be
   2449  * called on completion of the previous test.  This is what 'modifier_reset'
   2450  * does, below.
   2451  *
   2452  * After the function has been called the 'repeat' flag will still be set; the
   2453  * caller of modifier_reset must reset it at the start of each run of the test!
   2454  */
   2455 static unsigned int
   2456 modifier_total_encodings(const png_modifier *pm)
   2457 {
   2458    return 1 +                 /* (1) nothing */
   2459       pm->ngammas +           /* (2) gamma values to test */
   2460       pm->nencodings +        /* (3) total number of encodings */
   2461       /* The following test only works after the first time through the
   2462        * png_modifier code because 'bit_depth' is set when the IHDR is read.
   2463        * modifier_reset, below, preserves the setting until after it has called
   2464        * the iterate function (also below.)
   2465        *
   2466        * For this reason do not rely on this function outside a call to
   2467        * modifier_reset.
   2468        */
   2469       ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ?
   2470          pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */
   2471 }
   2472 
   2473 static void
   2474 modifier_encoding_iterate(png_modifier *pm)
   2475 {
   2476    if (!pm->repeat && /* Else something needs the current encoding again. */
   2477       pm->test_uses_encoding) /* Some transform is encoding dependent */
   2478    {
   2479       if (pm->test_exhaustive)
   2480       {
   2481          if (++pm->encoding_counter >= modifier_total_encodings(pm))
   2482             pm->encoding_counter = 0; /* This will stop the repeat */
   2483       }
   2484 
   2485       else
   2486       {
   2487          /* Not exhaustive - choose an encoding at random; generate a number in
   2488           * the range 1..(max-1), so the result is always non-zero:
   2489           */
   2490          if (pm->encoding_counter == 0)
   2491             pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1;
   2492          else
   2493             pm->encoding_counter = 0;
   2494       }
   2495 
   2496       if (pm->encoding_counter > 0)
   2497          pm->repeat = 1;
   2498    }
   2499 
   2500    else if (!pm->repeat)
   2501       pm->encoding_counter = 0;
   2502 }
   2503 
   2504 static void
   2505 modifier_reset(png_modifier *pm)
   2506 {
   2507    store_read_reset(&pm->this);
   2508    pm->limit = 4E-3;
   2509    pm->pending_len = pm->pending_chunk = 0;
   2510    pm->flush = pm->buffer_count = pm->buffer_position = 0;
   2511    pm->modifications = NULL;
   2512    pm->state = modifier_start;
   2513    modifier_encoding_iterate(pm);
   2514    /* The following must be set in the next run.  In particular
   2515     * test_uses_encodings must be set in the _ini function of each transform
   2516     * that looks at the encodings.  (Not the 'add' function!)
   2517     */
   2518    pm->test_uses_encoding = 0;
   2519    pm->current_gamma = 0;
   2520    pm->current_encoding = 0;
   2521    pm->encoding_ignored = 0;
   2522    /* These only become value after IHDR is read: */
   2523    pm->bit_depth = pm->colour_type = 0;
   2524 }
   2525 
   2526 /* The following must be called before anything else to get the encoding set up
   2527  * on the modifier.  In particular it must be called before the transform init
   2528  * functions are called.
   2529  */
   2530 static void
   2531 modifier_set_encoding(png_modifier *pm)
   2532 {
   2533    /* Set the encoding to the one specified by the current encoding counter,
   2534     * first clear out all the settings - this corresponds to an encoding_counter
   2535     * of 0.
   2536     */
   2537    pm->current_gamma = 0;
   2538    pm->current_encoding = 0;
   2539    pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */
   2540 
   2541    /* Now, if required, set the gamma and encoding fields. */
   2542    if (pm->encoding_counter > 0)
   2543    {
   2544       /* The gammas[] array is an array of screen gammas, not encoding gammas,
   2545        * so we need the inverse:
   2546        */
   2547       if (pm->encoding_counter <= pm->ngammas)
   2548          pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1];
   2549 
   2550       else
   2551       {
   2552          unsigned int i = pm->encoding_counter - pm->ngammas;
   2553 
   2554          if (i >= pm->nencodings)
   2555          {
   2556             i %= pm->nencodings;
   2557             pm->current_gamma = 1; /* Linear, only in the 16 bit case */
   2558          }
   2559 
   2560          else
   2561             pm->current_gamma = pm->encodings[i].gamma;
   2562 
   2563          pm->current_encoding = pm->encodings + i;
   2564       }
   2565    }
   2566 }
   2567 
   2568 /* Enquiry functions to find out what is set.  Notice that there is an implicit
   2569  * assumption below that the first encoding in the list is the one for sRGB.
   2570  */
   2571 static int
   2572 modifier_color_encoding_is_sRGB(const png_modifier *pm)
   2573 {
   2574    return pm->current_encoding != 0 && pm->current_encoding == pm->encodings &&
   2575       pm->current_encoding->gamma == pm->current_gamma;
   2576 }
   2577 
   2578 static int
   2579 modifier_color_encoding_is_set(const png_modifier *pm)
   2580 {
   2581    return pm->current_gamma != 0;
   2582 }
   2583 
   2584 /* Convenience macros. */
   2585 #define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d))
   2586 #define CHUNK_IHDR CHUNK(73,72,68,82)
   2587 #define CHUNK_PLTE CHUNK(80,76,84,69)
   2588 #define CHUNK_IDAT CHUNK(73,68,65,84)
   2589 #define CHUNK_IEND CHUNK(73,69,78,68)
   2590 #define CHUNK_cHRM CHUNK(99,72,82,77)
   2591 #define CHUNK_gAMA CHUNK(103,65,77,65)
   2592 #define CHUNK_sBIT CHUNK(115,66,73,84)
   2593 #define CHUNK_sRGB CHUNK(115,82,71,66)
   2594 
   2595 /* The guts of modification are performed during a read. */
   2596 static void
   2597 modifier_crc(png_bytep buffer)
   2598 {
   2599    /* Recalculate the chunk CRC - a complete chunk must be in
   2600     * the buffer, at the start.
   2601     */
   2602    uInt datalen = png_get_uint_32(buffer);
   2603    uLong crc = crc32(0, buffer+4, datalen+4);
   2604    /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value.
   2605     */
   2606    png_save_uint_32(buffer+datalen+8, (png_uint_32)crc);
   2607 }
   2608 
   2609 static void
   2610 modifier_setbuffer(png_modifier *pm)
   2611 {
   2612    modifier_crc(pm->buffer);
   2613    pm->buffer_count = png_get_uint_32(pm->buffer)+12;
   2614    pm->buffer_position = 0;
   2615 }
   2616 
   2617 /* Separate the callback into the actual implementation (which is passed the
   2618  * png_modifier explicitly) and the callback, which gets the modifier from the
   2619  * png_struct.
   2620  */
   2621 static void
   2622 modifier_read_imp(png_modifier *pm, png_bytep pb, png_size_t st)
   2623 {
   2624    while (st > 0)
   2625    {
   2626       size_t cb;
   2627       png_uint_32 len, chunk;
   2628       png_modification *mod;
   2629 
   2630       if (pm->buffer_position >= pm->buffer_count) switch (pm->state)
   2631       {
   2632          static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
   2633          case modifier_start:
   2634             store_read_imp(&pm->this, pm->buffer, 8); /* size of signature. */
   2635             pm->buffer_count = 8;
   2636             pm->buffer_position = 0;
   2637 
   2638             if (memcmp(pm->buffer, sign, 8) != 0)
   2639                png_error(pm->this.pread, "invalid PNG file signature");
   2640             pm->state = modifier_signature;
   2641             break;
   2642 
   2643          case modifier_signature:
   2644             store_read_imp(&pm->this, pm->buffer, 13+12); /* size of IHDR */
   2645             pm->buffer_count = 13+12;
   2646             pm->buffer_position = 0;
   2647 
   2648             if (png_get_uint_32(pm->buffer) != 13 ||
   2649                 png_get_uint_32(pm->buffer+4) != CHUNK_IHDR)
   2650                png_error(pm->this.pread, "invalid IHDR");
   2651 
   2652             /* Check the list of modifiers for modifications to the IHDR. */
   2653             mod = pm->modifications;
   2654             while (mod != NULL)
   2655             {
   2656                if (mod->chunk == CHUNK_IHDR && mod->modify_fn &&
   2657                    (*mod->modify_fn)(pm, mod, 0))
   2658                   {
   2659                   mod->modified = 1;
   2660                   modifier_setbuffer(pm);
   2661                   }
   2662 
   2663                /* Ignore removal or add if IHDR! */
   2664                mod = mod->next;
   2665             }
   2666 
   2667             /* Cache information from the IHDR (the modified one.) */
   2668             pm->bit_depth = pm->buffer[8+8];
   2669             pm->colour_type = pm->buffer[8+8+1];
   2670 
   2671             pm->state = modifier_IHDR;
   2672             pm->flush = 0;
   2673             break;
   2674 
   2675          case modifier_IHDR:
   2676          default:
   2677             /* Read a new chunk and process it until we see PLTE, IDAT or
   2678              * IEND.  'flush' indicates that there is still some data to
   2679              * output from the preceding chunk.
   2680              */
   2681             if ((cb = pm->flush) > 0)
   2682             {
   2683                if (cb > st) cb = st;
   2684                pm->flush -= cb;
   2685                store_read_imp(&pm->this, pb, cb);
   2686                pb += cb;
   2687                st -= cb;
   2688                if (st == 0) return;
   2689             }
   2690 
   2691             /* No more bytes to flush, read a header, or handle a pending
   2692              * chunk.
   2693              */
   2694             if (pm->pending_chunk != 0)
   2695             {
   2696                png_save_uint_32(pm->buffer, pm->pending_len);
   2697                png_save_uint_32(pm->buffer+4, pm->pending_chunk);
   2698                pm->pending_len = 0;
   2699                pm->pending_chunk = 0;
   2700             }
   2701             else
   2702                store_read_imp(&pm->this, pm->buffer, 8);
   2703 
   2704             pm->buffer_count = 8;
   2705             pm->buffer_position = 0;
   2706 
   2707             /* Check for something to modify or a terminator chunk. */
   2708             len = png_get_uint_32(pm->buffer);
   2709             chunk = png_get_uint_32(pm->buffer+4);
   2710 
   2711             /* Terminators first, they may have to be delayed for added
   2712              * chunks
   2713              */
   2714             if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT ||
   2715                 chunk == CHUNK_IEND)
   2716             {
   2717                mod = pm->modifications;
   2718 
   2719                while (mod != NULL)
   2720                {
   2721                   if ((mod->add == chunk ||
   2722                       (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) &&
   2723                       mod->modify_fn != NULL && !mod->modified && !mod->added)
   2724                   {
   2725                      /* Regardless of what the modify function does do not run
   2726                       * this again.
   2727                       */
   2728                      mod->added = 1;
   2729 
   2730                      if ((*mod->modify_fn)(pm, mod, 1 /*add*/))
   2731                      {
   2732                         /* Reset the CRC on a new chunk */
   2733                         if (pm->buffer_count > 0)
   2734                            modifier_setbuffer(pm);
   2735 
   2736                         else
   2737                            {
   2738                            pm->buffer_position = 0;
   2739                            mod->removed = 1;
   2740                            }
   2741 
   2742                         /* The buffer has been filled with something (we assume)
   2743                          * so output this.  Pend the current chunk.
   2744                          */
   2745                         pm->pending_len = len;
   2746                         pm->pending_chunk = chunk;
   2747                         break; /* out of while */
   2748                      }
   2749                   }
   2750 
   2751                   mod = mod->next;
   2752                }
   2753 
   2754                /* Don't do any further processing if the buffer was modified -
   2755                 * otherwise the code will end up modifying a chunk that was
   2756                 * just added.
   2757                 */
   2758                if (mod != NULL)
   2759                   break; /* out of switch */
   2760             }
   2761 
   2762             /* If we get to here then this chunk may need to be modified.  To
   2763              * do this it must be less than 1024 bytes in total size, otherwise
   2764              * it just gets flushed.
   2765              */
   2766             if (len+12 <= sizeof pm->buffer)
   2767             {
   2768                store_read_imp(&pm->this, pm->buffer+pm->buffer_count,
   2769                    len+12-pm->buffer_count);
   2770                pm->buffer_count = len+12;
   2771 
   2772                /* Check for a modification, else leave it be. */
   2773                mod = pm->modifications;
   2774                while (mod != NULL)
   2775                {
   2776                   if (mod->chunk == chunk)
   2777                   {
   2778                      if (mod->modify_fn == NULL)
   2779                      {
   2780                         /* Remove this chunk */
   2781                         pm->buffer_count = pm->buffer_position = 0;
   2782                         mod->removed = 1;
   2783                         break; /* Terminate the while loop */
   2784                      }
   2785 
   2786                      else if ((*mod->modify_fn)(pm, mod, 0))
   2787                      {
   2788                         mod->modified = 1;
   2789                         /* The chunk may have been removed: */
   2790                         if (pm->buffer_count == 0)
   2791                         {
   2792                            pm->buffer_position = 0;
   2793                            break;
   2794                         }
   2795                         modifier_setbuffer(pm);
   2796                      }
   2797                   }
   2798 
   2799                   mod = mod->next;
   2800                }
   2801             }
   2802 
   2803             else
   2804                pm->flush = len+12 - pm->buffer_count; /* data + crc */
   2805 
   2806             /* Take the data from the buffer (if there is any). */
   2807             break;
   2808       }
   2809 
   2810       /* Here to read from the modifier buffer (not directly from
   2811        * the store, as in the flush case above.)
   2812        */
   2813       cb = pm->buffer_count - pm->buffer_position;
   2814 
   2815       if (cb > st)
   2816          cb = st;
   2817 
   2818       memcpy(pb, pm->buffer + pm->buffer_position, cb);
   2819       st -= cb;
   2820       pb += cb;
   2821       pm->buffer_position += cb;
   2822    }
   2823 }
   2824 
   2825 /* The callback: */
   2826 static void PNGCBAPI
   2827 modifier_read(png_structp ppIn, png_bytep pb, png_size_t st)
   2828 {
   2829    png_const_structp pp = ppIn;
   2830    png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp));
   2831 
   2832    if (pm == NULL || pm->this.pread != pp)
   2833       png_error(pp, "bad modifier_read call");
   2834 
   2835    modifier_read_imp(pm, pb, st);
   2836 }
   2837 
   2838 /* Like store_progressive_read but the data is getting changed as we go so we
   2839  * need a local buffer.
   2840  */
   2841 static void
   2842 modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi)
   2843 {
   2844    if (pm->this.pread != pp || pm->this.current == NULL ||
   2845        pm->this.next == NULL)
   2846       png_error(pp, "store state damaged (progressive)");
   2847 
   2848    /* This is another Horowitz and Hill random noise generator.  In this case
   2849     * the aim is to stress the progressive reader with truly horrible variable
   2850     * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers
   2851     * is generated.  We could probably just count from 1 to 32767 and get as
   2852     * good a result.
   2853     */
   2854    for (;;)
   2855    {
   2856       static png_uint_32 noise = 1;
   2857       png_size_t cb, cbAvail;
   2858       png_byte buffer[512];
   2859 
   2860       /* Generate 15 more bits of stuff: */
   2861       noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff);
   2862       cb = noise & 0x1ff;
   2863 
   2864       /* Check that this number of bytes are available (in the current buffer.)
   2865        * (This doesn't quite work - the modifier might delete a chunk; unlikely
   2866        * but possible, it doesn't happen at present because the modifier only
   2867        * adds chunks to standard images.)
   2868        */
   2869       cbAvail = store_read_buffer_avail(&pm->this);
   2870       if (pm->buffer_count > pm->buffer_position)
   2871          cbAvail += pm->buffer_count - pm->buffer_position;
   2872 
   2873       if (cb > cbAvail)
   2874       {
   2875          /* Check for EOF: */
   2876          if (cbAvail == 0)
   2877             break;
   2878 
   2879          cb = cbAvail;
   2880       }
   2881 
   2882       modifier_read_imp(pm, buffer, cb);
   2883       png_process_data(pp, pi, buffer, cb);
   2884    }
   2885 
   2886    /* Check the invariants at the end (if this fails it's a problem in this
   2887     * file!)
   2888     */
   2889    if (pm->buffer_count > pm->buffer_position ||
   2890        pm->this.next != &pm->this.current->data ||
   2891        pm->this.readpos < pm->this.current->datacount)
   2892       png_error(pp, "progressive read implementation error");
   2893 }
   2894 
   2895 /* Set up a modifier. */
   2896 static png_structp
   2897 set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id,
   2898     const char *name)
   2899 {
   2900    /* Do this first so that the modifier fields are cleared even if an error
   2901     * happens allocating the png_struct.  No allocation is done here so no
   2902     * cleanup is required.
   2903     */
   2904    pm->state = modifier_start;
   2905    pm->bit_depth = 0;
   2906    pm->colour_type = 255;
   2907 
   2908    pm->pending_len = 0;
   2909    pm->pending_chunk = 0;
   2910    pm->flush = 0;
   2911    pm->buffer_count = 0;
   2912    pm->buffer_position = 0;
   2913 
   2914    return set_store_for_read(&pm->this, ppi, id, name);
   2915 }
   2916 
   2917 
   2918 /******************************** MODIFICATIONS *******************************/
   2919 /* Standard modifications to add chunks.  These do not require the _SUPPORTED
   2920  * macros because the chunks can be there regardless of whether this specific
   2921  * libpng supports them.
   2922  */
   2923 typedef struct gama_modification
   2924 {
   2925    png_modification this;
   2926    png_fixed_point  gamma;
   2927 } gama_modification;
   2928 
   2929 static int
   2930 gama_modify(png_modifier *pm, png_modification *me, int add)
   2931 {
   2932    UNUSED(add)
   2933    /* This simply dumps the given gamma value into the buffer. */
   2934    png_save_uint_32(pm->buffer, 4);
   2935    png_save_uint_32(pm->buffer+4, CHUNK_gAMA);
   2936    png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma);
   2937    return 1;
   2938 }
   2939 
   2940 static void
   2941 gama_modification_init(gama_modification *me, png_modifier *pm, double gammad)
   2942 {
   2943    double g;
   2944 
   2945    modification_init(&me->this);
   2946    me->this.chunk = CHUNK_gAMA;
   2947    me->this.modify_fn = gama_modify;
   2948    me->this.add = CHUNK_PLTE;
   2949    g = fix(gammad);
   2950    me->gamma = (png_fixed_point)g;
   2951    me->this.next = pm->modifications;
   2952    pm->modifications = &me->this;
   2953 }
   2954 
   2955 typedef struct chrm_modification
   2956 {
   2957    png_modification          this;
   2958    const color_encoding *encoding;
   2959    png_fixed_point           wx, wy, rx, ry, gx, gy, bx, by;
   2960 } chrm_modification;
   2961 
   2962 static int
   2963 chrm_modify(png_modifier *pm, png_modification *me, int add)
   2964 {
   2965    UNUSED(add)
   2966    /* As with gAMA this just adds the required cHRM chunk to the buffer. */
   2967    png_save_uint_32(pm->buffer   , 32);
   2968    png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM);
   2969    png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx);
   2970    png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy);
   2971    png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx);
   2972    png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry);
   2973    png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx);
   2974    png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy);
   2975    png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx);
   2976    png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by);
   2977    return 1;
   2978 }
   2979 
   2980 static void
   2981 chrm_modification_init(chrm_modification *me, png_modifier *pm,
   2982    const color_encoding *encoding)
   2983 {
   2984    CIE_color white = white_point(encoding);
   2985 
   2986    /* Original end points: */
   2987    me->encoding = encoding;
   2988 
   2989    /* Chromaticities (in fixed point): */
   2990    me->wx = fix(chromaticity_x(white));
   2991    me->wy = fix(chromaticity_y(white));
   2992 
   2993    me->rx = fix(chromaticity_x(encoding->red));
   2994    me->ry = fix(chromaticity_y(encoding->red));
   2995    me->gx = fix(chromaticity_x(encoding->green));
   2996    me->gy = fix(chromaticity_y(encoding->green));
   2997    me->bx = fix(chromaticity_x(encoding->blue));
   2998    me->by = fix(chromaticity_y(encoding->blue));
   2999 
   3000    modification_init(&me->this);
   3001    me->this.chunk = CHUNK_cHRM;
   3002    me->this.modify_fn = chrm_modify;
   3003    me->this.add = CHUNK_PLTE;
   3004    me->this.next = pm->modifications;
   3005    pm->modifications = &me->this;
   3006 }
   3007 
   3008 typedef struct srgb_modification
   3009 {
   3010    png_modification this;
   3011    png_byte         intent;
   3012 } srgb_modification;
   3013 
   3014 static int
   3015 srgb_modify(png_modifier *pm, png_modification *me, int add)
   3016 {
   3017    UNUSED(add)
   3018    /* As above, ignore add and just make a new chunk */
   3019    png_save_uint_32(pm->buffer, 1);
   3020    png_save_uint_32(pm->buffer+4, CHUNK_sRGB);
   3021    pm->buffer[8] = ((srgb_modification*)me)->intent;
   3022    return 1;
   3023 }
   3024 
   3025 static void
   3026 srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent)
   3027 {
   3028    modification_init(&me->this);
   3029    me->this.chunk = CHUNK_sBIT;
   3030 
   3031    if (intent <= 3) /* if valid, else *delete* sRGB chunks */
   3032    {
   3033       me->this.modify_fn = srgb_modify;
   3034       me->this.add = CHUNK_PLTE;
   3035       me->intent = intent;
   3036    }
   3037 
   3038    else
   3039    {
   3040       me->this.modify_fn = 0;
   3041       me->this.add = 0;
   3042       me->intent = 0;
   3043    }
   3044 
   3045    me->this.next = pm->modifications;
   3046    pm->modifications = &me->this;
   3047 }
   3048 
   3049 #ifdef PNG_READ_GAMMA_SUPPORTED
   3050 typedef struct sbit_modification
   3051 {
   3052    png_modification this;
   3053    png_byte         sbit;
   3054 } sbit_modification;
   3055 
   3056 static int
   3057 sbit_modify(png_modifier *pm, png_modification *me, int add)
   3058 {
   3059    png_byte sbit = ((sbit_modification*)me)->sbit;
   3060    if (pm->bit_depth > sbit)
   3061    {
   3062       int cb = 0;
   3063       switch (pm->colour_type)
   3064       {
   3065          case 0:
   3066             cb = 1;
   3067             break;
   3068 
   3069          case 2:
   3070          case 3:
   3071             cb = 3;
   3072             break;
   3073 
   3074          case 4:
   3075             cb = 2;
   3076             break;
   3077 
   3078          case 6:
   3079             cb = 4;
   3080             break;
   3081 
   3082          default:
   3083             png_error(pm->this.pread,
   3084                "unexpected colour type in sBIT modification");
   3085       }
   3086 
   3087       png_save_uint_32(pm->buffer, cb);
   3088       png_save_uint_32(pm->buffer+4, CHUNK_sBIT);
   3089 
   3090       while (cb > 0)
   3091          (pm->buffer+8)[--cb] = sbit;
   3092 
   3093       return 1;
   3094    }
   3095    else if (!add)
   3096    {
   3097       /* Remove the sBIT chunk */
   3098       pm->buffer_count = pm->buffer_position = 0;
   3099       return 1;
   3100    }
   3101    else
   3102       return 0; /* do nothing */
   3103 }
   3104 
   3105 static void
   3106 sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit)
   3107 {
   3108    modification_init(&me->this);
   3109    me->this.chunk = CHUNK_sBIT;
   3110    me->this.modify_fn = sbit_modify;
   3111    me->this.add = CHUNK_PLTE;
   3112    me->sbit = sbit;
   3113    me->this.next = pm->modifications;
   3114    pm->modifications = &me->this;
   3115 }
   3116 #endif /* PNG_READ_GAMMA_SUPPORTED */
   3117 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
   3118 
   3119 /***************************** STANDARD PNG FILES *****************************/
   3120 /* Standard files - write and save standard files. */
   3121 /* There are two basic forms of standard images.  Those which attempt to have
   3122  * all the possible pixel values (not possible for 16bpp images, but a range of
   3123  * values are produced) and those which have a range of image sizes.  The former
   3124  * are used for testing transforms, in particular gamma correction and bit
   3125  * reduction and increase.  The latter are reserved for testing the behavior of
   3126  * libpng with respect to 'odd' image sizes - particularly small images where
   3127  * rows become 1 byte and interlace passes disappear.
   3128  *
   3129  * The first, most useful, set are the 'transform' images, the second set of
   3130  * small images are the 'size' images.
   3131  *
   3132  * The transform files are constructed with rows which fit into a 1024 byte row
   3133  * buffer.  This makes allocation easier below.  Further regardless of the file
   3134  * format every row has 128 pixels (giving 1024 bytes for 64bpp formats).
   3135  *
   3136  * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed
   3137  * and with an ID derived from the colour type, bit depth and interlace type
   3138  * as above (FILEID).  The width (128) and height (variable) are not stored in
   3139  * the FILEID - instead the fields are set to 0, indicating a transform file.
   3140  *
   3141  * The size files ar constructed with rows a maximum of 128 bytes wide, allowing
   3142  * a maximum width of 16 pixels (for the 64bpp case.)  They also have a maximum
   3143  * height of 16 rows.  The width and height are stored in the FILEID and, being
   3144  * non-zero, indicate a size file.
   3145  *
   3146  * Because the PNG filter code is typically the largest CPU consumer within
   3147  * libpng itself there is a tendency to attempt to optimize it.  This results in
   3148  * special case code which needs to be validated.  To cause this to happen the
   3149  * 'size' images are made to use each possible filter, in so far as this is
   3150  * possible for smaller images.
   3151  *
   3152  * For palette image (colour type 3) multiple transform images are stored with
   3153  * the same bit depth to allow testing of more colour combinations -
   3154  * particularly important for testing the gamma code because libpng uses a
   3155  * different code path for palette images.  For size images a single palette is
   3156  * used.
   3157  */
   3158 
   3159 /* Make a 'standard' palette.  Because there are only 256 entries in a palette
   3160  * (maximum) this actually makes a random palette in the hope that enough tests
   3161  * will catch enough errors.  (Note that the same palette isn't produced every
   3162  * time for the same test - it depends on what previous tests have been run -
   3163  * but a given set of arguments to pngvalid will always produce the same palette
   3164  * at the same test!  This is why pseudo-random number generators are useful for
   3165  * testing.)
   3166  *
   3167  * The store must be open for write when this is called, otherwise an internal
   3168  * error will occur.  This routine contains its own magic number seed, so the
   3169  * palettes generated don't change if there are intervening errors (changing the
   3170  * calls to the store_mark seed.)
   3171  */
   3172 static store_palette_entry *
   3173 make_standard_palette(png_store* ps, int npalette, int do_tRNS)
   3174 {
   3175    static png_uint_32 palette_seed[2] = { 0x87654321, 9 };
   3176 
   3177    int i = 0;
   3178    png_byte values[256][4];
   3179 
   3180    /* Always put in black and white plus the six primary and secondary colors.
   3181     */
   3182    for (; i<8; ++i)
   3183    {
   3184       values[i][1] = (png_byte)((i&1) ? 255U : 0U);
   3185       values[i][2] = (png_byte)((i&2) ? 255U : 0U);
   3186       values[i][3] = (png_byte)((i&4) ? 255U : 0U);
   3187    }
   3188 
   3189    /* Then add 62 grays (one quarter of the remaining 256 slots). */
   3190    {
   3191       int j = 0;
   3192       png_byte random_bytes[4];
   3193       png_byte need[256];
   3194 
   3195       need[0] = 0; /*got black*/
   3196       memset(need+1, 1, (sizeof need)-2); /*need these*/
   3197       need[255] = 0; /*but not white*/
   3198 
   3199       while (i<70)
   3200       {
   3201          png_byte b;
   3202 
   3203          if (j==0)
   3204          {
   3205             make_four_random_bytes(palette_seed, random_bytes);
   3206             j = 4;
   3207          }
   3208 
   3209          b = random_bytes[--j];
   3210          if (need[b])
   3211          {
   3212             values[i][1] = b;
   3213             values[i][2] = b;
   3214             values[i++][3] = b;
   3215          }
   3216       }
   3217    }
   3218 
   3219    /* Finally add 192 colors at random - don't worry about matches to things we
   3220     * already have, chance is less than 1/65536.  Don't worry about grays,
   3221     * chance is the same, so we get a duplicate or extra gray less than 1 time
   3222     * in 170.
   3223     */
   3224    for (; i<256; ++i)
   3225       make_four_random_bytes(palette_seed, values[i]);
   3226 
   3227    /* Fill in the alpha values in the first byte.  Just use all possible values
   3228     * (0..255) in an apparently random order:
   3229     */
   3230    {
   3231       store_palette_entry *palette;
   3232       png_byte selector[4];
   3233 
   3234       make_four_random_bytes(palette_seed, selector);
   3235 
   3236       if (do_tRNS)
   3237          for (i=0; i<256; ++i)
   3238             values[i][0] = (png_byte)(i ^ selector[0]);
   3239 
   3240       else
   3241          for (i=0; i<256; ++i)
   3242             values[i][0] = 255; /* no transparency/tRNS chunk */
   3243 
   3244       /* 'values' contains 256 ARGB values, but we only need 'npalette'.
   3245        * 'npalette' will always be a power of 2: 2, 4, 16 or 256.  In the low
   3246        * bit depth cases select colors at random, else it is difficult to have
   3247        * a set of low bit depth palette test with any chance of a reasonable
   3248        * range of colors.  Do this by randomly permuting values into the low
   3249        * 'npalette' entries using an XOR mask generated here.  This also
   3250        * permutes the npalette == 256 case in a potentially useful way (there is
   3251        * no relationship between palette index and the color value therein!)
   3252        */
   3253       palette = store_write_palette(ps, npalette);
   3254 
   3255       for (i=0; i<npalette; ++i)
   3256       {
   3257          palette[i].alpha = values[i ^ selector[1]][0];
   3258          palette[i].red   = values[i ^ selector[1]][1];
   3259          palette[i].green = values[i ^ selector[1]][2];
   3260          palette[i].blue  = values[i ^ selector[1]][3];
   3261       }
   3262 
   3263       return palette;
   3264    }
   3265 }
   3266 
   3267 /* Initialize a standard palette on a write stream.  The 'do_tRNS' argument
   3268  * indicates whether or not to also set the tRNS chunk.
   3269  */
   3270 /* TODO: the png_structp here can probably be 'const' in the future */
   3271 static void
   3272 init_standard_palette(png_store *ps, png_structp pp, png_infop pi, int npalette,
   3273    int do_tRNS)
   3274 {
   3275    store_palette_entry *ppal = make_standard_palette(ps, npalette, do_tRNS);
   3276 
   3277    {
   3278       int i;
   3279       png_color palette[256];
   3280 
   3281       /* Set all entries to detect overread errors. */
   3282       for (i=0; i<npalette; ++i)
   3283       {
   3284          palette[i].red = ppal[i].red;
   3285          palette[i].green = ppal[i].green;
   3286          palette[i].blue = ppal[i].blue;
   3287       }
   3288 
   3289       /* Just in case fill in the rest with detectable values: */
   3290       for (; i<256; ++i)
   3291          palette[i].red = palette[i].green = palette[i].blue = 42;
   3292 
   3293       png_set_PLTE(pp, pi, palette, npalette);
   3294    }
   3295 
   3296    if (do_tRNS)
   3297    {
   3298       int i, j;
   3299       png_byte tRNS[256];
   3300 
   3301       /* Set all the entries, but skip trailing opaque entries */
   3302       for (i=j=0; i<npalette; ++i)
   3303          if ((tRNS[i] = ppal[i].alpha) < 255)
   3304             j = i+1;
   3305 
   3306       /* Fill in the remainder with a detectable value: */
   3307       for (; i<256; ++i)
   3308          tRNS[i] = 24;
   3309 
   3310 #     ifdef PNG_WRITE_tRNS_SUPPORTED
   3311          if (j > 0)
   3312             png_set_tRNS(pp, pi, tRNS, j, 0/*color*/);
   3313 #     endif
   3314    }
   3315 }
   3316 
   3317 #ifdef PNG_WRITE_tRNS_SUPPORTED
   3318 static void
   3319 set_random_tRNS(png_structp pp, png_infop pi, const png_byte colour_type,
   3320    const int bit_depth)
   3321 {
   3322    /* To make this useful the tRNS color needs to match at least one pixel.
   3323     * Random values are fine for gray, including the 16-bit case where we know
   3324     * that the test image contains all the gray values.  For RGB we need more
   3325     * method as only 65536 different RGB values are generated.
   3326     */
   3327    png_color_16 tRNS;
   3328    const png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1);
   3329 
   3330    R8(tRNS); /* makes unset fields random */
   3331 
   3332    if (colour_type & 2/*RGB*/)
   3333    {
   3334       if (bit_depth == 8)
   3335       {
   3336          R16(tRNS.red);
   3337          R16(tRNS.green);
   3338          tRNS.blue = tRNS.red ^ tRNS.green;
   3339          tRNS.red &= mask;
   3340          tRNS.green &= mask;
   3341          tRNS.blue &= mask;
   3342       }
   3343 
   3344       else /* bit_depth == 16 */
   3345       {
   3346          R16(tRNS.red);
   3347          tRNS.green = (png_uint_16)(tRNS.red * 257);
   3348          tRNS.blue = (png_uint_16)(tRNS.green * 17);
   3349       }
   3350    }
   3351 
   3352    else
   3353    {
   3354       R16(tRNS.gray);
   3355       tRNS.gray &= mask;
   3356    }
   3357 
   3358    png_set_tRNS(pp, pi, NULL, 0, &tRNS);
   3359 }
   3360 #endif
   3361 
   3362 /* The number of passes is related to the interlace type. There was no libpng
   3363  * API to determine this prior to 1.5, so we need an inquiry function:
   3364  */
   3365 static int
   3366 npasses_from_interlace_type(png_const_structp pp, int interlace_type)
   3367 {
   3368    switch (interlace_type)
   3369    {
   3370    default:
   3371       png_error(pp, "invalid interlace type");
   3372 
   3373    case PNG_INTERLACE_NONE:
   3374       return 1;
   3375 
   3376    case PNG_INTERLACE_ADAM7:
   3377       return PNG_INTERLACE_ADAM7_PASSES;
   3378    }
   3379 }
   3380 
   3381 static unsigned int
   3382 bit_size(png_const_structp pp, png_byte colour_type, png_byte bit_depth)
   3383 {
   3384    switch (colour_type)
   3385    {
   3386       default: png_error(pp, "invalid color type");
   3387 
   3388       case 0:  return bit_depth;
   3389 
   3390       case 2:  return 3*bit_depth;
   3391 
   3392       case 3:  return bit_depth;
   3393 
   3394       case 4:  return 2*bit_depth;
   3395 
   3396       case 6:  return 4*bit_depth;
   3397    }
   3398 }
   3399 
   3400 #define TRANSFORM_WIDTH  128U
   3401 #define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U)
   3402 #define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */
   3403 #define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */
   3404 #define SIZE_HEIGHTMAX 16 /* Maximum range of size images */
   3405 
   3406 static size_t
   3407 transform_rowsize(png_const_structp pp, png_byte colour_type,
   3408    png_byte bit_depth)
   3409 {
   3410    return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8;
   3411 }
   3412 
   3413 /* transform_width(pp, colour_type, bit_depth) current returns the same number
   3414  * every time, so just use a macro:
   3415  */
   3416 #define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH
   3417 
   3418 static png_uint_32
   3419 transform_height(png_const_structp pp, png_byte colour_type, png_byte bit_depth)
   3420 {
   3421    switch (bit_size(pp, colour_type, bit_depth))
   3422    {
   3423       case 1:
   3424       case 2:
   3425       case 4:
   3426          return 1;   /* Total of 128 pixels */
   3427 
   3428       case 8:
   3429          return 2;   /* Total of 256 pixels/bytes */
   3430 
   3431       case 16:
   3432          return 512; /* Total of 65536 pixels */
   3433 
   3434       case 24:
   3435       case 32:
   3436          return 512; /* 65536 pixels */
   3437 
   3438       case 48:
   3439       case 64:
   3440          return 2048;/* 4 x 65536 pixels. */
   3441 #        define TRANSFORM_HEIGHTMAX 2048
   3442 
   3443       default:
   3444          return 0;   /* Error, will be caught later */
   3445    }
   3446 }
   3447 
   3448 #ifdef PNG_READ_SUPPORTED
   3449 /* The following can only be defined here, now we have the definitions
   3450  * of the transform image sizes.
   3451  */
   3452 static png_uint_32
   3453 standard_width(png_const_structp pp, png_uint_32 id)
   3454 {
   3455    png_uint_32 width = WIDTH_FROM_ID(id);
   3456    UNUSED(pp)
   3457 
   3458    if (width == 0)
   3459       width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
   3460 
   3461    return width;
   3462 }
   3463 
   3464 static png_uint_32
   3465 standard_height(png_const_structp pp, png_uint_32 id)
   3466 {
   3467    png_uint_32 height = HEIGHT_FROM_ID(id);
   3468 
   3469    if (height == 0)
   3470       height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
   3471 
   3472    return height;
   3473 }
   3474 
   3475 static png_uint_32
   3476 standard_rowsize(png_const_structp pp, png_uint_32 id)
   3477 {
   3478    png_uint_32 width = standard_width(pp, id);
   3479 
   3480    /* This won't overflow: */
   3481    width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id));
   3482    return (width + 7) / 8;
   3483 }
   3484 #endif /* PNG_READ_SUPPORTED */
   3485 
   3486 static void
   3487 transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX],
   3488    png_byte colour_type, png_byte bit_depth, png_uint_32 y)
   3489 {
   3490    png_uint_32 v = y << 7;
   3491    png_uint_32 i = 0;
   3492 
   3493    switch (bit_size(pp, colour_type, bit_depth))
   3494    {
   3495       case 1:
   3496          while (i<128/8) buffer[i] = (png_byte)(v & 0xff), v += 17, ++i;
   3497          return;
   3498 
   3499       case 2:
   3500          while (i<128/4) buffer[i] = (png_byte)(v & 0xff), v += 33, ++i;
   3501          return;
   3502 
   3503       case 4:
   3504          while (i<128/2) buffer[i] = (png_byte)(v & 0xff), v += 65, ++i;
   3505          return;
   3506 
   3507       case 8:
   3508          /* 256 bytes total, 128 bytes in each row set as follows: */
   3509          while (i<128) buffer[i] = (png_byte)(v & 0xff), ++v, ++i;
   3510          return;
   3511 
   3512       case 16:
   3513          /* Generate all 65536 pixel values in order, which includes the 8 bit
   3514           * GA case as well as the 16 bit G case.
   3515           */
   3516          while (i<128)
   3517          {
   3518             buffer[2*i] = (png_byte)((v>>8) & 0xff);
   3519             buffer[2*i+1] = (png_byte)(v & 0xff);
   3520             ++v;
   3521             ++i;
   3522          }
   3523 
   3524          return;
   3525 
   3526       case 24:
   3527          /* 65535 pixels, but rotate the values. */
   3528          while (i<128)
   3529          {
   3530             /* Three bytes per pixel, r, g, b, make b by r^g */
   3531             buffer[3*i+0] = (png_byte)((v >> 8) & 0xff);
   3532             buffer[3*i+1] = (png_byte)(v & 0xff);
   3533             buffer[3*i+2] = (png_byte)(((v >> 8) ^ v) & 0xff);
   3534             ++v;
   3535             ++i;
   3536          }
   3537 
   3538          return;
   3539 
   3540       case 32:
   3541          /* 65535 pixels, r, g, b, a; just replicate */
   3542          while (i<128)
   3543          {
   3544             buffer[4*i+0] = (png_byte)((v >> 8) & 0xff);
   3545             buffer[4*i+1] = (png_byte)(v & 0xff);
   3546             buffer[4*i+2] = (png_byte)((v >> 8) & 0xff);
   3547             buffer[4*i+3] = (png_byte)(v & 0xff);
   3548             ++v;
   3549             ++i;
   3550          }
   3551 
   3552          return;
   3553 
   3554       case 48:
   3555          /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at
   3556           * each pixel, g increase by 257 (0x101) and 'b' by 0x1111:
   3557           */
   3558          while (i<128)
   3559          {
   3560             png_uint_32 t = v++;
   3561             buffer[6*i+0] = (png_byte)((t >> 8) & 0xff);
   3562             buffer[6*i+1] = (png_byte)(t & 0xff);
   3563             t *= 257;
   3564             buffer[6*i+2] = (png_byte)((t >> 8) & 0xff);
   3565             buffer[6*i+3] = (png_byte)(t & 0xff);
   3566             t *= 17;
   3567             buffer[6*i+4] = (png_byte)((t >> 8) & 0xff);
   3568             buffer[6*i+5] = (png_byte)(t & 0xff);
   3569             ++i;
   3570          }
   3571 
   3572          return;
   3573 
   3574       case 64:
   3575          /* As above in the 32 bit case. */
   3576          while (i<128)
   3577          {
   3578             png_uint_32 t = v++;
   3579             buffer[8*i+0] = (png_byte)((t >> 8) & 0xff);
   3580             buffer[8*i+1] = (png_byte)(t & 0xff);
   3581             buffer[8*i+4] = (png_byte)((t >> 8) & 0xff);
   3582             buffer[8*i+5] = (png_byte)(t & 0xff);
   3583             t *= 257;
   3584             buffer[8*i+2] = (png_byte)((t >> 8) & 0xff);
   3585             buffer[8*i+3] = (png_byte)(t & 0xff);
   3586             buffer[8*i+6] = (png_byte)((t >> 8) & 0xff);
   3587             buffer[8*i+7] = (png_byte)(t & 0xff);
   3588             ++i;
   3589          }
   3590          return;
   3591 
   3592       default:
   3593          break;
   3594    }
   3595 
   3596    png_error(pp, "internal error");
   3597 }
   3598 
   3599 /* This is just to do the right cast - could be changed to a function to check
   3600  * 'bd' but there isn't much point.
   3601  */
   3602 #define DEPTH(bd) ((png_byte)(1U << (bd)))
   3603 
   3604 /* This is just a helper for compiling on minimal systems with no write
   3605  * interlacing support.  If there is no write interlacing we can't generate test
   3606  * cases with interlace:
   3607  */
   3608 #ifdef PNG_WRITE_INTERLACING_SUPPORTED
   3609 #  define INTERLACE_LAST PNG_INTERLACE_LAST
   3610 #  define check_interlace_type(type) ((void)(type))
   3611 #  define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp)
   3612 #  define do_own_interlace 0
   3613 #elif PNG_LIBPNG_VER < 10700
   3614 #  define set_write_interlace_handling(pp,type) (1)
   3615 static void
   3616 check_interlace_type(int const interlace_type)
   3617 {
   3618    /* Prior to 1.7.0 libpng does not support the write of an interlaced image
   3619     * unless PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the
   3620     * code here does the pixel interlace itself, so:
   3621     */
   3622    if (interlace_type != PNG_INTERLACE_NONE)
   3623    {
   3624       /* This is an internal error - --interlace tests should be skipped, not
   3625        * attempted.
   3626        */
   3627       fprintf(stderr, "pngvalid: no interlace support\n");
   3628       exit(99);
   3629    }
   3630 }
   3631 #  define INTERLACE_LAST (PNG_INTERLACE_NONE+1)
   3632 #  define do_own_interlace 0
   3633 #else /* libpng 1.7+ */
   3634 #  define set_write_interlace_handling(pp,type)\
   3635       npasses_from_interlace_type(pp,type)
   3636 #  define check_interlace_type(type) ((void)(type))
   3637 #  define INTERLACE_LAST PNG_INTERLACE_LAST
   3638 #  define do_own_interlace 1
   3639 #endif /* WRITE_INTERLACING tests */
   3640 
   3641 #define CAN_WRITE_INTERLACE\
   3642    PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED
   3643 
   3644 /* Do the same thing for read interlacing; this controls whether read tests do
   3645  * their own de-interlace or use libpng.
   3646  */
   3647 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3648 #  define do_read_interlace 0
   3649 #else /* no libpng read interlace support */
   3650 #  define do_read_interlace 1
   3651 #endif
   3652 /* The following two routines use the PNG interlace support macros from
   3653  * png.h to interlace or deinterlace rows.
   3654  */
   3655 static void
   3656 interlace_row(png_bytep buffer, png_const_bytep imageRow,
   3657    unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)
   3658 {
   3659    png_uint_32 xin, xout, xstep;
   3660 
   3661    /* Note that this can, trivially, be optimized to a memcpy on pass 7, the
   3662     * code is presented this way to make it easier to understand.  In practice
   3663     * consult the code in the libpng source to see other ways of doing this.
   3664     *
   3665     * It is OK for buffer and imageRow to be identical, because 'xin' moves
   3666     * faster than 'xout' and we copy up.
   3667     */
   3668    xin = PNG_PASS_START_COL(pass);
   3669    xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
   3670 
   3671    for (xout=0; xin<w; xin+=xstep)
   3672    {
   3673       pixel_copy(buffer, xout, imageRow, xin, pixel_size, littleendian);
   3674       ++xout;
   3675    }
   3676 }
   3677 
   3678 #ifdef PNG_READ_SUPPORTED
   3679 static void
   3680 deinterlace_row(png_bytep buffer, png_const_bytep row,
   3681    unsigned int pixel_size, png_uint_32 w, int pass, int littleendian)
   3682 {
   3683    /* The inverse of the above, 'row' is part of row 'y' of the output image,
   3684     * in 'buffer'.  The image is 'w' wide and this is pass 'pass', distribute
   3685     * the pixels of row into buffer and return the number written (to allow
   3686     * this to be checked).
   3687     */
   3688    png_uint_32 xin, xout, xstep;
   3689 
   3690    xout = PNG_PASS_START_COL(pass);
   3691    xstep = 1U<<PNG_PASS_COL_SHIFT(pass);
   3692 
   3693    for (xin=0; xout<w; xout+=xstep)
   3694    {
   3695       pixel_copy(buffer, xout, row, xin, pixel_size, littleendian);
   3696       ++xin;
   3697    }
   3698 }
   3699 #endif /* PNG_READ_SUPPORTED */
   3700 
   3701 /* Make a standardized image given an image colour type, bit depth and
   3702  * interlace type.  The standard images have a very restricted range of
   3703  * rows and heights and are used for testing transforms rather than image
   3704  * layout details.  See make_size_images below for a way to make images
   3705  * that test odd sizes along with the libpng interlace handling.
   3706  */
   3707 #ifdef PNG_WRITE_FILTER_SUPPORTED
   3708 static void
   3709 choose_random_filter(png_structp pp, int start)
   3710 {
   3711    /* Choose filters randomly except that on the very first row ensure that
   3712     * there is at least one previous row filter.
   3713     */
   3714    int filters = PNG_ALL_FILTERS & random_mod(256U);
   3715 
   3716    /* There may be no filters; skip the setting. */
   3717    if (filters != 0)
   3718    {
   3719       if (start && filters < PNG_FILTER_UP)
   3720          filters |= PNG_FILTER_UP;
   3721 
   3722       png_set_filter(pp, 0/*method*/, filters);
   3723    }
   3724 }
   3725 #else /* !WRITE_FILTER */
   3726 #  define choose_random_filter(pp, start) ((void)0)
   3727 #endif /* !WRITE_FILTER */
   3728 
   3729 static void
   3730 make_transform_image(png_store* const ps, png_byte const colour_type,
   3731     png_byte const bit_depth, unsigned int palette_number,
   3732     int interlace_type, png_const_charp name)
   3733 {
   3734    context(ps, fault);
   3735 
   3736    check_interlace_type(interlace_type);
   3737 
   3738    Try
   3739    {
   3740       png_infop pi;
   3741       png_structp pp = set_store_for_write(ps, &pi, name);
   3742       png_uint_32 h, w;
   3743 
   3744       /* In the event of a problem return control to the Catch statement below
   3745        * to do the clean up - it is not possible to 'return' directly from a Try
   3746        * block.
   3747        */
   3748       if (pp == NULL)
   3749          Throw ps;
   3750 
   3751       w = transform_width(pp, colour_type, bit_depth);
   3752       h = transform_height(pp, colour_type, bit_depth);
   3753 
   3754       png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
   3755          PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
   3756 
   3757 #ifdef PNG_TEXT_SUPPORTED
   3758 #  if defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED)
   3759 #     define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_zTXt
   3760 #  else
   3761 #     define TEXT_COMPRESSION PNG_TEXT_COMPRESSION_NONE
   3762 #  endif
   3763       {
   3764          static char key[] = "image name"; /* must be writeable */
   3765          size_t pos;
   3766          png_text text;
   3767          char copy[FILE_NAME_SIZE];
   3768 
   3769          /* Use a compressed text string to test the correct interaction of text
   3770           * compression and IDAT compression.
   3771           */
   3772          text.compression = TEXT_COMPRESSION;
   3773          text.key = key;
   3774          /* Yuck: the text must be writable! */
   3775          pos = safecat(copy, sizeof copy, 0, ps->wname);
   3776          text.text = copy;
   3777          text.text_length = pos;
   3778          text.itxt_length = 0;
   3779          text.lang = 0;
   3780          text.lang_key = 0;
   3781 
   3782          png_set_text(pp, pi, &text, 1);
   3783       }
   3784 #endif
   3785 
   3786       if (colour_type == 3) /* palette */
   3787          init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/);
   3788 
   3789 #     ifdef PNG_WRITE_tRNS_SUPPORTED
   3790          else if (palette_number)
   3791             set_random_tRNS(pp, pi, colour_type, bit_depth);
   3792 #     endif
   3793 
   3794       png_write_info(pp, pi);
   3795 
   3796       if (png_get_rowbytes(pp, pi) !=
   3797           transform_rowsize(pp, colour_type, bit_depth))
   3798          png_error(pp, "transform row size incorrect");
   3799 
   3800       else
   3801       {
   3802          /* Somewhat confusingly this must be called *after* png_write_info
   3803           * because if it is called before, the information in *pp has not been
   3804           * updated to reflect the interlaced image.
   3805           */
   3806          int npasses = set_write_interlace_handling(pp, interlace_type);
   3807          int pass;
   3808 
   3809          if (npasses != npasses_from_interlace_type(pp, interlace_type))
   3810             png_error(pp, "write: png_set_interlace_handling failed");
   3811 
   3812          for (pass=0; pass<npasses; ++pass)
   3813          {
   3814             png_uint_32 y;
   3815 
   3816             /* do_own_interlace is a pre-defined boolean (a #define) which is
   3817              * set if we have to work out the interlaced rows here.
   3818              */
   3819             for (y=0; y<h; ++y)
   3820             {
   3821                png_byte buffer[TRANSFORM_ROWMAX];
   3822 
   3823                transform_row(pp, buffer, colour_type, bit_depth, y);
   3824 
   3825 #              if do_own_interlace
   3826                   /* If do_own_interlace *and* the image is interlaced we need a
   3827                    * reduced interlace row; this may be reduced to empty.
   3828                    */
   3829                   if (interlace_type == PNG_INTERLACE_ADAM7)
   3830                   {
   3831                      /* The row must not be written if it doesn't exist, notice
   3832                       * that there are two conditions here, either the row isn't
   3833                       * ever in the pass or the row would be but isn't wide
   3834                       * enough to contribute any pixels.  In fact the wPass test
   3835                       * can be used to skip the whole y loop in this case.
   3836                       */
   3837                      if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
   3838                          PNG_PASS_COLS(w, pass) > 0)
   3839                         interlace_row(buffer, buffer,
   3840                               bit_size(pp, colour_type, bit_depth), w, pass,
   3841                               0/*data always bigendian*/);
   3842                      else
   3843                         continue;
   3844                   }
   3845 #              endif /* do_own_interlace */
   3846 
   3847                choose_random_filter(pp, pass == 0 && y == 0);
   3848                png_write_row(pp, buffer);
   3849             }
   3850          }
   3851       }
   3852 
   3853 #ifdef PNG_TEXT_SUPPORTED
   3854       {
   3855          static char key[] = "end marker";
   3856          static char comment[] = "end";
   3857          png_text text;
   3858 
   3859          /* Use a compressed text string to test the correct interaction of text
   3860           * compression and IDAT compression.
   3861           */
   3862          text.compression = TEXT_COMPRESSION;
   3863          text.key = key;
   3864          text.text = comment;
   3865          text.text_length = (sizeof comment)-1;
   3866          text.itxt_length = 0;
   3867          text.lang = 0;
   3868          text.lang_key = 0;
   3869 
   3870          png_set_text(pp, pi, &text, 1);
   3871       }
   3872 #endif
   3873 
   3874       png_write_end(pp, pi);
   3875 
   3876       /* And store this under the appropriate id, then clean up. */
   3877       store_storefile(ps, FILEID(colour_type, bit_depth, palette_number,
   3878          interlace_type, 0, 0, 0));
   3879 
   3880       store_write_reset(ps);
   3881    }
   3882 
   3883    Catch(fault)
   3884    {
   3885       /* Use the png_store returned by the exception. This may help the compiler
   3886        * because 'ps' is not used in this branch of the setjmp.  Note that fault
   3887        * and ps will always be the same value.
   3888        */
   3889       store_write_reset(fault);
   3890    }
   3891 }
   3892 
   3893 static void
   3894 make_transform_images(png_modifier *pm)
   3895 {
   3896    png_byte colour_type = 0;
   3897    png_byte bit_depth = 0;
   3898    unsigned int palette_number = 0;
   3899 
   3900    /* This is in case of errors. */
   3901    safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images");
   3902 
   3903    /* Use next_format to enumerate all the combinations we test, including
   3904     * generating multiple low bit depth palette images. Non-A images (palette
   3905     * and direct) are created with and without tRNS chunks.
   3906     */
   3907    while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1))
   3908    {
   3909       int interlace_type;
   3910 
   3911       for (interlace_type = PNG_INTERLACE_NONE;
   3912            interlace_type < INTERLACE_LAST; ++interlace_type)
   3913       {
   3914          char name[FILE_NAME_SIZE];
   3915 
   3916          standard_name(name, sizeof name, 0, colour_type, bit_depth,
   3917             palette_number, interlace_type, 0, 0, do_own_interlace);
   3918          make_transform_image(&pm->this, colour_type, bit_depth, palette_number,
   3919             interlace_type, name);
   3920       }
   3921    }
   3922 }
   3923 
   3924 /* Build a single row for the 'size' test images; this fills in only the
   3925  * first bit_width bits of the sample row.
   3926  */
   3927 static void
   3928 size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y)
   3929 {
   3930    /* height is in the range 1 to 16, so: */
   3931    y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4);
   3932    /* the following ensures bits are set in small images: */
   3933    y ^= 0xA5;
   3934 
   3935    while (bit_width >= 8)
   3936       *buffer++ = (png_byte)y++, bit_width -= 8;
   3937 
   3938    /* There may be up to 7 remaining bits, these go in the most significant
   3939     * bits of the byte.
   3940     */
   3941    if (bit_width > 0)
   3942    {
   3943       png_uint_32 mask = (1U<<(8-bit_width))-1;
   3944       *buffer = (png_byte)((*buffer & mask) | (y & ~mask));
   3945    }
   3946 }
   3947 
   3948 static void
   3949 make_size_image(png_store* const ps, png_byte const colour_type,
   3950     png_byte const bit_depth, int const interlace_type,
   3951     png_uint_32 const w, png_uint_32 const h,
   3952     int const do_interlace)
   3953 {
   3954    context(ps, fault);
   3955 
   3956    check_interlace_type(interlace_type);
   3957 
   3958    Try
   3959    {
   3960       png_infop pi;
   3961       png_structp pp;
   3962       unsigned int pixel_size;
   3963 
   3964       /* Make a name and get an appropriate id for the store: */
   3965       char name[FILE_NAME_SIZE];
   3966       const png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/,
   3967          interlace_type, w, h, do_interlace);
   3968 
   3969       standard_name_from_id(name, sizeof name, 0, id);
   3970       pp = set_store_for_write(ps, &pi, name);
   3971 
   3972       /* In the event of a problem return control to the Catch statement below
   3973        * to do the clean up - it is not possible to 'return' directly from a Try
   3974        * block.
   3975        */
   3976       if (pp == NULL)
   3977          Throw ps;
   3978 
   3979       png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
   3980          PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
   3981 
   3982 #ifdef PNG_TEXT_SUPPORTED
   3983       {
   3984          static char key[] = "image name"; /* must be writeable */
   3985          size_t pos;
   3986          png_text text;
   3987          char copy[FILE_NAME_SIZE];
   3988 
   3989          /* Use a compressed text string to test the correct interaction of text
   3990           * compression and IDAT compression.
   3991           */
   3992          text.compression = TEXT_COMPRESSION;
   3993          text.key = key;
   3994          /* Yuck: the text must be writable! */
   3995          pos = safecat(copy, sizeof copy, 0, ps->wname);
   3996          text.text = copy;
   3997          text.text_length = pos;
   3998          text.itxt_length = 0;
   3999          text.lang = 0;
   4000          text.lang_key = 0;
   4001 
   4002          png_set_text(pp, pi, &text, 1);
   4003       }
   4004 #endif
   4005 
   4006       if (colour_type == 3) /* palette */
   4007          init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
   4008 
   4009       png_write_info(pp, pi);
   4010 
   4011       /* Calculate the bit size, divide by 8 to get the byte size - this won't
   4012        * overflow because we know the w values are all small enough even for
   4013        * a system where 'unsigned int' is only 16 bits.
   4014        */
   4015       pixel_size = bit_size(pp, colour_type, bit_depth);
   4016       if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8)
   4017          png_error(pp, "size row size incorrect");
   4018 
   4019       else
   4020       {
   4021          int npasses = npasses_from_interlace_type(pp, interlace_type);
   4022          png_uint_32 y;
   4023          int pass;
   4024          png_byte image[16][SIZE_ROWMAX];
   4025 
   4026          /* To help consistent error detection make the parts of this buffer
   4027           * that aren't set below all '1':
   4028           */
   4029          memset(image, 0xff, sizeof image);
   4030 
   4031          if (!do_interlace &&
   4032              npasses != set_write_interlace_handling(pp, interlace_type))
   4033             png_error(pp, "write: png_set_interlace_handling failed");
   4034 
   4035          /* Prepare the whole image first to avoid making it 7 times: */
   4036          for (y=0; y<h; ++y)
   4037             size_row(image[y], w * pixel_size, y);
   4038 
   4039          for (pass=0; pass<npasses; ++pass)
   4040          {
   4041             /* The following two are for checking the macros: */
   4042             const png_uint_32 wPass = PNG_PASS_COLS(w, pass);
   4043 
   4044             /* If do_interlace is set we don't call png_write_row for every
   4045              * row because some of them are empty.  In fact, for a 1x1 image,
   4046              * most of them are empty!
   4047              */
   4048             for (y=0; y<h; ++y)
   4049             {
   4050                png_const_bytep row = image[y];
   4051                png_byte tempRow[SIZE_ROWMAX];
   4052 
   4053                /* If do_interlace *and* the image is interlaced we
   4054                 * need a reduced interlace row; this may be reduced
   4055                 * to empty.
   4056                 */
   4057                if (do_interlace && interlace_type == PNG_INTERLACE_ADAM7)
   4058                {
   4059                   /* The row must not be written if it doesn't exist, notice
   4060                    * that there are two conditions here, either the row isn't
   4061                    * ever in the pass or the row would be but isn't wide
   4062                    * enough to contribute any pixels.  In fact the wPass test
   4063                    * can be used to skip the whole y loop in this case.
   4064                    */
   4065                   if (PNG_ROW_IN_INTERLACE_PASS(y, pass) && wPass > 0)
   4066                   {
   4067                      /* Set to all 1's for error detection (libpng tends to
   4068                       * set unset things to 0).
   4069                       */
   4070                      memset(tempRow, 0xff, sizeof tempRow);
   4071                      interlace_row(tempRow, row, pixel_size, w, pass,
   4072                            0/*data always bigendian*/);
   4073                      row = tempRow;
   4074                   }
   4075                   else
   4076                      continue;
   4077                }
   4078 
   4079 #           ifdef PNG_WRITE_FILTER_SUPPORTED
   4080                /* Only get to here if the row has some pixels in it, set the
   4081                 * filters to 'all' for the very first row and thereafter to a
   4082                 * single filter.  It isn't well documented, but png_set_filter
   4083                 * does accept a filter number (per the spec) as well as a bit
   4084                 * mask.
   4085                 *
   4086                 * The code now uses filters at random, except that on the first
   4087                 * row of an image it ensures that a previous row filter is in
   4088                 * the set so that libpng allocates the row buffer.
   4089                 */
   4090                {
   4091                   int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST);
   4092 
   4093                   if (pass == 0 && y == 0 &&
   4094                       (filters < PNG_FILTER_UP || w == 1U))
   4095                      filters |= PNG_FILTER_UP;
   4096 
   4097                   png_set_filter(pp, 0/*method*/, filters);
   4098                }
   4099 #           endif
   4100 
   4101                png_write_row(pp, row);
   4102             }
   4103          }
   4104       }
   4105 
   4106 #ifdef PNG_TEXT_SUPPORTED
   4107       {
   4108          static char key[] = "end marker";
   4109          static char comment[] = "end";
   4110          png_text text;
   4111 
   4112          /* Use a compressed text string to test the correct interaction of text
   4113           * compression and IDAT compression.
   4114           */
   4115          text.compression = TEXT_COMPRESSION;
   4116          text.key = key;
   4117          text.text = comment;
   4118          text.text_length = (sizeof comment)-1;
   4119          text.itxt_length = 0;
   4120          text.lang = 0;
   4121          text.lang_key = 0;
   4122 
   4123          png_set_text(pp, pi, &text, 1);
   4124       }
   4125 #endif
   4126 
   4127       png_write_end(pp, pi);
   4128 
   4129       /* And store this under the appropriate id, then clean up. */
   4130       store_storefile(ps, id);
   4131 
   4132       store_write_reset(ps);
   4133    }
   4134 
   4135    Catch(fault)
   4136    {
   4137       /* Use the png_store returned by the exception. This may help the compiler
   4138        * because 'ps' is not used in this branch of the setjmp.  Note that fault
   4139        * and ps will always be the same value.
   4140        */
   4141       store_write_reset(fault);
   4142    }
   4143 }
   4144 
   4145 static void
   4146 make_size(png_store* const ps, png_byte const colour_type, int bdlo,
   4147     int const bdhi)
   4148 {
   4149    for (; bdlo <= bdhi; ++bdlo)
   4150    {
   4151       png_uint_32 width;
   4152 
   4153       for (width = 1; width <= 16; ++width)
   4154       {
   4155          png_uint_32 height;
   4156 
   4157          for (height = 1; height <= 16; ++height)
   4158          {
   4159             /* The four combinations of DIY interlace and interlace or not -
   4160              * no interlace + DIY should be identical to no interlace with
   4161              * libpng doing it.
   4162              */
   4163             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
   4164                width, height, 0);
   4165             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE,
   4166                width, height, 1);
   4167 #        ifdef PNG_WRITE_INTERLACING_SUPPORTED
   4168             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
   4169                width, height, 0);
   4170 #        endif
   4171 #        if CAN_WRITE_INTERLACE
   4172             /* 1.7.0 removes the hack that prevented app write of an interlaced
   4173              * image if WRITE_INTERLACE was not supported
   4174              */
   4175             make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7,
   4176                width, height, 1);
   4177 #        endif
   4178          }
   4179       }
   4180    }
   4181 }
   4182 
   4183 static void
   4184 make_size_images(png_store *ps)
   4185 {
   4186    /* This is in case of errors. */
   4187    safecat(ps->test, sizeof ps->test, 0, "make size images");
   4188 
   4189    /* Arguments are colour_type, low bit depth, high bit depth
   4190     */
   4191    make_size(ps, 0, 0, WRITE_BDHI);
   4192    make_size(ps, 2, 3, WRITE_BDHI);
   4193    make_size(ps, 3, 0, 3 /*palette: max 8 bits*/);
   4194    make_size(ps, 4, 3, WRITE_BDHI);
   4195    make_size(ps, 6, 3, WRITE_BDHI);
   4196 }
   4197 
   4198 #ifdef PNG_READ_SUPPORTED
   4199 /* Return a row based on image id and 'y' for checking: */
   4200 static void
   4201 standard_row(png_const_structp pp, png_byte std[STANDARD_ROWMAX],
   4202    png_uint_32 id, png_uint_32 y)
   4203 {
   4204    if (WIDTH_FROM_ID(id) == 0)
   4205       transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y);
   4206    else
   4207       size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id),
   4208          DEPTH_FROM_ID(id)), y);
   4209 }
   4210 #endif /* PNG_READ_SUPPORTED */
   4211 
   4212 /* Tests - individual test cases */
   4213 /* Like 'make_standard' but errors are deliberately introduced into the calls
   4214  * to ensure that they get detected - it should not be possible to write an
   4215  * invalid image with libpng!
   4216  */
   4217 /* TODO: the 'set' functions can probably all be made to take a
   4218  * png_const_structp rather than a modifiable one.
   4219  */
   4220 #ifdef PNG_WARNINGS_SUPPORTED
   4221 static void
   4222 sBIT0_error_fn(png_structp pp, png_infop pi)
   4223 {
   4224    /* 0 is invalid... */
   4225    png_color_8 bad;
   4226    bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0;
   4227    png_set_sBIT(pp, pi, &bad);
   4228 }
   4229 
   4230 static void
   4231 sBIT_error_fn(png_structp pp, png_infop pi)
   4232 {
   4233    png_byte bit_depth;
   4234    png_color_8 bad;
   4235 
   4236    if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE)
   4237       bit_depth = 8;
   4238 
   4239    else
   4240       bit_depth = png_get_bit_depth(pp, pi);
   4241 
   4242    /* Now we know the bit depth we can easily generate an invalid sBIT entry */
   4243    bad.red = bad.green = bad.blue = bad.gray = bad.alpha =
   4244       (png_byte)(bit_depth+1);
   4245    png_set_sBIT(pp, pi, &bad);
   4246 }
   4247 
   4248 static const struct
   4249 {
   4250    void          (*fn)(png_structp, png_infop);
   4251    const char *msg;
   4252    unsigned int    warning :1; /* the error is a warning... */
   4253 } error_test[] =
   4254     {
   4255        /* no warnings makes these errors undetectable prior to 1.7.0 */
   4256        { sBIT0_error_fn, "sBIT(0): failed to detect error",
   4257          PNG_LIBPNG_VER < 10700 },
   4258 
   4259        { sBIT_error_fn, "sBIT(too big): failed to detect error",
   4260          PNG_LIBPNG_VER < 10700 },
   4261     };
   4262 
   4263 static void
   4264 make_error(png_store* const ps, png_byte const colour_type,
   4265     png_byte bit_depth, int interlace_type, int test, png_const_charp name)
   4266 {
   4267    context(ps, fault);
   4268 
   4269    check_interlace_type(interlace_type);
   4270 
   4271    Try
   4272    {
   4273       png_infop pi;
   4274       const png_structp pp = set_store_for_write(ps, &pi, name);
   4275       png_uint_32 w, h;
   4276       gnu_volatile(pp)
   4277 
   4278       if (pp == NULL)
   4279          Throw ps;
   4280 
   4281       w = transform_width(pp, colour_type, bit_depth);
   4282       gnu_volatile(w)
   4283       h = transform_height(pp, colour_type, bit_depth);
   4284       gnu_volatile(h)
   4285       png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type,
   4286             PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
   4287 
   4288       if (colour_type == 3) /* palette */
   4289          init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/);
   4290 
   4291       /* Time for a few errors; these are in various optional chunks, the
   4292        * standard tests test the standard chunks pretty well.
   4293        */
   4294 #     define exception__prev exception_prev_1
   4295 #     define exception__env exception_env_1
   4296       Try
   4297       {
   4298          gnu_volatile(exception__prev)
   4299 
   4300          /* Expect this to throw: */
   4301          ps->expect_error = !error_test[test].warning;
   4302          ps->expect_warning = error_test[test].warning;
   4303          ps->saw_warning = 0;
   4304          error_test[test].fn(pp, pi);
   4305 
   4306          /* Normally the error is only detected here: */
   4307          png_write_info(pp, pi);
   4308 
   4309          /* And handle the case where it was only a warning: */
   4310          if (ps->expect_warning && ps->saw_warning)
   4311             Throw ps;
   4312 
   4313          /* If we get here there is a problem, we have success - no error or
   4314           * no warning - when we shouldn't have success.  Log an error.
   4315           */
   4316          store_log(ps, pp, error_test[test].msg, 1 /*error*/);
   4317       }
   4318 
   4319       Catch (fault)
   4320       { /* expected exit */
   4321       }
   4322 #undef exception__prev
   4323 #undef exception__env
   4324 
   4325       /* And clear these flags */
   4326       ps->expect_warning = 0;
   4327 
   4328       if (ps->expect_error)
   4329          ps->expect_error = 0;
   4330 
   4331       else
   4332       {
   4333          /* Now write the whole image, just to make sure that the detected, or
   4334           * undetected, errro has not created problems inside libpng.  This
   4335           * doesn't work if there was a png_error in png_write_info because that
   4336           * can abort before PLTE was written.
   4337           */
   4338          if (png_get_rowbytes(pp, pi) !=
   4339              transform_rowsize(pp, colour_type, bit_depth))
   4340             png_error(pp, "row size incorrect");
   4341 
   4342          else
   4343          {
   4344             int npasses = set_write_interlace_handling(pp, interlace_type);
   4345             int pass;
   4346 
   4347             if (npasses != npasses_from_interlace_type(pp, interlace_type))
   4348                png_error(pp, "write: png_set_interlace_handling failed");
   4349 
   4350             for (pass=0; pass<npasses; ++pass)
   4351             {
   4352                png_uint_32 y;
   4353 
   4354                for (y=0; y<h; ++y)
   4355                {
   4356                   png_byte buffer[TRANSFORM_ROWMAX];
   4357 
   4358                   transform_row(pp, buffer, colour_type, bit_depth, y);
   4359 
   4360 #                 if do_own_interlace
   4361                      /* If do_own_interlace *and* the image is interlaced we
   4362                       * need a reduced interlace row; this may be reduced to
   4363                       * empty.
   4364                       */
   4365                      if (interlace_type == PNG_INTERLACE_ADAM7)
   4366                      {
   4367                         /* The row must not be written if it doesn't exist,
   4368                          * notice that there are two conditions here, either the
   4369                          * row isn't ever in the pass or the row would be but
   4370                          * isn't wide enough to contribute any pixels.  In fact
   4371                          * the wPass test can be used to skip the whole y loop
   4372                          * in this case.
   4373                          */
   4374                         if (PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
   4375                             PNG_PASS_COLS(w, pass) > 0)
   4376                            interlace_row(buffer, buffer,
   4377                                  bit_size(pp, colour_type, bit_depth), w, pass,
   4378                                  0/*data always bigendian*/);
   4379                         else
   4380                            continue;
   4381                      }
   4382 #                 endif /* do_own_interlace */
   4383 
   4384                   png_write_row(pp, buffer);
   4385                }
   4386             }
   4387          } /* image writing */
   4388 
   4389          png_write_end(pp, pi);
   4390       }
   4391 
   4392       /* The following deletes the file that was just written. */
   4393       store_write_reset(ps);
   4394    }
   4395 
   4396    Catch(fault)
   4397    {
   4398       store_write_reset(fault);
   4399    }
   4400 }
   4401 
   4402 static int
   4403 make_errors(png_modifier* const pm, png_byte const colour_type,
   4404     int bdlo, int const bdhi)
   4405 {
   4406    for (; bdlo <= bdhi; ++bdlo)
   4407    {
   4408       int interlace_type;
   4409 
   4410       for (interlace_type = PNG_INTERLACE_NONE;
   4411            interlace_type < INTERLACE_LAST; ++interlace_type)
   4412       {
   4413          unsigned int test;
   4414          char name[FILE_NAME_SIZE];
   4415 
   4416          standard_name(name, sizeof name, 0, colour_type, 1<<bdlo, 0,
   4417             interlace_type, 0, 0, do_own_interlace);
   4418 
   4419          for (test=0; test<ARRAY_SIZE(error_test); ++test)
   4420          {
   4421             make_error(&pm->this, colour_type, DEPTH(bdlo), interlace_type,
   4422                test, name);
   4423 
   4424             if (fail(pm))
   4425                return 0;
   4426          }
   4427       }
   4428    }
   4429 
   4430    return 1; /* keep going */
   4431 }
   4432 #endif /* PNG_WARNINGS_SUPPORTED */
   4433 
   4434 static void
   4435 perform_error_test(png_modifier *pm)
   4436 {
   4437 #ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */
   4438    /* Need to do this here because we just write in this test. */
   4439    safecat(pm->this.test, sizeof pm->this.test, 0, "error test");
   4440 
   4441    if (!make_errors(pm, 0, 0, WRITE_BDHI))
   4442       return;
   4443 
   4444    if (!make_errors(pm, 2, 3, WRITE_BDHI))
   4445       return;
   4446 
   4447    if (!make_errors(pm, 3, 0, 3))
   4448       return;
   4449 
   4450    if (!make_errors(pm, 4, 3, WRITE_BDHI))
   4451       return;
   4452 
   4453    if (!make_errors(pm, 6, 3, WRITE_BDHI))
   4454       return;
   4455 #else
   4456    UNUSED(pm)
   4457 #endif
   4458 }
   4459 
   4460 /* This is just to validate the internal PNG formatting code - if this fails
   4461  * then the warning messages the library outputs will probably be garbage.
   4462  */
   4463 static void
   4464 perform_formatting_test(png_store *ps)
   4465 {
   4466 #ifdef PNG_TIME_RFC1123_SUPPORTED
   4467    /* The handle into the formatting code is the RFC1123 support; this test does
   4468     * nothing if that is compiled out.
   4469     */
   4470    context(ps, fault);
   4471 
   4472    Try
   4473    {
   4474       png_const_charp correct = "29 Aug 2079 13:53:60 +0000";
   4475       png_const_charp result;
   4476 #     if PNG_LIBPNG_VER >= 10600
   4477          char timestring[29];
   4478 #     endif
   4479       png_structp pp;
   4480       png_time pt;
   4481 
   4482       pp = set_store_for_write(ps, NULL, "libpng formatting test");
   4483 
   4484       if (pp == NULL)
   4485          Throw ps;
   4486 
   4487 
   4488       /* Arbitrary settings: */
   4489       pt.year = 2079;
   4490       pt.month = 8;
   4491       pt.day = 29;
   4492       pt.hour = 13;
   4493       pt.minute = 53;
   4494       pt.second = 60; /* a leap second */
   4495 
   4496 #     if PNG_LIBPNG_VER < 10600
   4497          result = png_convert_to_rfc1123(pp, &pt);
   4498 #     else
   4499          if (png_convert_to_rfc1123_buffer(timestring, &pt))
   4500             result = timestring;
   4501 
   4502          else
   4503             result = NULL;
   4504 #     endif
   4505 
   4506       if (result == NULL)
   4507          png_error(pp, "png_convert_to_rfc1123 failed");
   4508 
   4509       if (strcmp(result, correct) != 0)
   4510       {
   4511          size_t pos = 0;
   4512          char msg[128];
   4513 
   4514          pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123(");
   4515          pos = safecat(msg, sizeof msg, pos, correct);
   4516          pos = safecat(msg, sizeof msg, pos, ") returned: '");
   4517          pos = safecat(msg, sizeof msg, pos, result);
   4518          pos = safecat(msg, sizeof msg, pos, "'");
   4519 
   4520          png_error(pp, msg);
   4521       }
   4522 
   4523       store_write_reset(ps);
   4524    }
   4525 
   4526    Catch(fault)
   4527    {
   4528       store_write_reset(fault);
   4529    }
   4530 #else
   4531    UNUSED(ps)
   4532 #endif
   4533 }
   4534 
   4535 #ifdef PNG_READ_SUPPORTED
   4536 /* Because we want to use the same code in both the progressive reader and the
   4537  * sequential reader it is necessary to deal with the fact that the progressive
   4538  * reader callbacks only have one parameter (png_get_progressive_ptr()), so this
   4539  * must contain all the test parameters and all the local variables directly
   4540  * accessible to the sequential reader implementation.
   4541  *
   4542  * The technique adopted is to reinvent part of what Dijkstra termed a
   4543  * 'display'; an array of pointers to the stack frames of enclosing functions so
   4544  * that a nested function definition can access the local (C auto) variables of
   4545  * the functions that contain its definition.  In fact C provides the first
   4546  * pointer (the local variables - the stack frame pointer) and the last (the
   4547  * global variables - the BCPL global vector typically implemented as global
   4548  * addresses), this code requires one more pointer to make the display - the
   4549  * local variables (and function call parameters) of the function that actually
   4550  * invokes either the progressive or sequential reader.
   4551  *
   4552  * Perhaps confusingly this technique is confounded with classes - the
   4553  * 'standard_display' defined here is sub-classed as the 'gamma_display' below.
   4554  * A gamma_display is a standard_display, taking advantage of the ANSI-C
   4555  * requirement that the pointer to the first member of a structure must be the
   4556  * same as the pointer to the structure.  This allows us to reuse standard_
   4557  * functions in the gamma test code; something that could not be done with
   4558  * nested functions!
   4559  */
   4560 typedef struct standard_display
   4561 {
   4562    png_store*  ps;             /* Test parameters (passed to the function) */
   4563    png_byte    colour_type;
   4564    png_byte    bit_depth;
   4565    png_byte    red_sBIT;       /* Input data sBIT values. */
   4566    png_byte    green_sBIT;
   4567    png_byte    blue_sBIT;
   4568    png_byte    alpha_sBIT;
   4569    png_byte    interlace_type;
   4570    png_byte    filler;         /* Output has a filler */
   4571    png_uint_32 id;             /* Calculated file ID */
   4572    png_uint_32 w;              /* Width of image */
   4573    png_uint_32 h;              /* Height of image */
   4574    int         npasses;        /* Number of interlaced passes */
   4575    png_uint_32 pixel_size;     /* Width of one pixel in bits */
   4576    png_uint_32 bit_width;      /* Width of output row in bits */
   4577    size_t      cbRow;          /* Bytes in a row of the output image */
   4578    int         do_interlace;   /* Do interlacing internally */
   4579    int         littleendian;   /* App (row) data is little endian */
   4580    int         is_transparent; /* Transparency information was present. */
   4581    int         has_tRNS;       /* color type GRAY or RGB with a tRNS chunk. */
   4582    int         speed;          /* Doing a speed test */
   4583    int         use_update_info;/* Call update_info, not start_image */
   4584    struct
   4585    {
   4586       png_uint_16 red;
   4587       png_uint_16 green;
   4588       png_uint_16 blue;
   4589    }           transparent;    /* The transparent color, if set. */
   4590    int         npalette;       /* Number of entries in the palette. */
   4591    store_palette
   4592                palette;
   4593 } standard_display;
   4594 
   4595 static void
   4596 standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id,
   4597    int do_interlace, int use_update_info)
   4598 {
   4599    memset(dp, 0, sizeof *dp);
   4600 
   4601    dp->ps = ps;
   4602    dp->colour_type = COL_FROM_ID(id);
   4603    dp->bit_depth = DEPTH_FROM_ID(id);
   4604    if (dp->bit_depth < 1 || dp->bit_depth > 16)
   4605       internal_error(ps, "internal: bad bit depth");
   4606    if (dp->colour_type == 3)
   4607       dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8;
   4608    else
   4609       dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT =
   4610          dp->bit_depth;
   4611    dp->interlace_type = INTERLACE_FROM_ID(id);
   4612    check_interlace_type(dp->interlace_type);
   4613    dp->id = id;
   4614    /* All the rest are filled in after the read_info: */
   4615    dp->w = 0;
   4616    dp->h = 0;
   4617    dp->npasses = 0;
   4618    dp->pixel_size = 0;
   4619    dp->bit_width = 0;
   4620    dp->cbRow = 0;
   4621    dp->do_interlace = do_interlace;
   4622    dp->littleendian = 0;
   4623    dp->is_transparent = 0;
   4624    dp->speed = ps->speed;
   4625    dp->use_update_info = use_update_info;
   4626    dp->npalette = 0;
   4627    /* Preset the transparent color to black: */
   4628    memset(&dp->transparent, 0, sizeof dp->transparent);
   4629    /* Preset the palette to full intensity/opaque througout: */
   4630    memset(dp->palette, 0xff, sizeof dp->palette);
   4631 }
   4632 
   4633 /* Initialize the palette fields - this must be done later because the palette
   4634  * comes from the particular png_store_file that is selected.
   4635  */
   4636 static void
   4637 standard_palette_init(standard_display *dp)
   4638 {
   4639    store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette);
   4640 
   4641    /* The remaining entries remain white/opaque. */
   4642    if (dp->npalette > 0)
   4643    {
   4644       int i = dp->npalette;
   4645       memcpy(dp->palette, palette, i * sizeof *palette);
   4646 
   4647       /* Check for a non-opaque palette entry: */
   4648       while (--i >= 0)
   4649          if (palette[i].alpha < 255)
   4650             break;
   4651 
   4652 #     ifdef __GNUC__
   4653          /* GCC can't handle the more obviously optimizable version. */
   4654          if (i >= 0)
   4655             dp->is_transparent = 1;
   4656          else
   4657             dp->is_transparent = 0;
   4658 #     else
   4659          dp->is_transparent = (i >= 0);
   4660 #     endif
   4661    }
   4662 }
   4663 
   4664 /* Utility to read the palette from the PNG file and convert it into
   4665  * store_palette format.  This returns 1 if there is any transparency in the
   4666  * palette (it does not check for a transparent colour in the non-palette case.)
   4667  */
   4668 static int
   4669 read_palette(store_palette palette, int *npalette, png_const_structp pp,
   4670    png_infop pi)
   4671 {
   4672    png_colorp pal;
   4673    png_bytep trans_alpha;
   4674    int num;
   4675 
   4676    pal = 0;
   4677    *npalette = -1;
   4678 
   4679    if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE)
   4680    {
   4681       int i = *npalette;
   4682 
   4683       if (i <= 0 || i > 256)
   4684          png_error(pp, "validate: invalid PLTE count");
   4685 
   4686       while (--i >= 0)
   4687       {
   4688          palette[i].red = pal[i].red;
   4689          palette[i].green = pal[i].green;
   4690          palette[i].blue = pal[i].blue;
   4691       }
   4692 
   4693       /* Mark the remainder of the entries with a flag value (other than
   4694        * white/opaque which is the flag value stored above.)
   4695        */
   4696       memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette);
   4697    }
   4698 
   4699    else /* !png_get_PLTE */
   4700    {
   4701       if (*npalette != (-1))
   4702          png_error(pp, "validate: invalid PLTE result");
   4703       /* But there is no palette, so record this: */
   4704       *npalette = 0;
   4705       memset(palette, 113, sizeof (store_palette));
   4706    }
   4707 
   4708    trans_alpha = 0;
   4709    num = 2; /* force error below */
   4710    if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 &&
   4711       (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) &&
   4712       /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so
   4713        * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans,
   4714        * so in the above call we get a success, we get a pointer (who knows what
   4715        * to) and we get num_trans == 0:
   4716        */
   4717       !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */
   4718    {
   4719       int i;
   4720 
   4721       /* Any of these are crash-worthy - given the implementation of
   4722        * png_get_tRNS up to 1.5 an app won't crash if it just checks the
   4723        * result above and fails to check that the variables it passed have
   4724        * actually been filled in!  Note that if the app were to pass the
   4725        * last, png_color_16p, variable too it couldn't rely on this.
   4726        */
   4727       if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette)
   4728          png_error(pp, "validate: unexpected png_get_tRNS (palette) result");
   4729 
   4730       for (i=0; i<num; ++i)
   4731          palette[i].alpha = trans_alpha[i];
   4732 
   4733       for (num=*npalette; i<num; ++i)
   4734          palette[i].alpha = 255;
   4735 
   4736       for (; i<256; ++i)
   4737          palette[i].alpha = 33; /* flag value */
   4738 
   4739       return 1; /* transparency */
   4740    }
   4741 
   4742    else
   4743    {
   4744       /* No palette transparency - just set the alpha channel to opaque. */
   4745       int i;
   4746 
   4747       for (i=0, num=*npalette; i<num; ++i)
   4748          palette[i].alpha = 255;
   4749 
   4750       for (; i<256; ++i)
   4751          palette[i].alpha = 55; /* flag value */
   4752 
   4753       return 0; /* no transparency */
   4754    }
   4755 }
   4756 
   4757 /* Utility to validate the palette if it should not have changed (the
   4758  * non-transform case).
   4759  */
   4760 static void
   4761 standard_palette_validate(standard_display *dp, png_const_structp pp,
   4762    png_infop pi)
   4763 {
   4764    int npalette;
   4765    store_palette palette;
   4766 
   4767    if (read_palette(palette, &npalette, pp, pi) != dp->is_transparent)
   4768       png_error(pp, "validate: palette transparency changed");
   4769 
   4770    if (npalette != dp->npalette)
   4771    {
   4772       size_t pos = 0;
   4773       char msg[64];
   4774 
   4775       pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: ");
   4776       pos = safecatn(msg, sizeof msg, pos, dp->npalette);
   4777       pos = safecat(msg, sizeof msg, pos, " -> ");
   4778       pos = safecatn(msg, sizeof msg, pos, npalette);
   4779       png_error(pp, msg);
   4780    }
   4781 
   4782    {
   4783       int i = npalette; /* npalette is aliased */
   4784 
   4785       while (--i >= 0)
   4786          if (palette[i].red != dp->palette[i].red ||
   4787             palette[i].green != dp->palette[i].green ||
   4788             palette[i].blue != dp->palette[i].blue ||
   4789             palette[i].alpha != dp->palette[i].alpha)
   4790             png_error(pp, "validate: PLTE or tRNS chunk changed");
   4791    }
   4792 }
   4793 
   4794 /* By passing a 'standard_display' the progressive callbacks can be used
   4795  * directly by the sequential code, the functions suffixed "_imp" are the
   4796  * implementations, the functions without the suffix are the callbacks.
   4797  *
   4798  * The code for the info callback is split into two because this callback calls
   4799  * png_read_update_info or png_start_read_image and what gets called depends on
   4800  * whether the info needs updating (we want to test both calls in pngvalid.)
   4801  */
   4802 static void
   4803 standard_info_part1(standard_display *dp, png_structp pp, png_infop pi)
   4804 {
   4805    if (png_get_bit_depth(pp, pi) != dp->bit_depth)
   4806       png_error(pp, "validate: bit depth changed");
   4807 
   4808    if (png_get_color_type(pp, pi) != dp->colour_type)
   4809       png_error(pp, "validate: color type changed");
   4810 
   4811    if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE)
   4812       png_error(pp, "validate: filter type changed");
   4813 
   4814    if (png_get_interlace_type(pp, pi) != dp->interlace_type)
   4815       png_error(pp, "validate: interlacing changed");
   4816 
   4817    if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE)
   4818       png_error(pp, "validate: compression type changed");
   4819 
   4820    dp->w = png_get_image_width(pp, pi);
   4821 
   4822    if (dp->w != standard_width(pp, dp->id))
   4823       png_error(pp, "validate: image width changed");
   4824 
   4825    dp->h = png_get_image_height(pp, pi);
   4826 
   4827    if (dp->h != standard_height(pp, dp->id))
   4828       png_error(pp, "validate: image height changed");
   4829 
   4830    /* Record (but don't check at present) the input sBIT according to the colour
   4831     * type information.
   4832     */
   4833    {
   4834       png_color_8p sBIT = 0;
   4835 
   4836       if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT)
   4837       {
   4838          int sBIT_invalid = 0;
   4839 
   4840          if (sBIT == 0)
   4841             png_error(pp, "validate: unexpected png_get_sBIT result");
   4842 
   4843          if (dp->colour_type & PNG_COLOR_MASK_COLOR)
   4844          {
   4845             if (sBIT->red == 0 || sBIT->red > dp->bit_depth)
   4846                sBIT_invalid = 1;
   4847             else
   4848                dp->red_sBIT = sBIT->red;
   4849 
   4850             if (sBIT->green == 0 || sBIT->green > dp->bit_depth)
   4851                sBIT_invalid = 1;
   4852             else
   4853                dp->green_sBIT = sBIT->green;
   4854 
   4855             if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth)
   4856                sBIT_invalid = 1;
   4857             else
   4858                dp->blue_sBIT = sBIT->blue;
   4859          }
   4860 
   4861          else /* !COLOR */
   4862          {
   4863             if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth)
   4864                sBIT_invalid = 1;
   4865             else
   4866                dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray;
   4867          }
   4868 
   4869          /* All 8 bits in tRNS for a palette image are significant - see the
   4870           * spec.
   4871           */
   4872          if (dp->colour_type & PNG_COLOR_MASK_ALPHA)
   4873          {
   4874             if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth)
   4875                sBIT_invalid = 1;
   4876             else
   4877                dp->alpha_sBIT = sBIT->alpha;
   4878          }
   4879 
   4880          if (sBIT_invalid)
   4881             png_error(pp, "validate: sBIT value out of range");
   4882       }
   4883    }
   4884 
   4885    /* Important: this is validating the value *before* any transforms have been
   4886     * put in place.  It doesn't matter for the standard tests, where there are
   4887     * no transforms, but it does for other tests where rowbytes may change after
   4888     * png_read_update_info.
   4889     */
   4890    if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id))
   4891       png_error(pp, "validate: row size changed");
   4892 
   4893    /* Validate the colour type 3 palette (this can be present on other color
   4894     * types.)
   4895     */
   4896    standard_palette_validate(dp, pp, pi);
   4897 
   4898    /* In any case always check for a tranparent color (notice that the
   4899     * colour type 3 case must not give a successful return on the get_tRNS call
   4900     * with these arguments!)
   4901     */
   4902    {
   4903       png_color_16p trans_color = 0;
   4904 
   4905       if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS)
   4906       {
   4907          if (trans_color == 0)
   4908             png_error(pp, "validate: unexpected png_get_tRNS (color) result");
   4909 
   4910          switch (dp->colour_type)
   4911          {
   4912          case 0:
   4913             dp->transparent.red = dp->transparent.green = dp->transparent.blue =
   4914                trans_color->gray;
   4915             dp->has_tRNS = 1;
   4916             break;
   4917 
   4918          case 2:
   4919             dp->transparent.red = trans_color->red;
   4920             dp->transparent.green = trans_color->green;
   4921             dp->transparent.blue = trans_color->blue;
   4922             dp->has_tRNS = 1;
   4923             break;
   4924 
   4925          case 3:
   4926             /* Not expected because it should result in the array case
   4927              * above.
   4928              */
   4929             png_error(pp, "validate: unexpected png_get_tRNS result");
   4930             break;
   4931 
   4932          default:
   4933             png_error(pp, "validate: invalid tRNS chunk with alpha image");
   4934          }
   4935       }
   4936    }
   4937 
   4938    /* Read the number of passes - expected to match the value used when
   4939     * creating the image (interlaced or not).  This has the side effect of
   4940     * turning on interlace handling (if do_interlace is not set.)
   4941     */
   4942    dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type);
   4943    if (!dp->do_interlace)
   4944    {
   4945 #     ifdef PNG_READ_INTERLACING_SUPPORTED
   4946          if (dp->npasses != png_set_interlace_handling(pp))
   4947             png_error(pp, "validate: file changed interlace type");
   4948 #     else /* !READ_INTERLACING */
   4949          /* This should never happen: the relevant tests (!do_interlace) should
   4950           * not be run.
   4951           */
   4952          if (dp->npasses > 1)
   4953             png_error(pp, "validate: no libpng interlace support");
   4954 #     endif /* !READ_INTERLACING */
   4955    }
   4956 
   4957    /* Caller calls png_read_update_info or png_start_read_image now, then calls
   4958     * part2.
   4959     */
   4960 }
   4961 
   4962 /* This must be called *after* the png_read_update_info call to get the correct
   4963  * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed
   4964  * image.
   4965  */
   4966 static void
   4967 standard_info_part2(standard_display *dp, png_const_structp pp,
   4968     png_const_infop pi, int nImages)
   4969 {
   4970    /* Record cbRow now that it can be found. */
   4971    {
   4972       png_byte ct = png_get_color_type(pp, pi);
   4973       png_byte bd = png_get_bit_depth(pp, pi);
   4974 
   4975       if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) &&
   4976           dp->filler)
   4977           ct |= 4; /* handle filler as faked alpha channel */
   4978 
   4979       dp->pixel_size = bit_size(pp, ct, bd);
   4980    }
   4981    dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size;
   4982    dp->cbRow = png_get_rowbytes(pp, pi);
   4983 
   4984    /* Validate the rowbytes here again. */
   4985    if (dp->cbRow != (dp->bit_width+7)/8)
   4986       png_error(pp, "bad png_get_rowbytes calculation");
   4987 
   4988    /* Then ensure there is enough space for the output image(s). */
   4989    store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h);
   4990 }
   4991 
   4992 static void
   4993 standard_info_imp(standard_display *dp, png_structp pp, png_infop pi,
   4994     int nImages)
   4995 {
   4996    /* Note that the validation routine has the side effect of turning on
   4997     * interlace handling in the subsequent code.
   4998     */
   4999    standard_info_part1(dp, pp, pi);
   5000 
   5001    /* And the info callback has to call this (or png_read_update_info - see
   5002     * below in the png_modifier code for that variant.
   5003     */
   5004    if (dp->use_update_info)
   5005    {
   5006       /* For debugging the effect of multiple calls: */
   5007       int i = dp->use_update_info;
   5008       while (i-- > 0)
   5009          png_read_update_info(pp, pi);
   5010    }
   5011 
   5012    else
   5013       png_start_read_image(pp);
   5014 
   5015    /* Validate the height, width and rowbytes plus ensure that sufficient buffer
   5016     * exists for decoding the image.
   5017     */
   5018    standard_info_part2(dp, pp, pi, nImages);
   5019 }
   5020 
   5021 static void PNGCBAPI
   5022 standard_info(png_structp pp, png_infop pi)
   5023 {
   5024    standard_display *dp = voidcast(standard_display*,
   5025       png_get_progressive_ptr(pp));
   5026 
   5027    /* Call with nImages==1 because the progressive reader can only produce one
   5028     * image.
   5029     */
   5030    standard_info_imp(dp, pp, pi, 1 /*only one image*/);
   5031 }
   5032 
   5033 static void PNGCBAPI
   5034 progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass)
   5035 {
   5036    png_const_structp pp = ppIn;
   5037    const standard_display *dp = voidcast(standard_display*,
   5038       png_get_progressive_ptr(pp));
   5039 
   5040    /* When handling interlacing some rows will be absent in each pass, the
   5041     * callback still gets called, but with a NULL pointer.  This is checked
   5042     * in the 'else' clause below.  We need our own 'cbRow', but we can't call
   5043     * png_get_rowbytes because we got no info structure.
   5044     */
   5045    if (new_row != NULL)
   5046    {
   5047       png_bytep row;
   5048 
   5049       /* In the case where the reader doesn't do the interlace it gives
   5050        * us the y in the sub-image:
   5051        */
   5052       if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7)
   5053       {
   5054 #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
   5055          /* Use this opportunity to validate the png 'current' APIs: */
   5056          if (y != png_get_current_row_number(pp))
   5057             png_error(pp, "png_get_current_row_number is broken");
   5058 
   5059          if (pass != png_get_current_pass_number(pp))
   5060             png_error(pp, "png_get_current_pass_number is broken");
   5061 #endif /* USER_TRANSFORM_INFO */
   5062 
   5063          y = PNG_ROW_FROM_PASS_ROW(y, pass);
   5064       }
   5065 
   5066       /* Validate this just in case. */
   5067       if (y >= dp->h)
   5068          png_error(pp, "invalid y to progressive row callback");
   5069 
   5070       row = store_image_row(dp->ps, pp, 0, y);
   5071 
   5072       /* Combine the new row into the old: */
   5073 #ifdef PNG_READ_INTERLACING_SUPPORTED
   5074       if (dp->do_interlace)
   5075 #endif /* READ_INTERLACING */
   5076       {
   5077          if (dp->interlace_type == PNG_INTERLACE_ADAM7)
   5078             deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass,
   5079                   dp->littleendian);
   5080          else
   5081             row_copy(row, new_row, dp->pixel_size * dp->w, dp->littleendian);
   5082       }
   5083 #ifdef PNG_READ_INTERLACING_SUPPORTED
   5084       else
   5085          png_progressive_combine_row(pp, row, new_row);
   5086 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   5087    }
   5088 
   5089    else if (dp->interlace_type == PNG_INTERLACE_ADAM7 &&
   5090        PNG_ROW_IN_INTERLACE_PASS(y, pass) &&
   5091        PNG_PASS_COLS(dp->w, pass) > 0)
   5092       png_error(pp, "missing row in progressive de-interlacing");
   5093 }
   5094 
   5095 static void
   5096 sequential_row(standard_display *dp, png_structp pp, png_infop pi,
   5097     const int iImage, const int iDisplay)
   5098 {
   5099    const int         npasses = dp->npasses;
   5100    const int         do_interlace = dp->do_interlace &&
   5101       dp->interlace_type == PNG_INTERLACE_ADAM7;
   5102    const png_uint_32 height = standard_height(pp, dp->id);
   5103    const png_uint_32 width = standard_width(pp, dp->id);
   5104    const png_store*  ps = dp->ps;
   5105    int pass;
   5106 
   5107    for (pass=0; pass<npasses; ++pass)
   5108    {
   5109       png_uint_32 y;
   5110       png_uint_32 wPass = PNG_PASS_COLS(width, pass);
   5111 
   5112       for (y=0; y<height; ++y)
   5113       {
   5114          if (do_interlace)
   5115          {
   5116             /* wPass may be zero or this row may not be in this pass.
   5117              * png_read_row must not be called in either case.
   5118              */
   5119             if (wPass > 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass))
   5120             {
   5121                /* Read the row into a pair of temporary buffers, then do the
   5122                 * merge here into the output rows.
   5123                 */
   5124                png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX];
   5125 
   5126                /* The following aids (to some extent) error detection - we can
   5127                 * see where png_read_row wrote.  Use opposite values in row and
   5128                 * display to make this easier.  Don't use 0xff (which is used in
   5129                 * the image write code to fill unused bits) or 0 (which is a
   5130                 * likely value to overwrite unused bits with).
   5131                 */
   5132                memset(row, 0xc5, sizeof row);
   5133                memset(display, 0x5c, sizeof display);
   5134 
   5135                png_read_row(pp, row, display);
   5136 
   5137                if (iImage >= 0)
   5138                   deinterlace_row(store_image_row(ps, pp, iImage, y), row,
   5139                      dp->pixel_size, dp->w, pass, dp->littleendian);
   5140 
   5141                if (iDisplay >= 0)
   5142                   deinterlace_row(store_image_row(ps, pp, iDisplay, y), display,
   5143                      dp->pixel_size, dp->w, pass, dp->littleendian);
   5144             }
   5145          }
   5146          else
   5147             png_read_row(pp,
   5148                iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL,
   5149                iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL);
   5150       }
   5151    }
   5152 
   5153    /* And finish the read operation (only really necessary if the caller wants
   5154     * to find additional data in png_info from chunks after the last IDAT.)
   5155     */
   5156    png_read_end(pp, pi);
   5157 }
   5158 
   5159 #ifdef PNG_TEXT_SUPPORTED
   5160 static void
   5161 standard_check_text(png_const_structp pp, png_const_textp tp,
   5162    png_const_charp keyword, png_const_charp text)
   5163 {
   5164    char msg[1024];
   5165    size_t pos = safecat(msg, sizeof msg, 0, "text: ");
   5166    size_t ok;
   5167 
   5168    pos = safecat(msg, sizeof msg, pos, keyword);
   5169    pos = safecat(msg, sizeof msg, pos, ": ");
   5170    ok = pos;
   5171 
   5172    if (tp->compression != TEXT_COMPRESSION)
   5173    {
   5174       char buf[64];
   5175 
   5176       sprintf(buf, "compression [%d->%d], ", TEXT_COMPRESSION,
   5177          tp->compression);
   5178       pos = safecat(msg, sizeof msg, pos, buf);
   5179    }
   5180 
   5181    if (tp->key == NULL || strcmp(tp->key, keyword) != 0)
   5182    {
   5183       pos = safecat(msg, sizeof msg, pos, "keyword \"");
   5184       if (tp->key != NULL)
   5185       {
   5186          pos = safecat(msg, sizeof msg, pos, tp->key);
   5187          pos = safecat(msg, sizeof msg, pos, "\", ");
   5188       }
   5189 
   5190       else
   5191          pos = safecat(msg, sizeof msg, pos, "null, ");
   5192    }
   5193 
   5194    if (tp->text == NULL)
   5195       pos = safecat(msg, sizeof msg, pos, "text lost, ");
   5196 
   5197    else
   5198    {
   5199       if (tp->text_length != strlen(text))
   5200       {
   5201          char buf[64];
   5202          sprintf(buf, "text length changed[%lu->%lu], ",
   5203             (unsigned long)strlen(text), (unsigned long)tp->text_length);
   5204          pos = safecat(msg, sizeof msg, pos, buf);
   5205       }
   5206 
   5207       if (strcmp(tp->text, text) != 0)
   5208       {
   5209          pos = safecat(msg, sizeof msg, pos, "text becomes \"");
   5210          pos = safecat(msg, sizeof msg, pos, tp->text);
   5211          pos = safecat(msg, sizeof msg, pos, "\" (was \"");
   5212          pos = safecat(msg, sizeof msg, pos, text);
   5213          pos = safecat(msg, sizeof msg, pos, "\"), ");
   5214       }
   5215    }
   5216 
   5217    if (tp->itxt_length != 0)
   5218       pos = safecat(msg, sizeof msg, pos, "iTXt length set, ");
   5219 
   5220    if (tp->lang != NULL)
   5221    {
   5222       pos = safecat(msg, sizeof msg, pos, "iTXt language \"");
   5223       pos = safecat(msg, sizeof msg, pos, tp->lang);
   5224       pos = safecat(msg, sizeof msg, pos, "\", ");
   5225    }
   5226 
   5227    if (tp->lang_key != NULL)
   5228    {
   5229       pos = safecat(msg, sizeof msg, pos, "iTXt keyword \"");
   5230       pos = safecat(msg, sizeof msg, pos, tp->lang_key);
   5231       pos = safecat(msg, sizeof msg, pos, "\", ");
   5232    }
   5233 
   5234    if (pos > ok)
   5235    {
   5236       msg[pos-2] = '\0'; /* Remove the ", " at the end */
   5237       png_error(pp, msg);
   5238    }
   5239 }
   5240 
   5241 static void
   5242 standard_text_validate(standard_display *dp, png_const_structp pp,
   5243    png_infop pi, int check_end)
   5244 {
   5245    png_textp tp = NULL;
   5246    png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL);
   5247 
   5248    if (num_text == 2 && tp != NULL)
   5249    {
   5250       standard_check_text(pp, tp, "image name", dp->ps->current->name);
   5251 
   5252       /* This exists because prior to 1.5.18 the progressive reader left the
   5253        * png_struct z_stream unreset at the end of the image, so subsequent
   5254        * attempts to use it simply returns Z_STREAM_END.
   5255        */
   5256       if (check_end)
   5257          standard_check_text(pp, tp+1, "end marker", "end");
   5258    }
   5259 
   5260    else
   5261    {
   5262       char msg[64];
   5263 
   5264       sprintf(msg, "expected two text items, got %lu",
   5265          (unsigned long)num_text);
   5266       png_error(pp, msg);
   5267    }
   5268 }
   5269 #else
   5270 #  define standard_text_validate(dp,pp,pi,check_end) ((void)0)
   5271 #endif
   5272 
   5273 static void
   5274 standard_row_validate(standard_display *dp, png_const_structp pp,
   5275    int iImage, int iDisplay, png_uint_32 y)
   5276 {
   5277    int where;
   5278    png_byte std[STANDARD_ROWMAX];
   5279 
   5280    /* The row must be pre-initialized to the magic number here for the size
   5281     * tests to pass:
   5282     */
   5283    memset(std, 178, sizeof std);
   5284    standard_row(pp, std, dp->id, y);
   5285 
   5286    /* At the end both the 'row' and 'display' arrays should end up identical.
   5287     * In earlier passes 'row' will be partially filled in, with only the pixels
   5288     * that have been read so far, but 'display' will have those pixels
   5289     * replicated to fill the unread pixels while reading an interlaced image.
   5290     */
   5291    if (iImage >= 0 &&
   5292       (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y),
   5293             dp->bit_width)) != 0)
   5294    {
   5295       char msg[64];
   5296       sprintf(msg, "PNG image row[%lu][%d] changed from %.2x to %.2x",
   5297          (unsigned long)y, where-1, std[where-1],
   5298          store_image_row(dp->ps, pp, iImage, y)[where-1]);
   5299       png_error(pp, msg);
   5300    }
   5301 
   5302    if (iDisplay >= 0 &&
   5303       (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y),
   5304          dp->bit_width)) != 0)
   5305    {
   5306       char msg[64];
   5307       sprintf(msg, "display row[%lu][%d] changed from %.2x to %.2x",
   5308          (unsigned long)y, where-1, std[where-1],
   5309          store_image_row(dp->ps, pp, iDisplay, y)[where-1]);
   5310       png_error(pp, msg);
   5311    }
   5312 }
   5313 
   5314 static void
   5315 standard_image_validate(standard_display *dp, png_const_structp pp, int iImage,
   5316     int iDisplay)
   5317 {
   5318    png_uint_32 y;
   5319 
   5320    if (iImage >= 0)
   5321       store_image_check(dp->ps, pp, iImage);
   5322 
   5323    if (iDisplay >= 0)
   5324       store_image_check(dp->ps, pp, iDisplay);
   5325 
   5326    for (y=0; y<dp->h; ++y)
   5327       standard_row_validate(dp, pp, iImage, iDisplay, y);
   5328 
   5329    /* This avoids false positives if the validation code is never called! */
   5330    dp->ps->validated = 1;
   5331 }
   5332 
   5333 static void PNGCBAPI
   5334 standard_end(png_structp ppIn, png_infop pi)
   5335 {
   5336    png_const_structp pp = ppIn;
   5337    standard_display *dp = voidcast(standard_display*,
   5338       png_get_progressive_ptr(pp));
   5339 
   5340    UNUSED(pi)
   5341 
   5342    /* Validate the image - progressive reading only produces one variant for
   5343     * interlaced images.
   5344     */
   5345    standard_text_validate(dp, pp, pi,
   5346       PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/);
   5347    standard_image_validate(dp, pp, 0, -1);
   5348 }
   5349 
   5350 /* A single test run checking the standard image to ensure it is not damaged. */
   5351 static void
   5352 standard_test(png_store* const psIn, png_uint_32 const id,
   5353    int do_interlace, int use_update_info)
   5354 {
   5355    standard_display d;
   5356    context(psIn, fault);
   5357 
   5358    /* Set up the display (stack frame) variables from the arguments to the
   5359     * function and initialize the locals that are filled in later.
   5360     */
   5361    standard_display_init(&d, psIn, id, do_interlace, use_update_info);
   5362 
   5363    /* Everything is protected by a Try/Catch.  The functions called also
   5364     * typically have local Try/Catch blocks.
   5365     */
   5366    Try
   5367    {
   5368       png_structp pp;
   5369       png_infop pi;
   5370 
   5371       /* Get a png_struct for reading the image. This will throw an error if it
   5372        * fails, so we don't need to check the result.
   5373        */
   5374       pp = set_store_for_read(d.ps, &pi, d.id,
   5375          d.do_interlace ?  (d.ps->progressive ?
   5376             "pngvalid progressive deinterlacer" :
   5377             "pngvalid sequential deinterlacer") : (d.ps->progressive ?
   5378                "progressive reader" : "sequential reader"));
   5379 
   5380       /* Initialize the palette correctly from the png_store_file. */
   5381       standard_palette_init(&d);
   5382 
   5383       /* Introduce the correct read function. */
   5384       if (d.ps->progressive)
   5385       {
   5386          png_set_progressive_read_fn(pp, &d, standard_info, progressive_row,
   5387             standard_end);
   5388 
   5389          /* Now feed data into the reader until we reach the end: */
   5390          store_progressive_read(d.ps, pp, pi);
   5391       }
   5392       else
   5393       {
   5394          /* Note that this takes the store, not the display. */
   5395          png_set_read_fn(pp, d.ps, store_read);
   5396 
   5397          /* Check the header values: */
   5398          png_read_info(pp, pi);
   5399 
   5400          /* The code tests both versions of the images that the sequential
   5401           * reader can produce.
   5402           */
   5403          standard_info_imp(&d, pp, pi, 2 /*images*/);
   5404 
   5405          /* Need the total bytes in the image below; we can't get to this point
   5406           * unless the PNG file values have been checked against the expected
   5407           * values.
   5408           */
   5409          {
   5410             sequential_row(&d, pp, pi, 0, 1);
   5411 
   5412             /* After the last pass loop over the rows again to check that the
   5413              * image is correct.
   5414              */
   5415             if (!d.speed)
   5416             {
   5417                standard_text_validate(&d, pp, pi, 1/*check_end*/);
   5418                standard_image_validate(&d, pp, 0, 1);
   5419             }
   5420             else
   5421                d.ps->validated = 1;
   5422          }
   5423       }
   5424 
   5425       /* Check for validation. */
   5426       if (!d.ps->validated)
   5427          png_error(pp, "image read failed silently");
   5428 
   5429       /* Successful completion. */
   5430    }
   5431 
   5432    Catch(fault)
   5433       d.ps = fault; /* make sure this hasn't been clobbered. */
   5434 
   5435    /* In either case clean up the store. */
   5436    store_read_reset(d.ps);
   5437 }
   5438 
   5439 static int
   5440 test_standard(png_modifier* const pm, png_byte const colour_type,
   5441     int bdlo, int const bdhi)
   5442 {
   5443    for (; bdlo <= bdhi; ++bdlo)
   5444    {
   5445       int interlace_type;
   5446 
   5447       for (interlace_type = PNG_INTERLACE_NONE;
   5448            interlace_type < INTERLACE_LAST; ++interlace_type)
   5449       {
   5450          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5451             interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info);
   5452 
   5453          if (fail(pm))
   5454             return 0;
   5455       }
   5456    }
   5457 
   5458    return 1; /* keep going */
   5459 }
   5460 
   5461 static void
   5462 perform_standard_test(png_modifier *pm)
   5463 {
   5464    /* Test each colour type over the valid range of bit depths (expressed as
   5465     * log2(bit_depth) in turn, stop as soon as any error is detected.
   5466     */
   5467    if (!test_standard(pm, 0, 0, READ_BDHI))
   5468       return;
   5469 
   5470    if (!test_standard(pm, 2, 3, READ_BDHI))
   5471       return;
   5472 
   5473    if (!test_standard(pm, 3, 0, 3))
   5474       return;
   5475 
   5476    if (!test_standard(pm, 4, 3, READ_BDHI))
   5477       return;
   5478 
   5479    if (!test_standard(pm, 6, 3, READ_BDHI))
   5480       return;
   5481 }
   5482 
   5483 
   5484 /********************************** SIZE TESTS ********************************/
   5485 static int
   5486 test_size(png_modifier* const pm, png_byte const colour_type,
   5487     int bdlo, int const bdhi)
   5488 {
   5489    /* Run the tests on each combination.
   5490     *
   5491     * NOTE: on my 32 bit x86 each of the following blocks takes
   5492     * a total of 3.5 seconds if done across every combo of bit depth
   5493     * width and height.  This is a waste of time in practice, hence the
   5494     * hinc and winc stuff:
   5495     */
   5496    static const png_byte hinc[] = {1, 3, 11, 1, 5};
   5497    static const png_byte winc[] = {1, 9, 5, 7, 1};
   5498    const int save_bdlo = bdlo;
   5499 
   5500    for (; bdlo <= bdhi; ++bdlo)
   5501    {
   5502       png_uint_32 h, w;
   5503 
   5504       for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
   5505       {
   5506          /* First test all the 'size' images against the sequential
   5507           * reader using libpng to deinterlace (where required.)  This
   5508           * validates the write side of libpng.  There are four possibilities
   5509           * to validate.
   5510           */
   5511          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5512             PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/,
   5513             pm->use_update_info);
   5514 
   5515          if (fail(pm))
   5516             return 0;
   5517 
   5518          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5519             PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/,
   5520             pm->use_update_info);
   5521 
   5522          if (fail(pm))
   5523             return 0;
   5524 
   5525          /* Now validate the interlaced read side - do_interlace true,
   5526           * in the progressive case this does actually make a difference
   5527           * to the code used in the non-interlaced case too.
   5528           */
   5529          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5530             PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/,
   5531             pm->use_update_info);
   5532 
   5533          if (fail(pm))
   5534             return 0;
   5535 
   5536 #     if CAN_WRITE_INTERLACE
   5537          /* Validate the pngvalid code itself: */
   5538          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5539             PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/,
   5540             pm->use_update_info);
   5541 
   5542          if (fail(pm))
   5543             return 0;
   5544 #     endif
   5545       }
   5546    }
   5547 
   5548    /* Now do the tests of libpng interlace handling, after we have made sure
   5549     * that the pngvalid version works:
   5550     */
   5551    for (bdlo = save_bdlo; bdlo <= bdhi; ++bdlo)
   5552    {
   5553       png_uint_32 h, w;
   5554 
   5555       for (h=1; h<=16; h+=hinc[bdlo]) for (w=1; w<=16; w+=winc[bdlo])
   5556       {
   5557 #     ifdef PNG_READ_INTERLACING_SUPPORTED
   5558          /* Test with pngvalid generated interlaced images first; we have
   5559           * already verify these are ok (unless pngvalid has self-consistent
   5560           * read/write errors, which is unlikely), so this detects errors in the
   5561           * read side first:
   5562           */
   5563 #     if CAN_WRITE_INTERLACE
   5564          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5565             PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/,
   5566             pm->use_update_info);
   5567 
   5568          if (fail(pm))
   5569             return 0;
   5570 #     endif
   5571 #     endif /* READ_INTERLACING */
   5572 
   5573 #     ifdef PNG_WRITE_INTERLACING_SUPPORTED
   5574          /* Test the libpng write side against the pngvalid read side: */
   5575          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5576             PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/,
   5577             pm->use_update_info);
   5578 
   5579          if (fail(pm))
   5580             return 0;
   5581 #     endif
   5582 
   5583 #     ifdef PNG_READ_INTERLACING_SUPPORTED
   5584 #     ifdef PNG_WRITE_INTERLACING_SUPPORTED
   5585          /* Test both together: */
   5586          standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/,
   5587             PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/,
   5588             pm->use_update_info);
   5589 
   5590          if (fail(pm))
   5591             return 0;
   5592 #     endif
   5593 #     endif /* READ_INTERLACING */
   5594       }
   5595    }
   5596 
   5597    return 1; /* keep going */
   5598 }
   5599 
   5600 static void
   5601 perform_size_test(png_modifier *pm)
   5602 {
   5603    /* Test each colour type over the valid range of bit depths (expressed as
   5604     * log2(bit_depth) in turn, stop as soon as any error is detected.
   5605     */
   5606    if (!test_size(pm, 0, 0, READ_BDHI))
   5607       return;
   5608 
   5609    if (!test_size(pm, 2, 3, READ_BDHI))
   5610       return;
   5611 
   5612    /* For the moment don't do the palette test - it's a waste of time when
   5613     * compared to the grayscale test.
   5614     */
   5615 #if 0
   5616    if (!test_size(pm, 3, 0, 3))
   5617       return;
   5618 #endif
   5619 
   5620    if (!test_size(pm, 4, 3, READ_BDHI))
   5621       return;
   5622 
   5623    if (!test_size(pm, 6, 3, READ_BDHI))
   5624       return;
   5625 }
   5626 
   5627 
   5628 /******************************* TRANSFORM TESTS ******************************/
   5629 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   5630 /* A set of tests to validate libpng image transforms.  The possibilities here
   5631  * are legion because the transforms can be combined in a combinatorial
   5632  * fashion.  To deal with this some measure of restraint is required, otherwise
   5633  * the tests would take forever.
   5634  */
   5635 typedef struct image_pixel
   5636 {
   5637    /* A local (pngvalid) representation of a PNG pixel, in all its
   5638     * various forms.
   5639     */
   5640    unsigned int red, green, blue, alpha; /* For non-palette images. */
   5641    unsigned int palette_index;           /* For a palette image. */
   5642    png_byte     colour_type;             /* As in the spec. */
   5643    png_byte     bit_depth;               /* Defines bit size in row */
   5644    png_byte     sample_depth;            /* Scale of samples */
   5645    unsigned int have_tRNS :1;            /* tRNS chunk may need processing */
   5646    unsigned int swap_rgb :1;             /* RGB swapped to BGR */
   5647    unsigned int alpha_first :1;          /* Alpha at start, not end */
   5648    unsigned int alpha_inverted :1;       /* Alpha channel inverted */
   5649    unsigned int mono_inverted :1;        /* Gray channel inverted */
   5650    unsigned int swap16 :1;               /* Byte swap 16-bit components */
   5651    unsigned int littleendian :1;         /* High bits on right */
   5652    unsigned int sig_bits :1;             /* Pixel shifted (sig bits only) */
   5653 
   5654    /* For checking the code calculates double precision floating point values
   5655     * along with an error value, accumulated from the transforms.  Because an
   5656     * sBIT setting allows larger error bounds (indeed, by the spec, apparently
   5657     * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each
   5658     * channel is stored.  This sBIT value is folded in to the stored error value
   5659     * at the end of the application of the transforms to the pixel.
   5660     *
   5661     * If sig_bits is set above the red, green, blue and alpha values have been
   5662     * scaled so they only contain the significant bits of the component values.
   5663     */
   5664    double   redf, greenf, bluef, alphaf;
   5665    double   rede, greene, bluee, alphae;
   5666    png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT;
   5667 } image_pixel;
   5668 
   5669 /* Shared utility function, see below. */
   5670 static void
   5671 image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax,
   5672         unsigned int bMax, unsigned int aMax)
   5673 {
   5674    this->redf = this->red / (double)rMax;
   5675    this->greenf = this->green / (double)gMax;
   5676    this->bluef = this->blue / (double)bMax;
   5677    this->alphaf = this->alpha / (double)aMax;
   5678 
   5679    if (this->red < rMax)
   5680       this->rede = this->redf * DBL_EPSILON;
   5681    else
   5682       this->rede = 0;
   5683    if (this->green < gMax)
   5684       this->greene = this->greenf * DBL_EPSILON;
   5685    else
   5686       this->greene = 0;
   5687    if (this->blue < bMax)
   5688       this->bluee = this->bluef * DBL_EPSILON;
   5689    else
   5690       this->bluee = 0;
   5691    if (this->alpha < aMax)
   5692       this->alphae = this->alphaf * DBL_EPSILON;
   5693    else
   5694       this->alphae = 0;
   5695 }
   5696 
   5697 /* Initialize the structure for the next pixel - call this before doing any
   5698  * transforms and call it for each pixel since all the fields may need to be
   5699  * reset.
   5700  */
   5701 static void
   5702 image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type,
   5703     png_byte bit_depth, png_uint_32 x, store_palette palette,
   5704     const image_pixel *format /*from pngvalid transform of input*/)
   5705 {
   5706    const png_byte sample_depth = (png_byte)(colour_type ==
   5707       PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth);
   5708    const unsigned int max = (1U<<sample_depth)-1;
   5709    const int swap16 = (format != 0 && format->swap16);
   5710    const int littleendian = (format != 0 && format->littleendian);
   5711    const int sig_bits = (format != 0 && format->sig_bits);
   5712 
   5713    /* Initially just set everything to the same number and the alpha to opaque.
   5714     * Note that this currently assumes a simple palette where entry x has colour
   5715     * rgb(x,x,x)!
   5716     */
   5717    this->palette_index = this->red = this->green = this->blue =
   5718       sample(row, colour_type, bit_depth, x, 0, swap16, littleendian);
   5719    this->alpha = max;
   5720    this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT =
   5721       sample_depth;
   5722 
   5723    /* Then override as appropriate: */
   5724    if (colour_type == 3) /* palette */
   5725    {
   5726       /* This permits the caller to default to the sample value. */
   5727       if (palette != 0)
   5728       {
   5729          const unsigned int i = this->palette_index;
   5730 
   5731          this->red = palette[i].red;
   5732          this->green = palette[i].green;
   5733          this->blue = palette[i].blue;
   5734          this->alpha = palette[i].alpha;
   5735       }
   5736    }
   5737 
   5738    else /* not palette */
   5739    {
   5740       unsigned int i = 0;
   5741 
   5742       if ((colour_type & 4) != 0 && format != 0 && format->alpha_first)
   5743       {
   5744          this->alpha = this->red;
   5745          /* This handles the gray case for 'AG' pixels */
   5746          this->palette_index = this->red = this->green = this->blue =
   5747             sample(row, colour_type, bit_depth, x, 1, swap16, littleendian);
   5748          i = 1;
   5749       }
   5750 
   5751       if (colour_type & 2)
   5752       {
   5753          /* Green is second for both BGR and RGB: */
   5754          this->green = sample(row, colour_type, bit_depth, x, ++i, swap16,
   5755                  littleendian);
   5756 
   5757          if (format != 0 && format->swap_rgb) /* BGR */
   5758              this->red = sample(row, colour_type, bit_depth, x, ++i, swap16,
   5759                      littleendian);
   5760          else
   5761              this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16,
   5762                      littleendian);
   5763       }
   5764 
   5765       else /* grayscale */ if (format != 0 && format->mono_inverted)
   5766          this->red = this->green = this->blue = this->red ^ max;
   5767 
   5768       if ((colour_type & 4) != 0) /* alpha */
   5769       {
   5770          if (format == 0 || !format->alpha_first)
   5771              this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16,
   5772                      littleendian);
   5773 
   5774          if (format != 0 && format->alpha_inverted)
   5775             this->alpha ^= max;
   5776       }
   5777    }
   5778 
   5779    /* Calculate the scaled values, these are simply the values divided by
   5780     * 'max' and the error is initialized to the double precision epsilon value
   5781     * from the header file.
   5782     */
   5783    image_pixel_setf(this,
   5784       sig_bits ? (1U << format->red_sBIT)-1 : max,
   5785       sig_bits ? (1U << format->green_sBIT)-1 : max,
   5786       sig_bits ? (1U << format->blue_sBIT)-1 : max,
   5787       sig_bits ? (1U << format->alpha_sBIT)-1 : max);
   5788 
   5789    /* Store the input information for use in the transforms - these will
   5790     * modify the information.
   5791     */
   5792    this->colour_type = colour_type;
   5793    this->bit_depth = bit_depth;
   5794    this->sample_depth = sample_depth;
   5795    this->have_tRNS = 0;
   5796    this->swap_rgb = 0;
   5797    this->alpha_first = 0;
   5798    this->alpha_inverted = 0;
   5799    this->mono_inverted = 0;
   5800    this->swap16 = 0;
   5801    this->littleendian = 0;
   5802    this->sig_bits = 0;
   5803 }
   5804 
   5805 #if defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_GRAY_TO_RGB_SUPPORTED\
   5806    || defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_EXPAND_16_SUPPORTED\
   5807    || defined PNG_READ_BACKGROUND_SUPPORTED
   5808 /* Convert a palette image to an rgb image.  This necessarily converts the tRNS
   5809  * chunk at the same time, because the tRNS will be in palette form.  The way
   5810  * palette validation works means that the original palette is never updated,
   5811  * instead the image_pixel value from the row contains the RGB of the
   5812  * corresponding palette entry and *this* is updated.  Consequently this routine
   5813  * only needs to change the colour type information.
   5814  */
   5815 static void
   5816 image_pixel_convert_PLTE(image_pixel *this)
   5817 {
   5818    if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
   5819    {
   5820       if (this->have_tRNS)
   5821       {
   5822          this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
   5823          this->have_tRNS = 0;
   5824       }
   5825       else
   5826          this->colour_type = PNG_COLOR_TYPE_RGB;
   5827 
   5828       /* The bit depth of the row changes at this point too (notice that this is
   5829        * the row format, not the sample depth, which is separate.)
   5830        */
   5831       this->bit_depth = 8;
   5832    }
   5833 }
   5834 
   5835 /* Add an alpha channel; this will import the tRNS information because tRNS is
   5836  * not valid in an alpha image.  The bit depth will invariably be set to at
   5837  * least 8 prior to 1.7.0.  Palette images will be converted to alpha (using
   5838  * the above API).  With png_set_background the alpha channel is never expanded
   5839  * but this routine is used by pngvalid to simplify code; 'for_background'
   5840  * records this.
   5841  */
   5842 static void
   5843 image_pixel_add_alpha(image_pixel *this, const standard_display *display,
   5844    int for_background)
   5845 {
   5846    if (this->colour_type == PNG_COLOR_TYPE_PALETTE)
   5847       image_pixel_convert_PLTE(this);
   5848 
   5849    if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
   5850    {
   5851       if (this->colour_type == PNG_COLOR_TYPE_GRAY)
   5852       {
   5853 #        if PNG_LIBPNG_VER < 10700
   5854             if (!for_background && this->bit_depth < 8)
   5855                this->bit_depth = this->sample_depth = 8;
   5856 #        endif
   5857 
   5858          if (this->have_tRNS)
   5859          {
   5860             /* After 1.7 the expansion of bit depth only happens if there is a
   5861              * tRNS chunk to expand at this point.
   5862              */
   5863 #           if PNG_LIBPNG_VER >= 10700
   5864                if (!for_background && this->bit_depth < 8)
   5865                   this->bit_depth = this->sample_depth = 8;
   5866 #           endif
   5867 
   5868             this->have_tRNS = 0;
   5869 
   5870             /* Check the input, original, channel value here against the
   5871              * original tRNS gray chunk valie.
   5872              */
   5873             if (this->red == display->transparent.red)
   5874                this->alphaf = 0;
   5875             else
   5876                this->alphaf = 1;
   5877          }
   5878          else
   5879             this->alphaf = 1;
   5880 
   5881          this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
   5882       }
   5883 
   5884       else if (this->colour_type == PNG_COLOR_TYPE_RGB)
   5885       {
   5886          if (this->have_tRNS)
   5887          {
   5888             this->have_tRNS = 0;
   5889 
   5890             /* Again, check the exact input values, not the current transformed
   5891              * value!
   5892              */
   5893             if (this->red == display->transparent.red &&
   5894                this->green == display->transparent.green &&
   5895                this->blue == display->transparent.blue)
   5896                this->alphaf = 0;
   5897             else
   5898                this->alphaf = 1;
   5899          }
   5900          else
   5901             this->alphaf = 1;
   5902 
   5903          this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
   5904       }
   5905 
   5906       /* The error in the alpha is zero and the sBIT value comes from the
   5907        * original sBIT data (actually it will always be the original bit depth).
   5908        */
   5909       this->alphae = 0;
   5910       this->alpha_sBIT = display->alpha_sBIT;
   5911    }
   5912 }
   5913 #endif /* transforms that need image_pixel_add_alpha */
   5914 
   5915 struct transform_display;
   5916 typedef struct image_transform
   5917 {
   5918    /* The name of this transform: a string. */
   5919    const char *name;
   5920 
   5921    /* Each transform can be disabled from the command line: */
   5922    int enable;
   5923 
   5924    /* The global list of transforms; read only. */
   5925    struct image_transform *const list;
   5926 
   5927    /* The global count of the number of times this transform has been set on an
   5928     * image.
   5929     */
   5930    unsigned int global_use;
   5931 
   5932    /* The local count of the number of times this transform has been set. */
   5933    unsigned int local_use;
   5934 
   5935    /* The next transform in the list, each transform must call its own next
   5936     * transform after it has processed the pixel successfully.
   5937     */
   5938    const struct image_transform *next;
   5939 
   5940    /* A single transform for the image, expressed as a series of function
   5941     * callbacks and some space for values.
   5942     *
   5943     * First a callback to add any required modifications to the png_modifier;
   5944     * this gets called just before the modifier is set up for read.
   5945     */
   5946    void (*ini)(const struct image_transform *this,
   5947       struct transform_display *that);
   5948 
   5949    /* And a callback to set the transform on the current png_read_struct:
   5950     */
   5951    void (*set)(const struct image_transform *this,
   5952       struct transform_display *that, png_structp pp, png_infop pi);
   5953 
   5954    /* Then a transform that takes an input pixel in one PNG format or another
   5955     * and modifies it by a pngvalid implementation of the transform (thus
   5956     * duplicating the libpng intent without, we hope, duplicating the bugs
   5957     * in the libpng implementation!)  The png_structp is solely to allow error
   5958     * reporting via png_error and png_warning.
   5959     */
   5960    void (*mod)(const struct image_transform *this, image_pixel *that,
   5961       png_const_structp pp, const struct transform_display *display);
   5962 
   5963    /* Add this transform to the list and return true if the transform is
   5964     * meaningful for this colour type and bit depth - if false then the
   5965     * transform should have no effect on the image so there's not a lot of
   5966     * point running it.
   5967     */
   5968    int (*add)(struct image_transform *this,
   5969       const struct image_transform **that, png_byte colour_type,
   5970       png_byte bit_depth);
   5971 } image_transform;
   5972 
   5973 typedef struct transform_display
   5974 {
   5975    standard_display this;
   5976 
   5977    /* Parameters */
   5978    png_modifier*              pm;
   5979    const image_transform* transform_list;
   5980    unsigned int max_gamma_8;
   5981 
   5982    /* Local variables */
   5983    png_byte output_colour_type;
   5984    png_byte output_bit_depth;
   5985    png_byte unpacked;
   5986 
   5987    /* Modifications (not necessarily used.) */
   5988    gama_modification gama_mod;
   5989    chrm_modification chrm_mod;
   5990    srgb_modification srgb_mod;
   5991 } transform_display;
   5992 
   5993 /* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */
   5994 static void
   5995 transform_set_encoding(transform_display *this)
   5996 {
   5997    /* Set up the png_modifier '_current' fields then use these to determine how
   5998     * to add appropriate chunks.
   5999     */
   6000    png_modifier *pm = this->pm;
   6001 
   6002    modifier_set_encoding(pm);
   6003 
   6004    if (modifier_color_encoding_is_set(pm))
   6005    {
   6006       if (modifier_color_encoding_is_sRGB(pm))
   6007          srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE);
   6008 
   6009       else
   6010       {
   6011          /* Set gAMA and cHRM separately. */
   6012          gama_modification_init(&this->gama_mod, pm, pm->current_gamma);
   6013 
   6014          if (pm->current_encoding != 0)
   6015             chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding);
   6016       }
   6017    }
   6018 }
   6019 
   6020 /* Three functions to end the list: */
   6021 static void
   6022 image_transform_ini_end(const image_transform *this,
   6023    transform_display *that)
   6024 {
   6025    UNUSED(this)
   6026    UNUSED(that)
   6027 }
   6028 
   6029 static void
   6030 image_transform_set_end(const image_transform *this,
   6031    transform_display *that, png_structp pp, png_infop pi)
   6032 {
   6033    UNUSED(this)
   6034    UNUSED(that)
   6035    UNUSED(pp)
   6036    UNUSED(pi)
   6037 }
   6038 
   6039 /* At the end of the list recalculate the output image pixel value from the
   6040  * double precision values set up by the preceding 'mod' calls:
   6041  */
   6042 static unsigned int
   6043 sample_scale(double sample_value, unsigned int scale)
   6044 {
   6045    sample_value = floor(sample_value * scale + .5);
   6046 
   6047    /* Return NaN as 0: */
   6048    if (!(sample_value > 0))
   6049       sample_value = 0;
   6050    else if (sample_value > scale)
   6051       sample_value = scale;
   6052 
   6053    return (unsigned int)sample_value;
   6054 }
   6055 
   6056 static void
   6057 image_transform_mod_end(const image_transform *this, image_pixel *that,
   6058     png_const_structp pp, const transform_display *display)
   6059 {
   6060    const unsigned int scale = (1U<<that->sample_depth)-1;
   6061    const int sig_bits = that->sig_bits;
   6062 
   6063    UNUSED(this)
   6064    UNUSED(pp)
   6065    UNUSED(display)
   6066 
   6067    /* At the end recalculate the digitized red green and blue values according
   6068     * to the current sample_depth of the pixel.
   6069     *
   6070     * The sample value is simply scaled to the maximum, checking for over
   6071     * and underflow (which can both happen for some image transforms,
   6072     * including simple size scaling, though libpng doesn't do that at present.
   6073     */
   6074    that->red = sample_scale(that->redf, scale);
   6075 
   6076    /* This is a bit bogus; really the above calculation should use the red_sBIT
   6077     * value, not sample_depth, but because libpng does png_set_shift by just
   6078     * shifting the bits we get errors if we don't do it the same way.
   6079     */
   6080    if (sig_bits && that->red_sBIT < that->sample_depth)
   6081       that->red >>= that->sample_depth - that->red_sBIT;
   6082 
   6083    /* The error value is increased, at the end, according to the lowest sBIT
   6084     * value seen.  Common sense tells us that the intermediate integer
   6085     * representations are no more accurate than +/- 0.5 in the integral values,
   6086     * the sBIT allows the implementation to be worse than this.  In addition the
   6087     * PNG specification actually permits any error within the range (-1..+1),
   6088     * but that is ignored here.  Instead the final digitized value is compared,
   6089     * below to the digitized value of the error limits - this has the net effect
   6090     * of allowing (almost) +/-1 in the output value.  It's difficult to see how
   6091     * any algorithm that digitizes intermediate results can be more accurate.
   6092     */
   6093    that->rede += 1./(2*((1U<<that->red_sBIT)-1));
   6094 
   6095    if (that->colour_type & PNG_COLOR_MASK_COLOR)
   6096    {
   6097       that->green = sample_scale(that->greenf, scale);
   6098       if (sig_bits && that->green_sBIT < that->sample_depth)
   6099          that->green >>= that->sample_depth - that->green_sBIT;
   6100 
   6101       that->blue = sample_scale(that->bluef, scale);
   6102       if (sig_bits && that->blue_sBIT < that->sample_depth)
   6103          that->blue >>= that->sample_depth - that->blue_sBIT;
   6104 
   6105       that->greene += 1./(2*((1U<<that->green_sBIT)-1));
   6106       that->bluee += 1./(2*((1U<<that->blue_sBIT)-1));
   6107    }
   6108    else
   6109    {
   6110       that->blue = that->green = that->red;
   6111       that->bluef = that->greenf = that->redf;
   6112       that->bluee = that->greene = that->rede;
   6113    }
   6114 
   6115    if ((that->colour_type & PNG_COLOR_MASK_ALPHA) ||
   6116       that->colour_type == PNG_COLOR_TYPE_PALETTE)
   6117    {
   6118       that->alpha = sample_scale(that->alphaf, scale);
   6119       that->alphae += 1./(2*((1U<<that->alpha_sBIT)-1));
   6120    }
   6121    else
   6122    {
   6123       that->alpha = scale; /* opaque */
   6124       that->alphaf = 1;    /* Override this. */
   6125       that->alphae = 0;    /* It's exact ;-) */
   6126    }
   6127 
   6128    if (sig_bits && that->alpha_sBIT < that->sample_depth)
   6129       that->alpha >>= that->sample_depth - that->alpha_sBIT;
   6130 }
   6131 
   6132 /* Static 'end' structure: */
   6133 static image_transform image_transform_end =
   6134 {
   6135    "(end)", /* name */
   6136    1, /* enable */
   6137    0, /* list */
   6138    0, /* global_use */
   6139    0, /* local_use */
   6140    0, /* next */
   6141    image_transform_ini_end,
   6142    image_transform_set_end,
   6143    image_transform_mod_end,
   6144    0 /* never called, I want it to crash if it is! */
   6145 };
   6146 
   6147 /* Reader callbacks and implementations, where they differ from the standard
   6148  * ones.
   6149  */
   6150 static void
   6151 transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id,
   6152     const image_transform *transform_list)
   6153 {
   6154    memset(dp, 0, sizeof *dp);
   6155 
   6156    /* Standard fields */
   6157    standard_display_init(&dp->this, &pm->this, id, do_read_interlace,
   6158       pm->use_update_info);
   6159 
   6160    /* Parameter fields */
   6161    dp->pm = pm;
   6162    dp->transform_list = transform_list;
   6163    dp->max_gamma_8 = 16;
   6164 
   6165    /* Local variable fields */
   6166    dp->output_colour_type = 255; /* invalid */
   6167    dp->output_bit_depth = 255;  /* invalid */
   6168    dp->unpacked = 0; /* not unpacked */
   6169 }
   6170 
   6171 static void
   6172 transform_info_imp(transform_display *dp, png_structp pp, png_infop pi)
   6173 {
   6174    /* Reuse the standard stuff as appropriate. */
   6175    standard_info_part1(&dp->this, pp, pi);
   6176 
   6177    /* Now set the list of transforms. */
   6178    dp->transform_list->set(dp->transform_list, dp, pp, pi);
   6179 
   6180    /* Update the info structure for these transforms: */
   6181    {
   6182       int i = dp->this.use_update_info;
   6183       /* Always do one call, even if use_update_info is 0. */
   6184       do
   6185          png_read_update_info(pp, pi);
   6186       while (--i > 0);
   6187    }
   6188 
   6189    /* And get the output information into the standard_display */
   6190    standard_info_part2(&dp->this, pp, pi, 1/*images*/);
   6191 
   6192    /* Plus the extra stuff we need for the transform tests: */
   6193    dp->output_colour_type = png_get_color_type(pp, pi);
   6194    dp->output_bit_depth = png_get_bit_depth(pp, pi);
   6195 
   6196    /* If png_set_filler is in action then fake the output color type to include
   6197     * an alpha channel where appropriate.
   6198     */
   6199    if (dp->output_bit_depth >= 8 &&
   6200        (dp->output_colour_type == PNG_COLOR_TYPE_RGB ||
   6201         dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler)
   6202        dp->output_colour_type |= 4;
   6203 
   6204    /* Validate the combination of colour type and bit depth that we are getting
   6205     * out of libpng; the semantics of something not in the PNG spec are, at
   6206     * best, unclear.
   6207     */
   6208    switch (dp->output_colour_type)
   6209    {
   6210    case PNG_COLOR_TYPE_PALETTE:
   6211       if (dp->output_bit_depth > 8) goto error;
   6212       /*FALL THROUGH*/
   6213    case PNG_COLOR_TYPE_GRAY:
   6214       if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 ||
   6215          dp->output_bit_depth == 4)
   6216          break;
   6217       /*FALL THROUGH*/
   6218    default:
   6219       if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16)
   6220          break;
   6221       /*FALL THROUGH*/
   6222    error:
   6223       {
   6224          char message[128];
   6225          size_t pos;
   6226 
   6227          pos = safecat(message, sizeof message, 0,
   6228             "invalid final bit depth: colour type(");
   6229          pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
   6230          pos = safecat(message, sizeof message, pos, ") with bit depth: ");
   6231          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
   6232 
   6233          png_error(pp, message);
   6234       }
   6235    }
   6236 
   6237    /* Use a test pixel to check that the output agrees with what we expect -
   6238     * this avoids running the whole test if the output is unexpected.  This also
   6239     * checks for internal errors.
   6240     */
   6241    {
   6242       image_pixel test_pixel;
   6243 
   6244       memset(&test_pixel, 0, sizeof test_pixel);
   6245       test_pixel.colour_type = dp->this.colour_type; /* input */
   6246       test_pixel.bit_depth = dp->this.bit_depth;
   6247       if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE)
   6248          test_pixel.sample_depth = 8;
   6249       else
   6250          test_pixel.sample_depth = test_pixel.bit_depth;
   6251       /* Don't need sBIT here, but it must be set to non-zero to avoid
   6252        * arithmetic overflows.
   6253        */
   6254       test_pixel.have_tRNS = dp->this.is_transparent != 0;
   6255       test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT =
   6256          test_pixel.alpha_sBIT = test_pixel.sample_depth;
   6257 
   6258       dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp);
   6259 
   6260       if (test_pixel.colour_type != dp->output_colour_type)
   6261       {
   6262          char message[128];
   6263          size_t pos = safecat(message, sizeof message, 0, "colour type ");
   6264 
   6265          pos = safecatn(message, sizeof message, pos, dp->output_colour_type);
   6266          pos = safecat(message, sizeof message, pos, " expected ");
   6267          pos = safecatn(message, sizeof message, pos, test_pixel.colour_type);
   6268 
   6269          png_error(pp, message);
   6270       }
   6271 
   6272       if (test_pixel.bit_depth != dp->output_bit_depth)
   6273       {
   6274          char message[128];
   6275          size_t pos = safecat(message, sizeof message, 0, "bit depth ");
   6276 
   6277          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
   6278          pos = safecat(message, sizeof message, pos, " expected ");
   6279          pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
   6280 
   6281          png_error(pp, message);
   6282       }
   6283 
   6284       /* If both bit depth and colour type are correct check the sample depth.
   6285        */
   6286       if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE &&
   6287           test_pixel.sample_depth != 8) /* oops - internal error! */
   6288          png_error(pp, "pngvalid: internal: palette sample depth not 8");
   6289       else if (dp->unpacked && test_pixel.bit_depth != 8)
   6290          png_error(pp, "pngvalid: internal: bad unpacked pixel depth");
   6291       else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE
   6292               && test_pixel.bit_depth != test_pixel.sample_depth)
   6293       {
   6294          char message[128];
   6295          size_t pos = safecat(message, sizeof message, 0,
   6296             "internal: sample depth ");
   6297 
   6298          /* Because unless something has set 'unpacked' or the image is palette
   6299           * mapped we expect the transform to keep sample depth and bit depth
   6300           * the same.
   6301           */
   6302          pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth);
   6303          pos = safecat(message, sizeof message, pos, " expected ");
   6304          pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
   6305 
   6306          png_error(pp, message);
   6307       }
   6308       else if (test_pixel.bit_depth != dp->output_bit_depth)
   6309       {
   6310          /* This could be a libpng error too; libpng has not produced what we
   6311           * expect for the output bit depth.
   6312           */
   6313          char message[128];
   6314          size_t pos = safecat(message, sizeof message, 0,
   6315             "internal: bit depth ");
   6316 
   6317          pos = safecatn(message, sizeof message, pos, dp->output_bit_depth);
   6318          pos = safecat(message, sizeof message, pos, " expected ");
   6319          pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth);
   6320 
   6321          png_error(pp, message);
   6322       }
   6323    }
   6324 }
   6325 
   6326 static void PNGCBAPI
   6327 transform_info(png_structp pp, png_infop pi)
   6328 {
   6329    transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)),
   6330       pp, pi);
   6331 }
   6332 
   6333 static void
   6334 transform_range_check(png_const_structp pp, unsigned int r, unsigned int g,
   6335    unsigned int b, unsigned int a, unsigned int in_digitized, double in,
   6336    unsigned int out, png_byte sample_depth, double err, double limit,
   6337    const char *name, double digitization_error)
   6338 {
   6339    /* Compare the scaled, digitzed, values of our local calculation (in+-err)
   6340     * with the digitized values libpng produced;  'sample_depth' is the actual
   6341     * digitization depth of the libpng output colors (the bit depth except for
   6342     * palette images where it is always 8.)  The check on 'err' is to detect
   6343     * internal errors in pngvalid itself.
   6344     */
   6345    unsigned int max = (1U<<sample_depth)-1;
   6346    double in_min = ceil((in-err)*max - digitization_error);
   6347    double in_max = floor((in+err)*max + digitization_error);
   6348    if (debugonly(err > limit ||) !(out >= in_min && out <= in_max))
   6349    {
   6350       char message[256];
   6351       size_t pos;
   6352 
   6353       pos = safecat(message, sizeof message, 0, name);
   6354       pos = safecat(message, sizeof message, pos, " output value error: rgba(");
   6355       pos = safecatn(message, sizeof message, pos, r);
   6356       pos = safecat(message, sizeof message, pos, ",");
   6357       pos = safecatn(message, sizeof message, pos, g);
   6358       pos = safecat(message, sizeof message, pos, ",");
   6359       pos = safecatn(message, sizeof message, pos, b);
   6360       pos = safecat(message, sizeof message, pos, ",");
   6361       pos = safecatn(message, sizeof message, pos, a);
   6362       pos = safecat(message, sizeof message, pos, "): ");
   6363       pos = safecatn(message, sizeof message, pos, out);
   6364       pos = safecat(message, sizeof message, pos, " expected: ");
   6365       pos = safecatn(message, sizeof message, pos, in_digitized);
   6366       pos = safecat(message, sizeof message, pos, " (");
   6367       pos = safecatd(message, sizeof message, pos, (in-err)*max, 3);
   6368       pos = safecat(message, sizeof message, pos, "..");
   6369       pos = safecatd(message, sizeof message, pos, (in+err)*max, 3);
   6370       pos = safecat(message, sizeof message, pos, ")");
   6371 
   6372       png_error(pp, message);
   6373    }
   6374 
   6375    UNUSED(limit)
   6376 }
   6377 
   6378 static void
   6379 transform_image_validate(transform_display *dp, png_const_structp pp,
   6380    png_infop pi)
   6381 {
   6382    /* Constants for the loop below: */
   6383    const png_store* const ps = dp->this.ps;
   6384    const png_byte in_ct = dp->this.colour_type;
   6385    const png_byte in_bd = dp->this.bit_depth;
   6386    const png_uint_32 w = dp->this.w;
   6387    const png_uint_32 h = dp->this.h;
   6388    const png_byte out_ct = dp->output_colour_type;
   6389    const png_byte out_bd = dp->output_bit_depth;
   6390    const png_byte sample_depth = (png_byte)(out_ct ==
   6391       PNG_COLOR_TYPE_PALETTE ? 8 : out_bd);
   6392    const png_byte red_sBIT = dp->this.red_sBIT;
   6393    const png_byte green_sBIT = dp->this.green_sBIT;
   6394    const png_byte blue_sBIT = dp->this.blue_sBIT;
   6395    const png_byte alpha_sBIT = dp->this.alpha_sBIT;
   6396    const int have_tRNS = dp->this.is_transparent;
   6397    double digitization_error;
   6398 
   6399    store_palette out_palette;
   6400    png_uint_32 y;
   6401 
   6402    UNUSED(pi)
   6403 
   6404    /* Check for row overwrite errors */
   6405    store_image_check(dp->this.ps, pp, 0);
   6406 
   6407    /* Read the palette corresponding to the output if the output colour type
   6408     * indicates a palette, othewise set out_palette to garbage.
   6409     */
   6410    if (out_ct == PNG_COLOR_TYPE_PALETTE)
   6411    {
   6412       /* Validate that the palette count itself has not changed - this is not
   6413        * expected.
   6414        */
   6415       int npalette = (-1);
   6416 
   6417       (void)read_palette(out_palette, &npalette, pp, pi);
   6418       if (npalette != dp->this.npalette)
   6419          png_error(pp, "unexpected change in palette size");
   6420 
   6421       digitization_error = .5;
   6422    }
   6423    else
   6424    {
   6425       png_byte in_sample_depth;
   6426 
   6427       memset(out_palette, 0x5e, sizeof out_palette);
   6428 
   6429       /* use-input-precision means assume that if the input has 8 bit (or less)
   6430        * samples and the output has 16 bit samples the calculations will be done
   6431        * with 8 bit precision, not 16.
   6432        */
   6433       if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16)
   6434          in_sample_depth = 8;
   6435       else
   6436          in_sample_depth = in_bd;
   6437 
   6438       if (sample_depth != 16 || in_sample_depth > 8 ||
   6439          !dp->pm->calculations_use_input_precision)
   6440          digitization_error = .5;
   6441 
   6442       /* Else calculations are at 8 bit precision, and the output actually
   6443        * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits:
   6444        */
   6445       else
   6446          digitization_error = .5 * 257;
   6447    }
   6448 
   6449    for (y=0; y<h; ++y)
   6450    {
   6451       png_const_bytep const pRow = store_image_row(ps, pp, 0, y);
   6452       png_uint_32 x;
   6453 
   6454       /* The original, standard, row pre-transforms. */
   6455       png_byte std[STANDARD_ROWMAX];
   6456 
   6457       transform_row(pp, std, in_ct, in_bd, y);
   6458 
   6459       /* Go through each original pixel transforming it and comparing with what
   6460        * libpng did to the same pixel.
   6461        */
   6462       for (x=0; x<w; ++x)
   6463       {
   6464          image_pixel in_pixel, out_pixel;
   6465          unsigned int r, g, b, a;
   6466 
   6467          /* Find out what we think the pixel should be: */
   6468          image_pixel_init(&in_pixel, std, in_ct, in_bd, x, dp->this.palette,
   6469                  NULL);
   6470 
   6471          in_pixel.red_sBIT = red_sBIT;
   6472          in_pixel.green_sBIT = green_sBIT;
   6473          in_pixel.blue_sBIT = blue_sBIT;
   6474          in_pixel.alpha_sBIT = alpha_sBIT;
   6475          in_pixel.have_tRNS = have_tRNS != 0;
   6476 
   6477          /* For error detection, below. */
   6478          r = in_pixel.red;
   6479          g = in_pixel.green;
   6480          b = in_pixel.blue;
   6481          a = in_pixel.alpha;
   6482 
   6483          /* This applies the transforms to the input data, including output
   6484           * format operations which must be used when reading the output
   6485           * pixel that libpng produces.
   6486           */
   6487          dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp);
   6488 
   6489          /* Read the output pixel and compare it to what we got, we don't
   6490           * use the error field here, so no need to update sBIT.  in_pixel
   6491           * says whether we expect libpng to change the output format.
   6492           */
   6493          image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette,
   6494                  &in_pixel);
   6495 
   6496          /* We don't expect changes to the index here even if the bit depth is
   6497           * changed.
   6498           */
   6499          if (in_ct == PNG_COLOR_TYPE_PALETTE &&
   6500             out_ct == PNG_COLOR_TYPE_PALETTE)
   6501          {
   6502             if (in_pixel.palette_index != out_pixel.palette_index)
   6503                png_error(pp, "unexpected transformed palette index");
   6504          }
   6505 
   6506          /* Check the colours for palette images too - in fact the palette could
   6507           * be separately verified itself in most cases.
   6508           */
   6509          if (in_pixel.red != out_pixel.red)
   6510             transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf,
   6511                out_pixel.red, sample_depth, in_pixel.rede,
   6512                dp->pm->limit + 1./(2*((1U<<in_pixel.red_sBIT)-1)), "red/gray",
   6513                digitization_error);
   6514 
   6515          if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
   6516             in_pixel.green != out_pixel.green)
   6517             transform_range_check(pp, r, g, b, a, in_pixel.green,
   6518                in_pixel.greenf, out_pixel.green, sample_depth, in_pixel.greene,
   6519                dp->pm->limit + 1./(2*((1U<<in_pixel.green_sBIT)-1)), "green",
   6520                digitization_error);
   6521 
   6522          if ((out_ct & PNG_COLOR_MASK_COLOR) != 0 &&
   6523             in_pixel.blue != out_pixel.blue)
   6524             transform_range_check(pp, r, g, b, a, in_pixel.blue, in_pixel.bluef,
   6525                out_pixel.blue, sample_depth, in_pixel.bluee,
   6526                dp->pm->limit + 1./(2*((1U<<in_pixel.blue_sBIT)-1)), "blue",
   6527                digitization_error);
   6528 
   6529          if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0 &&
   6530             in_pixel.alpha != out_pixel.alpha)
   6531             transform_range_check(pp, r, g, b, a, in_pixel.alpha,
   6532                in_pixel.alphaf, out_pixel.alpha, sample_depth, in_pixel.alphae,
   6533                dp->pm->limit + 1./(2*((1U<<in_pixel.alpha_sBIT)-1)), "alpha",
   6534                digitization_error);
   6535       } /* pixel (x) loop */
   6536    } /* row (y) loop */
   6537 
   6538    /* Record that something was actually checked to avoid a false positive. */
   6539    dp->this.ps->validated = 1;
   6540 }
   6541 
   6542 static void PNGCBAPI
   6543 transform_end(png_structp ppIn, png_infop pi)
   6544 {
   6545    png_const_structp pp = ppIn;
   6546    transform_display *dp = voidcast(transform_display*,
   6547       png_get_progressive_ptr(pp));
   6548 
   6549    if (!dp->this.speed)
   6550       transform_image_validate(dp, pp, pi);
   6551    else
   6552       dp->this.ps->validated = 1;
   6553 }
   6554 
   6555 /* A single test run. */
   6556 static void
   6557 transform_test(png_modifier *pmIn, const png_uint_32 idIn,
   6558     const image_transform* transform_listIn, const char * const name)
   6559 {
   6560    transform_display d;
   6561    context(&pmIn->this, fault);
   6562 
   6563    transform_display_init(&d, pmIn, idIn, transform_listIn);
   6564 
   6565    Try
   6566    {
   6567       size_t pos = 0;
   6568       png_structp pp;
   6569       png_infop pi;
   6570       char full_name[256];
   6571 
   6572       /* Make sure the encoding fields are correct and enter the required
   6573        * modifications.
   6574        */
   6575       transform_set_encoding(&d);
   6576 
   6577       /* Add any modifications required by the transform list. */
   6578       d.transform_list->ini(d.transform_list, &d);
   6579 
   6580       /* Add the color space information, if any, to the name. */
   6581       pos = safecat(full_name, sizeof full_name, pos, name);
   6582       pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm);
   6583 
   6584       /* Get a png_struct for reading the image. */
   6585       pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name);
   6586       standard_palette_init(&d.this);
   6587 
   6588 #     if 0
   6589          /* Logging (debugging only) */
   6590          {
   6591             char buffer[256];
   6592 
   6593             (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0,
   6594                "running test");
   6595 
   6596             fprintf(stderr, "%s\n", buffer);
   6597          }
   6598 #     endif
   6599 
   6600       /* Introduce the correct read function. */
   6601       if (d.pm->this.progressive)
   6602       {
   6603          /* Share the row function with the standard implementation. */
   6604          png_set_progressive_read_fn(pp, &d, transform_info, progressive_row,
   6605             transform_end);
   6606 
   6607          /* Now feed data into the reader until we reach the end: */
   6608          modifier_progressive_read(d.pm, pp, pi);
   6609       }
   6610       else
   6611       {
   6612          /* modifier_read expects a png_modifier* */
   6613          png_set_read_fn(pp, d.pm, modifier_read);
   6614 
   6615          /* Check the header values: */
   6616          png_read_info(pp, pi);
   6617 
   6618          /* Process the 'info' requirements. Only one image is generated */
   6619          transform_info_imp(&d, pp, pi);
   6620 
   6621          sequential_row(&d.this, pp, pi, -1, 0);
   6622 
   6623          if (!d.this.speed)
   6624             transform_image_validate(&d, pp, pi);
   6625          else
   6626             d.this.ps->validated = 1;
   6627       }
   6628 
   6629       modifier_reset(d.pm);
   6630    }
   6631 
   6632    Catch(fault)
   6633    {
   6634       modifier_reset(voidcast(png_modifier*,(void*)fault));
   6635    }
   6636 }
   6637 
   6638 /* The transforms: */
   6639 #define ITSTRUCT(name) image_transform_##name
   6640 #define ITDATA(name) image_transform_data_##name
   6641 #define image_transform_ini image_transform_default_ini
   6642 #define IT(name)\
   6643 static image_transform ITSTRUCT(name) =\
   6644 {\
   6645    #name,\
   6646    1, /*enable*/\
   6647    &PT, /*list*/\
   6648    0, /*global_use*/\
   6649    0, /*local_use*/\
   6650    0, /*next*/\
   6651    image_transform_ini,\
   6652    image_transform_png_set_##name##_set,\
   6653    image_transform_png_set_##name##_mod,\
   6654    image_transform_png_set_##name##_add\
   6655 }
   6656 #define PT ITSTRUCT(end) /* stores the previous transform */
   6657 
   6658 /* To save code: */
   6659 extern void image_transform_default_ini(const image_transform *this,
   6660    transform_display *that); /* silence GCC warnings */
   6661 
   6662 void /* private, but almost always needed */
   6663 image_transform_default_ini(const image_transform *this,
   6664     transform_display *that)
   6665 {
   6666    this->next->ini(this->next, that);
   6667 }
   6668 
   6669 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   6670 static int
   6671 image_transform_default_add(image_transform *this,
   6672     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6673 {
   6674    UNUSED(colour_type)
   6675    UNUSED(bit_depth)
   6676 
   6677    this->next = *that;
   6678    *that = this;
   6679 
   6680    return 1;
   6681 }
   6682 #endif
   6683 
   6684 #ifdef PNG_READ_EXPAND_SUPPORTED
   6685 /* png_set_palette_to_rgb */
   6686 static void
   6687 image_transform_png_set_palette_to_rgb_set(const image_transform *this,
   6688     transform_display *that, png_structp pp, png_infop pi)
   6689 {
   6690    png_set_palette_to_rgb(pp);
   6691    this->next->set(this->next, that, pp, pi);
   6692 }
   6693 
   6694 static void
   6695 image_transform_png_set_palette_to_rgb_mod(const image_transform *this,
   6696     image_pixel *that, png_const_structp pp,
   6697     const transform_display *display)
   6698 {
   6699    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
   6700       image_pixel_convert_PLTE(that);
   6701 
   6702    this->next->mod(this->next, that, pp, display);
   6703 }
   6704 
   6705 static int
   6706 image_transform_png_set_palette_to_rgb_add(image_transform *this,
   6707     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6708 {
   6709    UNUSED(bit_depth)
   6710 
   6711    this->next = *that;
   6712    *that = this;
   6713 
   6714    return colour_type == PNG_COLOR_TYPE_PALETTE;
   6715 }
   6716 
   6717 IT(palette_to_rgb);
   6718 #undef PT
   6719 #define PT ITSTRUCT(palette_to_rgb)
   6720 #endif /* PNG_READ_EXPAND_SUPPORTED */
   6721 
   6722 #ifdef PNG_READ_EXPAND_SUPPORTED
   6723 /* png_set_tRNS_to_alpha */
   6724 static void
   6725 image_transform_png_set_tRNS_to_alpha_set(const image_transform *this,
   6726    transform_display *that, png_structp pp, png_infop pi)
   6727 {
   6728    png_set_tRNS_to_alpha(pp);
   6729 
   6730    /* If there was a tRNS chunk that would get expanded and add an alpha
   6731     * channel is_transparent must be updated:
   6732     */
   6733    if (that->this.has_tRNS)
   6734       that->this.is_transparent = 1;
   6735 
   6736    this->next->set(this->next, that, pp, pi);
   6737 }
   6738 
   6739 static void
   6740 image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this,
   6741    image_pixel *that, png_const_structp pp,
   6742    const transform_display *display)
   6743 {
   6744 #if PNG_LIBPNG_VER < 10700
   6745    /* LIBPNG BUG: this always forces palette images to RGB. */
   6746    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
   6747       image_pixel_convert_PLTE(that);
   6748 #endif
   6749 
   6750    /* This effectively does an 'expand' only if there is some transparency to
   6751     * convert to an alpha channel.
   6752     */
   6753    if (that->have_tRNS)
   6754 #     if PNG_LIBPNG_VER >= 10700
   6755          if (that->colour_type != PNG_COLOR_TYPE_PALETTE &&
   6756              (that->colour_type & PNG_COLOR_MASK_ALPHA) == 0)
   6757 #     endif
   6758       image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
   6759 
   6760 #if PNG_LIBPNG_VER < 10700
   6761    /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */
   6762    else
   6763    {
   6764       if (that->bit_depth < 8)
   6765          that->bit_depth =8;
   6766       if (that->sample_depth < 8)
   6767          that->sample_depth = 8;
   6768    }
   6769 #endif
   6770 
   6771    this->next->mod(this->next, that, pp, display);
   6772 }
   6773 
   6774 static int
   6775 image_transform_png_set_tRNS_to_alpha_add(image_transform *this,
   6776     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6777 {
   6778    UNUSED(bit_depth)
   6779 
   6780    this->next = *that;
   6781    *that = this;
   6782 
   6783    /* We don't know yet whether there will be a tRNS chunk, but we know that
   6784     * this transformation should do nothing if there already is an alpha
   6785     * channel.  In addition, after the bug fix in 1.7.0, there is no longer
   6786     * any action on a palette image.
   6787     */
   6788    return
   6789 #  if PNG_LIBPNG_VER >= 10700
   6790       colour_type != PNG_COLOR_TYPE_PALETTE &&
   6791 #  endif
   6792    (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
   6793 }
   6794 
   6795 IT(tRNS_to_alpha);
   6796 #undef PT
   6797 #define PT ITSTRUCT(tRNS_to_alpha)
   6798 #endif /* PNG_READ_EXPAND_SUPPORTED */
   6799 
   6800 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   6801 /* png_set_gray_to_rgb */
   6802 static void
   6803 image_transform_png_set_gray_to_rgb_set(const image_transform *this,
   6804     transform_display *that, png_structp pp, png_infop pi)
   6805 {
   6806    png_set_gray_to_rgb(pp);
   6807    /* NOTE: this doesn't result in tRNS expansion. */
   6808    this->next->set(this->next, that, pp, pi);
   6809 }
   6810 
   6811 static void
   6812 image_transform_png_set_gray_to_rgb_mod(const image_transform *this,
   6813     image_pixel *that, png_const_structp pp,
   6814     const transform_display *display)
   6815 {
   6816    /* NOTE: we can actually pend the tRNS processing at this point because we
   6817     * can correctly recognize the original pixel value even though we have
   6818     * mapped the one gray channel to the three RGB ones, but in fact libpng
   6819     * doesn't do this, so we don't either.
   6820     */
   6821    if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS)
   6822       image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
   6823 
   6824    /* Simply expand the bit depth and alter the colour type as required. */
   6825    if (that->colour_type == PNG_COLOR_TYPE_GRAY)
   6826    {
   6827       /* RGB images have a bit depth at least equal to '8' */
   6828       if (that->bit_depth < 8)
   6829          that->sample_depth = that->bit_depth = 8;
   6830 
   6831       /* And just changing the colour type works here because the green and blue
   6832        * channels are being maintained in lock-step with the red/gray:
   6833        */
   6834       that->colour_type = PNG_COLOR_TYPE_RGB;
   6835    }
   6836 
   6837    else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   6838       that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
   6839 
   6840    this->next->mod(this->next, that, pp, display);
   6841 }
   6842 
   6843 static int
   6844 image_transform_png_set_gray_to_rgb_add(image_transform *this,
   6845     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6846 {
   6847    UNUSED(bit_depth)
   6848 
   6849    this->next = *that;
   6850    *that = this;
   6851 
   6852    return (colour_type & PNG_COLOR_MASK_COLOR) == 0;
   6853 }
   6854 
   6855 IT(gray_to_rgb);
   6856 #undef PT
   6857 #define PT ITSTRUCT(gray_to_rgb)
   6858 #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
   6859 
   6860 #ifdef PNG_READ_EXPAND_SUPPORTED
   6861 /* png_set_expand */
   6862 static void
   6863 image_transform_png_set_expand_set(const image_transform *this,
   6864     transform_display *that, png_structp pp, png_infop pi)
   6865 {
   6866    png_set_expand(pp);
   6867 
   6868    if (that->this.has_tRNS)
   6869       that->this.is_transparent = 1;
   6870 
   6871    this->next->set(this->next, that, pp, pi);
   6872 }
   6873 
   6874 static void
   6875 image_transform_png_set_expand_mod(const image_transform *this,
   6876     image_pixel *that, png_const_structp pp,
   6877     const transform_display *display)
   6878 {
   6879    /* The general expand case depends on what the colour type is: */
   6880    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
   6881       image_pixel_convert_PLTE(that);
   6882    else if (that->bit_depth < 8) /* grayscale */
   6883       that->sample_depth = that->bit_depth = 8;
   6884 
   6885    if (that->have_tRNS)
   6886       image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
   6887 
   6888    this->next->mod(this->next, that, pp, display);
   6889 }
   6890 
   6891 static int
   6892 image_transform_png_set_expand_add(image_transform *this,
   6893     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6894 {
   6895    UNUSED(bit_depth)
   6896 
   6897    this->next = *that;
   6898    *that = this;
   6899 
   6900    /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit
   6901     * depth is at least 8 already.
   6902     */
   6903    return (colour_type & PNG_COLOR_MASK_ALPHA) == 0;
   6904 }
   6905 
   6906 IT(expand);
   6907 #undef PT
   6908 #define PT ITSTRUCT(expand)
   6909 #endif /* PNG_READ_EXPAND_SUPPORTED */
   6910 
   6911 #ifdef PNG_READ_EXPAND_SUPPORTED
   6912 /* png_set_expand_gray_1_2_4_to_8
   6913  * Pre 1.7.0 LIBPNG BUG: this just does an 'expand'
   6914  */
   6915 static void
   6916 image_transform_png_set_expand_gray_1_2_4_to_8_set(
   6917     const image_transform *this, transform_display *that, png_structp pp,
   6918     png_infop pi)
   6919 {
   6920    png_set_expand_gray_1_2_4_to_8(pp);
   6921    /* NOTE: don't expect this to expand tRNS */
   6922    this->next->set(this->next, that, pp, pi);
   6923 }
   6924 
   6925 static void
   6926 image_transform_png_set_expand_gray_1_2_4_to_8_mod(
   6927     const image_transform *this, image_pixel *that, png_const_structp pp,
   6928     const transform_display *display)
   6929 {
   6930 #if PNG_LIBPNG_VER < 10700
   6931    image_transform_png_set_expand_mod(this, that, pp, display);
   6932 #else
   6933    /* Only expand grayscale of bit depth less than 8: */
   6934    if (that->colour_type == PNG_COLOR_TYPE_GRAY &&
   6935        that->bit_depth < 8)
   6936       that->sample_depth = that->bit_depth = 8;
   6937 
   6938    this->next->mod(this->next, that, pp, display);
   6939 #endif /* 1.7 or later */
   6940 }
   6941 
   6942 static int
   6943 image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this,
   6944     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   6945 {
   6946 #if PNG_LIBPNG_VER < 10700
   6947    return image_transform_png_set_expand_add(this, that, colour_type,
   6948       bit_depth);
   6949 #else
   6950    UNUSED(bit_depth)
   6951 
   6952    this->next = *that;
   6953    *that = this;
   6954 
   6955    /* This should do nothing unless the color type is gray and the bit depth is
   6956     * less than 8:
   6957     */
   6958    return colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8;
   6959 #endif /* 1.7 or later */
   6960 }
   6961 
   6962 IT(expand_gray_1_2_4_to_8);
   6963 #undef PT
   6964 #define PT ITSTRUCT(expand_gray_1_2_4_to_8)
   6965 #endif /* PNG_READ_EXPAND_SUPPORTED */
   6966 
   6967 #ifdef PNG_READ_EXPAND_16_SUPPORTED
   6968 /* png_set_expand_16 */
   6969 static void
   6970 image_transform_png_set_expand_16_set(const image_transform *this,
   6971     transform_display *that, png_structp pp, png_infop pi)
   6972 {
   6973    png_set_expand_16(pp);
   6974 
   6975    /* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */
   6976 #  if PNG_LIBPNG_VER < 10700
   6977       if (that->this.has_tRNS)
   6978          that->this.is_transparent = 1;
   6979 #  endif
   6980 
   6981    this->next->set(this->next, that, pp, pi);
   6982 }
   6983 
   6984 static void
   6985 image_transform_png_set_expand_16_mod(const image_transform *this,
   6986     image_pixel *that, png_const_structp pp,
   6987     const transform_display *display)
   6988 {
   6989    /* Expect expand_16 to expand everything to 16 bits as a result of also
   6990     * causing 'expand' to happen.
   6991     */
   6992    if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
   6993       image_pixel_convert_PLTE(that);
   6994 
   6995    if (that->have_tRNS)
   6996       image_pixel_add_alpha(that, &display->this, 0/*!for background*/);
   6997 
   6998    if (that->bit_depth < 16)
   6999       that->sample_depth = that->bit_depth = 16;
   7000 
   7001    this->next->mod(this->next, that, pp, display);
   7002 }
   7003 
   7004 static int
   7005 image_transform_png_set_expand_16_add(image_transform *this,
   7006     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   7007 {
   7008    UNUSED(colour_type)
   7009 
   7010    this->next = *that;
   7011    *that = this;
   7012 
   7013    /* expand_16 does something unless the bit depth is already 16. */
   7014    return bit_depth < 16;
   7015 }
   7016 
   7017 IT(expand_16);
   7018 #undef PT
   7019 #define PT ITSTRUCT(expand_16)
   7020 #endif /* PNG_READ_EXPAND_16_SUPPORTED */
   7021 
   7022 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED  /* API added in 1.5.4 */
   7023 /* png_set_scale_16 */
   7024 static void
   7025 image_transform_png_set_scale_16_set(const image_transform *this,
   7026     transform_display *that, png_structp pp, png_infop pi)
   7027 {
   7028    png_set_scale_16(pp);
   7029 #  if PNG_LIBPNG_VER < 10700
   7030       /* libpng will limit the gamma table size: */
   7031       that->max_gamma_8 = PNG_MAX_GAMMA_8;
   7032 #  endif
   7033    this->next->set(this->next, that, pp, pi);
   7034 }
   7035 
   7036 static void
   7037 image_transform_png_set_scale_16_mod(const image_transform *this,
   7038     image_pixel *that, png_const_structp pp,
   7039     const transform_display *display)
   7040 {
   7041    if (that->bit_depth == 16)
   7042    {
   7043       that->sample_depth = that->bit_depth = 8;
   7044       if (that->red_sBIT > 8) that->red_sBIT = 8;
   7045       if (that->green_sBIT > 8) that->green_sBIT = 8;
   7046       if (that->blue_sBIT > 8) that->blue_sBIT = 8;
   7047       if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
   7048    }
   7049 
   7050    this->next->mod(this->next, that, pp, display);
   7051 }
   7052 
   7053 static int
   7054 image_transform_png_set_scale_16_add(image_transform *this,
   7055     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   7056 {
   7057    UNUSED(colour_type)
   7058 
   7059    this->next = *that;
   7060    *that = this;
   7061 
   7062    return bit_depth > 8;
   7063 }
   7064 
   7065 IT(scale_16);
   7066 #undef PT
   7067 #define PT ITSTRUCT(scale_16)
   7068 #endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */
   7069 
   7070 #ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */
   7071 /* png_set_strip_16 */
   7072 static void
   7073 image_transform_png_set_strip_16_set(const image_transform *this,
   7074     transform_display *that, png_structp pp, png_infop pi)
   7075 {
   7076    png_set_strip_16(pp);
   7077 #  if PNG_LIBPNG_VER < 10700
   7078       /* libpng will limit the gamma table size: */
   7079       that->max_gamma_8 = PNG_MAX_GAMMA_8;
   7080 #  endif
   7081    this->next->set(this->next, that, pp, pi);
   7082 }
   7083 
   7084 static void
   7085 image_transform_png_set_strip_16_mod(const image_transform *this,
   7086     image_pixel *that, png_const_structp pp,
   7087     const transform_display *display)
   7088 {
   7089    if (that->bit_depth == 16)
   7090    {
   7091       that->sample_depth = that->bit_depth = 8;
   7092       if (that->red_sBIT > 8) that->red_sBIT = 8;
   7093       if (that->green_sBIT > 8) that->green_sBIT = 8;
   7094       if (that->blue_sBIT > 8) that->blue_sBIT = 8;
   7095       if (that->alpha_sBIT > 8) that->alpha_sBIT = 8;
   7096 
   7097       /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this
   7098        * configuration option is set.  From 1.5.4 the flag is never set and the
   7099        * 'scale' API (above) must be used.
   7100        */
   7101 #     ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED
   7102 #        if PNG_LIBPNG_VER >= 10504
   7103 #           error PNG_READ_ACCURATE_SCALE should not be set
   7104 #        endif
   7105 
   7106          /* The strip 16 algorithm drops the low 8 bits rather than calculating
   7107           * 1/257, so we need to adjust the permitted errors appropriately:
   7108           * Notice that this is only relevant prior to the addition of the
   7109           * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!)
   7110           */
   7111          {
   7112             const double d = (255-128.5)/65535;
   7113             that->rede += d;
   7114             that->greene += d;
   7115             that->bluee += d;
   7116             that->alphae += d;
   7117          }
   7118 #     endif
   7119    }
   7120 
   7121    this->next->mod(this->next, that, pp, display);
   7122 }
   7123 
   7124 static int
   7125 image_transform_png_set_strip_16_add(image_transform *this,
   7126     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   7127 {
   7128    UNUSED(colour_type)
   7129 
   7130    this->next = *that;
   7131    *that = this;
   7132 
   7133    return bit_depth > 8;
   7134 }
   7135 
   7136 IT(strip_16);
   7137 #undef PT
   7138 #define PT ITSTRUCT(strip_16)
   7139 #endif /* PNG_READ_16_TO_8_SUPPORTED */
   7140 
   7141 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   7142 /* png_set_strip_alpha */
   7143 static void
   7144 image_transform_png_set_strip_alpha_set(const image_transform *this,
   7145     transform_display *that, png_structp pp, png_infop pi)
   7146 {
   7147    png_set_strip_alpha(pp);
   7148    this->next->set(this->next, that, pp, pi);
   7149 }
   7150 
   7151 static void
   7152 image_transform_png_set_strip_alpha_mod(const image_transform *this,
   7153     image_pixel *that, png_const_structp pp,
   7154     const transform_display *display)
   7155 {
   7156    if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   7157       that->colour_type = PNG_COLOR_TYPE_GRAY;
   7158    else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
   7159       that->colour_type = PNG_COLOR_TYPE_RGB;
   7160 
   7161    that->have_tRNS = 0;
   7162    that->alphaf = 1;
   7163 
   7164    this->next->mod(this->next, that, pp, display);
   7165 }
   7166 
   7167 static int
   7168 image_transform_png_set_strip_alpha_add(image_transform *this,
   7169     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   7170 {
   7171    UNUSED(bit_depth)
   7172 
   7173    this->next = *that;
   7174    *that = this;
   7175 
   7176    return (colour_type & PNG_COLOR_MASK_ALPHA) != 0;
   7177 }
   7178 
   7179 IT(strip_alpha);
   7180 #undef PT
   7181 #define PT ITSTRUCT(strip_alpha)
   7182 #endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */
   7183 
   7184 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
   7185 /* png_set_rgb_to_gray(png_structp, int err_action, double red, double green)
   7186  * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red,
   7187  *    png_fixed_point green)
   7188  * png_get_rgb_to_gray_status
   7189  *
   7190  * The 'default' test here uses values known to be used inside libpng prior to
   7191  * 1.7.0:
   7192  *
   7193  *   red:    6968
   7194  *   green: 23434
   7195  *   blue:   2366
   7196  *
   7197  * These values are being retained for compatibility, along with the somewhat
   7198  * broken truncation calculation in the fast-and-inaccurate code path.  Older
   7199  * versions of libpng will fail the accuracy tests below because they use the
   7200  * truncation algorithm everywhere.
   7201  */
   7202 #define data ITDATA(rgb_to_gray)
   7203 static struct
   7204 {
   7205    double gamma;      /* File gamma to use in processing */
   7206 
   7207    /* The following are the parameters for png_set_rgb_to_gray: */
   7208 #  ifdef PNG_FLOATING_POINT_SUPPORTED
   7209       double red_to_set;
   7210       double green_to_set;
   7211 #  else
   7212       png_fixed_point red_to_set;
   7213       png_fixed_point green_to_set;
   7214 #  endif
   7215 
   7216    /* The actual coefficients: */
   7217    double red_coefficient;
   7218    double green_coefficient;
   7219    double blue_coefficient;
   7220 
   7221    /* Set if the coeefficients have been overridden. */
   7222    int coefficients_overridden;
   7223 } data;
   7224 
   7225 #undef image_transform_ini
   7226 #define image_transform_ini image_transform_png_set_rgb_to_gray_ini
   7227 static void
   7228 image_transform_png_set_rgb_to_gray_ini(const image_transform *this,
   7229     transform_display *that)
   7230 {
   7231    png_modifier *pm = that->pm;
   7232    const color_encoding *e = pm->current_encoding;
   7233 
   7234    UNUSED(this)
   7235 
   7236    /* Since we check the encoding this flag must be set: */
   7237    pm->test_uses_encoding = 1;
   7238 
   7239    /* If 'e' is not NULL chromaticity information is present and either a cHRM
   7240     * or an sRGB chunk will be inserted.
   7241     */
   7242    if (e != 0)
   7243    {
   7244       /* Coefficients come from the encoding, but may need to be normalized to a
   7245        * white point Y of 1.0
   7246        */
   7247       const double whiteY = e->red.Y + e->green.Y + e->blue.Y;
   7248 
   7249       data.red_coefficient = e->red.Y;
   7250       data.green_coefficient = e->green.Y;
   7251       data.blue_coefficient = e->blue.Y;
   7252 
   7253       if (whiteY != 1)
   7254       {
   7255          data.red_coefficient /= whiteY;
   7256          data.green_coefficient /= whiteY;
   7257          data.blue_coefficient /= whiteY;
   7258       }
   7259    }
   7260 
   7261    else
   7262    {
   7263       /* The default (built in) coeffcients, as above: */
   7264 #     if PNG_LIBPNG_VER < 10700
   7265          data.red_coefficient = 6968 / 32768.;
   7266          data.green_coefficient = 23434 / 32768.;
   7267          data.blue_coefficient = 2366 / 32768.;
   7268 #     else
   7269          data.red_coefficient = .2126;
   7270          data.green_coefficient = .7152;
   7271          data.blue_coefficient = .0722;
   7272 #     endif
   7273    }
   7274 
   7275    data.gamma = pm->current_gamma;
   7276 
   7277    /* If not set then the calculations assume linear encoding (implicitly): */
   7278    if (data.gamma == 0)
   7279       data.gamma = 1;
   7280 
   7281    /* The arguments to png_set_rgb_to_gray can override the coefficients implied
   7282     * by the color space encoding.  If doing exhaustive checks do the override
   7283     * in each case, otherwise do it randomly.
   7284     */
   7285    if (pm->test_exhaustive)
   7286    {
   7287       /* First time in coefficients_overridden is 0, the following sets it to 1,
   7288        * so repeat if it is set.  If a test fails this may mean we subsequently
   7289        * skip a non-override test, ignore that.
   7290        */
   7291       data.coefficients_overridden = !data.coefficients_overridden;
   7292       pm->repeat = data.coefficients_overridden != 0;
   7293    }
   7294 
   7295    else
   7296       data.coefficients_overridden = random_choice();
   7297 
   7298    if (data.coefficients_overridden)
   7299    {
   7300       /* These values override the color encoding defaults, simply use random
   7301        * numbers.
   7302        */
   7303       png_uint_32 ru;
   7304       double total;
   7305 
   7306       R32_1(ru);
   7307       data.green_coefficient = total = (ru & 0xffff) / 65535.;
   7308       ru >>= 16;
   7309       data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.;
   7310       total += data.red_coefficient;
   7311       data.blue_coefficient = 1 - total;
   7312 
   7313 #     ifdef PNG_FLOATING_POINT_SUPPORTED
   7314          data.red_to_set = data.red_coefficient;
   7315          data.green_to_set = data.green_coefficient;
   7316 #     else
   7317          data.red_to_set = fix(data.red_coefficient);
   7318          data.green_to_set = fix(data.green_coefficient);
   7319 #     endif
   7320 
   7321       /* The following just changes the error messages: */
   7322       pm->encoding_ignored = 1;
   7323    }
   7324 
   7325    else
   7326    {
   7327       data.red_to_set = -1;
   7328       data.green_to_set = -1;
   7329    }
   7330 
   7331    /* Adjust the error limit in the png_modifier because of the larger errors
   7332     * produced in the digitization during the gamma handling.
   7333     */
   7334    if (data.gamma != 1) /* Use gamma tables */
   7335    {
   7336       if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations)
   7337       {
   7338          /* The computations have the form:
   7339           *
   7340           *    r * rc + g * gc + b * bc
   7341           *
   7342           *  Each component of which is +/-1/65535 from the gamma_to_1 table
   7343           *  lookup, resulting in a base error of +/-6.  The gamma_from_1
   7344           *  conversion adds another +/-2 in the 16-bit case and
   7345           *  +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case.
   7346           */
   7347 #        if PNG_LIBPNG_VER < 10700
   7348             if (that->this.bit_depth < 16)
   7349                that->max_gamma_8 = PNG_MAX_GAMMA_8;
   7350 #        endif
   7351          that->pm->limit += pow(
   7352             (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ?
   7353                8. :
   7354                6. + (1<<(15-that->max_gamma_8))
   7355             )/65535, data.gamma);
   7356       }
   7357 
   7358       else
   7359       {
   7360          /* Rounding to 8 bits in the linear space causes massive errors which
   7361           * will trigger the error check in transform_range_check.  Fix that
   7362           * here by taking the gamma encoding into account.
   7363           *
   7364           * When DIGITIZE is set because a pre-1.7 version of libpng is being
   7365           * tested allow a bigger slack.
   7366           *
   7367           * NOTE: this number only affects the internal limit check in pngvalid,
   7368           * it has no effect on the limits applied to the libpng values.
   7369           */
   7370          that->pm->limit += pow(
   7371 #        if DIGITIZE
   7372             2.0
   7373 #        else
   7374             1.0
   7375 #        endif
   7376             /255, data.gamma);
   7377       }
   7378    }
   7379 
   7380    else
   7381    {
   7382       /* With no gamma correction a large error comes from the truncation of the
   7383        * calculation in the 8 bit case, allow for that here.
   7384        */
   7385       if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations)
   7386          that->pm->limit += 4E-3;
   7387    }
   7388 }
   7389 
   7390 static void
   7391 image_transform_png_set_rgb_to_gray_set(const image_transform *this,
   7392     transform_display *that, png_structp pp, png_infop pi)
   7393 {
   7394    const int error_action = 1; /* no error, no defines in png.h */
   7395 
   7396 #  ifdef PNG_FLOATING_POINT_SUPPORTED
   7397       png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set);
   7398 #  else
   7399       png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set,
   7400          data.green_to_set);
   7401 #  endif
   7402 
   7403 #  ifdef PNG_READ_cHRM_SUPPORTED
   7404       if (that->pm->current_encoding != 0)
   7405       {
   7406          /* We have an encoding so a cHRM chunk may have been set; if so then
   7407           * check that the libpng APIs give the correct (X,Y,Z) values within
   7408           * some margin of error for the round trip through the chromaticity
   7409           * form.
   7410           */
   7411 #        ifdef PNG_FLOATING_POINT_SUPPORTED
   7412 #           define API_function png_get_cHRM_XYZ
   7413 #           define API_form "FP"
   7414 #           define API_type double
   7415 #           define API_cvt(x) (x)
   7416 #        else
   7417 #           define API_function png_get_cHRM_XYZ_fixed
   7418 #           define API_form "fixed"
   7419 #           define API_type png_fixed_point
   7420 #           define API_cvt(x) ((double)(x)/PNG_FP_1)
   7421 #        endif
   7422 
   7423          API_type rX, gX, bX;
   7424          API_type rY, gY, bY;
   7425          API_type rZ, gZ, bZ;
   7426 
   7427          if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ)
   7428                & PNG_INFO_cHRM) != 0)
   7429          {
   7430             double maxe;
   7431             const char *el;
   7432             color_encoding e, o;
   7433 
   7434             /* Expect libpng to return a normalized result, but the original
   7435              * color space encoding may not be normalized.
   7436              */
   7437             modifier_current_encoding(that->pm, &o);
   7438             normalize_color_encoding(&o);
   7439 
   7440             /* Sanity check the pngvalid code - the coefficients should match
   7441              * the normalized Y values of the encoding unless they were
   7442              * overridden.
   7443              */
   7444             if (data.red_to_set == -1 && data.green_to_set == -1 &&
   7445                (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON ||
   7446                fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON ||
   7447                fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON))
   7448                png_error(pp, "internal pngvalid cHRM coefficient error");
   7449 
   7450             /* Generate a colour space encoding. */
   7451             e.gamma = o.gamma; /* not used */
   7452             e.red.X = API_cvt(rX);
   7453             e.red.Y = API_cvt(rY);
   7454             e.red.Z = API_cvt(rZ);
   7455             e.green.X = API_cvt(gX);
   7456             e.green.Y = API_cvt(gY);
   7457             e.green.Z = API_cvt(gZ);
   7458             e.blue.X = API_cvt(bX);
   7459             e.blue.Y = API_cvt(bY);
   7460             e.blue.Z = API_cvt(bZ);
   7461 
   7462             /* This should match the original one from the png_modifier, within
   7463              * the range permitted by the libpng fixed point representation.
   7464              */
   7465             maxe = 0;
   7466             el = "-"; /* Set to element name with error */
   7467 
   7468 #           define CHECK(col,x)\
   7469             {\
   7470                double err = fabs(o.col.x - e.col.x);\
   7471                if (err > maxe)\
   7472                {\
   7473                   maxe = err;\
   7474                   el = #col "(" #x ")";\
   7475                }\
   7476             }
   7477 
   7478             CHECK(red,X)
   7479             CHECK(red,Y)
   7480             CHECK(red,Z)
   7481             CHECK(green,X)
   7482             CHECK(green,Y)
   7483             CHECK(green,Z)
   7484             CHECK(blue,X)
   7485             CHECK(blue,Y)
   7486             CHECK(blue,Z)
   7487 
   7488             /* Here in both fixed and floating cases to check the values read
   7489              * from the cHRm chunk.  PNG uses fixed point in the cHRM chunk, so
   7490              * we can't expect better than +/-.5E-5 on the result, allow 1E-5.
   7491              */
   7492             if (maxe >= 1E-5)
   7493             {
   7494                size_t pos = 0;
   7495                char buffer[256];
   7496 
   7497                pos = safecat(buffer, sizeof buffer, pos, API_form);
   7498                pos = safecat(buffer, sizeof buffer, pos, " cHRM ");
   7499                pos = safecat(buffer, sizeof buffer, pos, el);
   7500                pos = safecat(buffer, sizeof buffer, pos, " error: ");
   7501                pos = safecatd(buffer, sizeof buffer, pos, maxe, 7);
   7502                pos = safecat(buffer, sizeof buffer, pos, " ");
   7503                /* Print the color space without the gamma value: */
   7504                pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0);
   7505                pos = safecat(buffer, sizeof buffer, pos, " -> ");
   7506                pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0);
   7507 
   7508                png_error(pp, buffer);
   7509             }
   7510          }
   7511       }
   7512 #  endif /* READ_cHRM */
   7513 
   7514    this->next->set(this->next, that, pp, pi);
   7515 }
   7516 
   7517 static void
   7518 image_transform_png_set_rgb_to_gray_mod(const image_transform *this,
   7519     image_pixel *that, png_const_structp pp,
   7520     const transform_display *display)
   7521 {
   7522    if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0)
   7523    {
   7524       double gray, err;
   7525 
   7526 #     if PNG_LIBPNG_VER < 10700
   7527          if (that->colour_type == PNG_COLOR_TYPE_PALETTE)
   7528             image_pixel_convert_PLTE(that);
   7529 #     endif
   7530 
   7531       /* Image now has RGB channels... */
   7532 #  if DIGITIZE
   7533       {
   7534          png_modifier *pm = display->pm;
   7535          const unsigned int sample_depth = that->sample_depth;
   7536          const unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 :
   7537             sample_depth);
   7538          const unsigned int gamma_depth =
   7539             (sample_depth == 16 ?
   7540                display->max_gamma_8 :
   7541                (pm->assume_16_bit_calculations ?
   7542                   display->max_gamma_8 :
   7543                   sample_depth));
   7544          int isgray;
   7545          double r, g, b;
   7546          double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi;
   7547 
   7548          /* Do this using interval arithmetic, otherwise it is too difficult to
   7549           * handle the errors correctly.
   7550           *
   7551           * To handle the gamma correction work out the upper and lower bounds
   7552           * of the digitized value.  Assume rounding here - normally the values
   7553           * will be identical after this operation if there is only one
   7554           * transform, feel free to delete the png_error checks on this below in
   7555           * the future (this is just me trying to ensure it works!)
   7556           *
   7557           * Interval arithmetic is exact, but to implement it it must be
   7558           * possible to control the floating point implementation rounding mode.
   7559           * This cannot be done in ANSI-C, so instead I reduce the 'lo' values
   7560           * by DBL_EPSILON and increase the 'hi' values by the same.
   7561           */
   7562 #        define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON))
   7563 #        define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON))
   7564 
   7565          r = rlo = rhi = that->redf;
   7566          rlo -= that->rede;
   7567          rlo = DD(rlo, calc_depth, 1/*round*/);
   7568          rhi += that->rede;
   7569          rhi = DU(rhi, calc_depth, 1/*round*/);
   7570 
   7571          g = glo = ghi = that->greenf;
   7572          glo -= that->greene;
   7573          glo = DD(glo, calc_depth, 1/*round*/);
   7574          ghi += that->greene;
   7575          ghi = DU(ghi, calc_depth, 1/*round*/);
   7576 
   7577          b = blo = bhi = that->bluef;
   7578          blo -= that->bluee;
   7579          blo = DD(blo, calc_depth, 1/*round*/);
   7580          bhi += that->bluee;
   7581          bhi = DU(bhi, calc_depth, 1/*round*/);
   7582 
   7583          isgray = r==g && g==b;
   7584 
   7585          if (data.gamma != 1)
   7586          {
   7587             const double power = 1/data.gamma;
   7588             const double abse = .5/(sample_depth == 16 ? 65535 : 255);
   7589 
   7590             /* If a gamma calculation is done it is done using lookup tables of
   7591              * precision gamma_depth, so the already digitized value above may
   7592              * need to be further digitized here.
   7593              */
   7594             if (gamma_depth != calc_depth)
   7595             {
   7596                rlo = DD(rlo, gamma_depth, 0/*truncate*/);
   7597                rhi = DU(rhi, gamma_depth, 0/*truncate*/);
   7598                glo = DD(glo, gamma_depth, 0/*truncate*/);
   7599                ghi = DU(ghi, gamma_depth, 0/*truncate*/);
   7600                blo = DD(blo, gamma_depth, 0/*truncate*/);
   7601                bhi = DU(bhi, gamma_depth, 0/*truncate*/);
   7602             }
   7603 
   7604             /* 'abse' is the error in the gamma table calculation itself. */
   7605             r = pow(r, power);
   7606             rlo = DD(pow(rlo, power)-abse, calc_depth, 1);
   7607             rhi = DU(pow(rhi, power)+abse, calc_depth, 1);
   7608 
   7609             g = pow(g, power);
   7610             glo = DD(pow(glo, power)-abse, calc_depth, 1);
   7611             ghi = DU(pow(ghi, power)+abse, calc_depth, 1);
   7612 
   7613             b = pow(b, power);
   7614             blo = DD(pow(blo, power)-abse, calc_depth, 1);
   7615             bhi = DU(pow(bhi, power)+abse, calc_depth, 1);
   7616          }
   7617 
   7618          /* Now calculate the actual gray values.  Although the error in the
   7619           * coefficients depends on whether they were specified on the command
   7620           * line (in which case truncation to 15 bits happened) or not (rounding
   7621           * was used) the maxium error in an individual coefficient is always
   7622           * 2/32768, because even in the rounding case the requirement that
   7623           * coefficients add up to 32768 can cause a larger rounding error.
   7624           *
   7625           * The only time when rounding doesn't occur in 1.5.5 and later is when
   7626           * the non-gamma code path is used for less than 16 bit data.
   7627           */
   7628          gray = r * data.red_coefficient + g * data.green_coefficient +
   7629             b * data.blue_coefficient;
   7630 
   7631          {
   7632             const int do_round = data.gamma != 1 || calc_depth == 16;
   7633             const double ce = 2. / 32768;
   7634 
   7635             graylo = DD(rlo * (data.red_coefficient-ce) +
   7636                glo * (data.green_coefficient-ce) +
   7637                blo * (data.blue_coefficient-ce), calc_depth, do_round);
   7638             if (graylo > gray) /* always accept the right answer */
   7639                graylo = gray;
   7640 
   7641             grayhi = DU(rhi * (data.red_coefficient+ce) +
   7642                ghi * (data.green_coefficient+ce) +
   7643                bhi * (data.blue_coefficient+ce), calc_depth, do_round);
   7644             if (grayhi < gray)
   7645                grayhi = gray;
   7646          }
   7647 
   7648          /* And invert the gamma. */
   7649          if (data.gamma != 1)
   7650          {
   7651             const double power = data.gamma;
   7652 
   7653             /* And this happens yet again, shifting the values once more. */
   7654             if (gamma_depth != sample_depth)
   7655             {
   7656                rlo = DD(rlo, gamma_depth, 0/*truncate*/);
   7657                rhi = DU(rhi, gamma_depth, 0/*truncate*/);
   7658                glo = DD(glo, gamma_depth, 0/*truncate*/);
   7659                ghi = DU(ghi, gamma_depth, 0/*truncate*/);
   7660                blo = DD(blo, gamma_depth, 0/*truncate*/);
   7661                bhi = DU(bhi, gamma_depth, 0/*truncate*/);
   7662             }
   7663 
   7664             gray = pow(gray, power);
   7665             graylo = DD(pow(graylo, power), sample_depth, 1);
   7666             grayhi = DU(pow(grayhi, power), sample_depth, 1);
   7667          }
   7668 
   7669 #        undef DD
   7670 #        undef DU
   7671 
   7672          /* Now the error can be calculated.
   7673           *
   7674           * If r==g==b because there is no overall gamma correction libpng
   7675           * currently preserves the original value.
   7676           */
   7677          if (isgray)
   7678             err = (that->rede + that->greene + that->bluee)/3;
   7679 
   7680          else
   7681          {
   7682             err = fabs(grayhi-gray);
   7683 
   7684             if (fabs(gray - graylo) > err)
   7685                err = fabs(graylo-gray);
   7686 
   7687 #if !RELEASE_BUILD
   7688             /* Check that this worked: */
   7689             if (err > pm->limit)
   7690             {
   7691                size_t pos = 0;
   7692                char buffer[128];
   7693 
   7694                pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
   7695                pos = safecatd(buffer, sizeof buffer, pos, err, 6);
   7696                pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
   7697                pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
   7698                png_warning(pp, buffer);
   7699                pm->limit = err;
   7700             }
   7701 #endif /* !RELEASE_BUILD */
   7702          }
   7703       }
   7704 #  else  /* !DIGITIZE */
   7705       {
   7706          double r = that->redf;
   7707          double re = that->rede;
   7708          double g = that->greenf;
   7709          double ge = that->greene;
   7710          double b = that->bluef;
   7711          double be = that->bluee;
   7712 
   7713 #        if PNG_LIBPNG_VER < 10700
   7714             /* The true gray case involves no math in earlier versions (not
   7715              * true, there was some if gamma correction was happening too.)
   7716              */
   7717             if (r == g && r == b)
   7718             {
   7719                gray = r;
   7720                err = re;
   7721                if (err < ge) err = ge;
   7722                if (err < be) err = be;
   7723             }
   7724 
   7725             else
   7726 #        endif /* before 1.7 */
   7727          if (data.gamma == 1)
   7728          {
   7729             /* There is no need to do the conversions to and from linear space,
   7730              * so the calculation should be a lot more accurate.  There is a
   7731              * built in error in the coefficients because they only have 15 bits
   7732              * and are adjusted to make sure they add up to 32768.  This
   7733              * involves a integer calculation with truncation of the form:
   7734              *
   7735              *     ((int)(coefficient * 100000) * 32768)/100000
   7736              *
   7737              * This is done to the red and green coefficients (the ones
   7738              * provided to the API) then blue is calculated from them so the
   7739              * result adds up to 32768.  In the worst case this can result in
   7740              * a -1 error in red and green and a +2 error in blue.  Consequently
   7741              * the worst case in the calculation below is 2/32768 error.
   7742              *
   7743              * TODO: consider fixing this in libpng by rounding the calculation
   7744              * limiting the error to 1/32768.
   7745              *
   7746              * Handling this by adding 2/32768 here avoids needing to increase
   7747              * the global error limits to take this into account.)
   7748              */
   7749             gray = r * data.red_coefficient + g * data.green_coefficient +
   7750                b * data.blue_coefficient;
   7751             err = re * data.red_coefficient + ge * data.green_coefficient +
   7752                be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON;
   7753          }
   7754 
   7755          else
   7756          {
   7757             /* The calculation happens in linear space, and this produces much
   7758              * wider errors in the encoded space.  These are handled here by
   7759              * factoring the errors in to the calculation.  There are two table
   7760              * lookups in the calculation and each introduces a quantization
   7761              * error defined by the table size.
   7762              */
   7763             png_modifier *pm = display->pm;
   7764             double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255);
   7765             double out_qe = (that->sample_depth > 8 ? .5/65535 :
   7766                (pm->assume_16_bit_calculations ? .5/(1<<display->max_gamma_8) :
   7767                .5/255));
   7768             double rhi, ghi, bhi, grayhi;
   7769             double g1 = 1/data.gamma;
   7770 
   7771             rhi = r + re + in_qe; if (rhi > 1) rhi = 1;
   7772             r -= re + in_qe; if (r < 0) r = 0;
   7773             ghi = g + ge + in_qe; if (ghi > 1) ghi = 1;
   7774             g -= ge + in_qe; if (g < 0) g = 0;
   7775             bhi = b + be + in_qe; if (bhi > 1) bhi = 1;
   7776             b -= be + in_qe; if (b < 0) b = 0;
   7777 
   7778             r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON);
   7779             g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON);
   7780             b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON);
   7781 
   7782             /* Work out the lower and upper bounds for the gray value in the
   7783              * encoded space, then work out an average and error.  Remove the
   7784              * previously added input quantization error at this point.
   7785              */
   7786             gray = r * data.red_coefficient + g * data.green_coefficient +
   7787                b * data.blue_coefficient - 2./32768 - out_qe;
   7788             if (gray <= 0)
   7789                gray = 0;
   7790             else
   7791             {
   7792                gray *= (1 - 6 * DBL_EPSILON);
   7793                gray = pow(gray, data.gamma) * (1-DBL_EPSILON);
   7794             }
   7795 
   7796             grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient +
   7797                bhi * data.blue_coefficient + 2./32768 + out_qe;
   7798             grayhi *= (1 + 6 * DBL_EPSILON);
   7799             if (grayhi >= 1)
   7800                grayhi = 1;
   7801             else
   7802                grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON);
   7803 
   7804             err = (grayhi - gray) / 2;
   7805             gray = (grayhi + gray) / 2;
   7806 
   7807             if (err <= in_qe)
   7808                err = gray * DBL_EPSILON;
   7809 
   7810             else
   7811                err -= in_qe;
   7812 
   7813 #if !RELEASE_BUILD
   7814             /* Validate that the error is within limits (this has caused
   7815              * problems before, it's much easier to detect them here.)
   7816              */
   7817             if (err > pm->limit)
   7818             {
   7819                size_t pos = 0;
   7820                char buffer[128];
   7821 
   7822                pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error ");
   7823                pos = safecatd(buffer, sizeof buffer, pos, err, 6);
   7824                pos = safecat(buffer, sizeof buffer, pos, " exceeds limit ");
   7825                pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6);
   7826                png_warning(pp, buffer);
   7827                pm->limit = err;
   7828             }
   7829 #endif /* !RELEASE_BUILD */
   7830          }
   7831       }
   7832 #  endif /* !DIGITIZE */
   7833 
   7834       that->bluef = that->greenf = that->redf = gray;
   7835       that->bluee = that->greene = that->rede = err;
   7836 
   7837       /* The sBIT is the minium of the three colour channel sBITs. */
   7838       if (that->red_sBIT > that->green_sBIT)
   7839          that->red_sBIT = that->green_sBIT;
   7840       if (that->red_sBIT > that->blue_sBIT)
   7841          that->red_sBIT = that->blue_sBIT;
   7842       that->blue_sBIT = that->green_sBIT = that->red_sBIT;
   7843 
   7844       /* And remove the colour bit in the type: */
   7845       if (that->colour_type == PNG_COLOR_TYPE_RGB)
   7846          that->colour_type = PNG_COLOR_TYPE_GRAY;
   7847       else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
   7848          that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
   7849    }
   7850 
   7851    this->next->mod(this->next, that, pp, display);
   7852 }
   7853 
   7854 static int
   7855 image_transform_png_set_rgb_to_gray_add(image_transform *this,
   7856     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   7857 {
   7858    UNUSED(bit_depth)
   7859 
   7860    this->next = *that;
   7861    *that = this;
   7862 
   7863    return (colour_type & PNG_COLOR_MASK_COLOR) != 0;
   7864 }
   7865 
   7866 #undef data
   7867 IT(rgb_to_gray);
   7868 #undef PT
   7869 #define PT ITSTRUCT(rgb_to_gray)
   7870 #undef image_transform_ini
   7871 #define image_transform_ini image_transform_default_ini
   7872 #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */
   7873 
   7874 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   7875 /* png_set_background(png_structp, png_const_color_16p background_color,
   7876  *    int background_gamma_code, int need_expand, double background_gamma)
   7877  * png_set_background_fixed(png_structp, png_const_color_16p background_color,
   7878  *    int background_gamma_code, int need_expand,
   7879  *    png_fixed_point background_gamma)
   7880  *
   7881  * This ignores the gamma (at present.)
   7882 */
   7883 #define data ITDATA(background)
   7884 static image_pixel data;
   7885 
   7886 static void
   7887 image_transform_png_set_background_set(const image_transform *this,
   7888     transform_display *that, png_structp pp, png_infop pi)
   7889 {
   7890    png_byte colour_type, bit_depth;
   7891    png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */
   7892    int expand;
   7893    png_color_16 back;
   7894 
   7895    /* We need a background colour, because we don't know exactly what transforms
   7896     * have been set we have to supply the colour in the original file format and
   7897     * so we need to know what that is!  The background colour is stored in the
   7898     * transform_display.
   7899     */
   7900    R8(random_bytes);
   7901 
   7902    /* Read the random value, for colour type 3 the background colour is actually
   7903     * expressed as a 24bit rgb, not an index.
   7904     */
   7905    colour_type = that->this.colour_type;
   7906    if (colour_type == 3)
   7907    {
   7908       colour_type = PNG_COLOR_TYPE_RGB;
   7909       bit_depth = 8;
   7910       expand = 0; /* passing in an RGB not a pixel index */
   7911    }
   7912 
   7913    else
   7914    {
   7915       if (that->this.has_tRNS)
   7916          that->this.is_transparent = 1;
   7917 
   7918       bit_depth = that->this.bit_depth;
   7919       expand = 1;
   7920    }
   7921 
   7922    image_pixel_init(&data, random_bytes, colour_type,
   7923       bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/);
   7924 
   7925    /* Extract the background colour from this image_pixel, but make sure the
   7926     * unused fields of 'back' are garbage.
   7927     */
   7928    R8(back);
   7929 
   7930    if (colour_type & PNG_COLOR_MASK_COLOR)
   7931    {
   7932       back.red = (png_uint_16)data.red;
   7933       back.green = (png_uint_16)data.green;
   7934       back.blue = (png_uint_16)data.blue;
   7935    }
   7936 
   7937    else
   7938       back.gray = (png_uint_16)data.red;
   7939 
   7940 #  ifdef PNG_FLOATING_POINT_SUPPORTED
   7941       png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
   7942 #  else
   7943       png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0);
   7944 #  endif
   7945 
   7946    this->next->set(this->next, that, pp, pi);
   7947 }
   7948 
   7949 static void
   7950 image_transform_png_set_background_mod(const image_transform *this,
   7951     image_pixel *that, png_const_structp pp,
   7952     const transform_display *display)
   7953 {
   7954    /* Check for tRNS first: */
   7955    if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE)
   7956       image_pixel_add_alpha(that, &display->this, 1/*for background*/);
   7957 
   7958    /* This is only necessary if the alpha value is less than 1. */
   7959    if (that->alphaf < 1)
   7960    {
   7961       /* Now we do the background calculation without any gamma correction. */
   7962       if (that->alphaf <= 0)
   7963       {
   7964          that->redf = data.redf;
   7965          that->greenf = data.greenf;
   7966          that->bluef = data.bluef;
   7967 
   7968          that->rede = data.rede;
   7969          that->greene = data.greene;
   7970          that->bluee = data.bluee;
   7971 
   7972          that->red_sBIT= data.red_sBIT;
   7973          that->green_sBIT= data.green_sBIT;
   7974          that->blue_sBIT= data.blue_sBIT;
   7975       }
   7976 
   7977       else /* 0 < alpha < 1 */
   7978       {
   7979          double alf = 1 - that->alphaf;
   7980 
   7981          that->redf = that->redf * that->alphaf + data.redf * alf;
   7982          that->rede = that->rede * that->alphaf + data.rede * alf +
   7983             DBL_EPSILON;
   7984          that->greenf = that->greenf * that->alphaf + data.greenf * alf;
   7985          that->greene = that->greene * that->alphaf + data.greene * alf +
   7986             DBL_EPSILON;
   7987          that->bluef = that->bluef * that->alphaf + data.bluef * alf;
   7988          that->bluee = that->bluee * that->alphaf + data.bluee * alf +
   7989             DBL_EPSILON;
   7990       }
   7991 
   7992       /* Remove the alpha type and set the alpha (not in that order.) */
   7993       that->alphaf = 1;
   7994       that->alphae = 0;
   7995    }
   7996 
   7997    if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA)
   7998       that->colour_type = PNG_COLOR_TYPE_RGB;
   7999    else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   8000       that->colour_type = PNG_COLOR_TYPE_GRAY;
   8001    /* PNG_COLOR_TYPE_PALETTE is not changed */
   8002 
   8003    this->next->mod(this->next, that, pp, display);
   8004 }
   8005 
   8006 #define image_transform_png_set_background_add image_transform_default_add
   8007 
   8008 #undef data
   8009 IT(background);
   8010 #undef PT
   8011 #define PT ITSTRUCT(background)
   8012 #endif /* PNG_READ_BACKGROUND_SUPPORTED */
   8013 
   8014 /* png_set_quantize(png_structp, png_colorp palette, int num_palette,
   8015  *    int maximum_colors, png_const_uint_16p histogram, int full_quantize)
   8016  *
   8017  * Very difficult to validate this!
   8018  */
   8019 /*NOTE: TBD NYI */
   8020 
   8021 /* The data layout transforms are handled by swapping our own channel data,
   8022  * necessarily these need to happen at the end of the transform list because the
   8023  * semantic of the channels changes after these are executed.  Some of these,
   8024  * like set_shift and set_packing, can't be done at present because they change
   8025  * the layout of the data at the sub-sample level so sample() won't get the
   8026  * right answer.
   8027  */
   8028 /* png_set_invert_alpha */
   8029 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   8030 /* Invert the alpha channel
   8031  *
   8032  *  png_set_invert_alpha(png_structrp png_ptr)
   8033  */
   8034 static void
   8035 image_transform_png_set_invert_alpha_set(const image_transform *this,
   8036     transform_display *that, png_structp pp, png_infop pi)
   8037 {
   8038    png_set_invert_alpha(pp);
   8039    this->next->set(this->next, that, pp, pi);
   8040 }
   8041 
   8042 static void
   8043 image_transform_png_set_invert_alpha_mod(const image_transform *this,
   8044     image_pixel *that, png_const_structp pp,
   8045     const transform_display *display)
   8046 {
   8047    if (that->colour_type & 4)
   8048       that->alpha_inverted = 1;
   8049 
   8050    this->next->mod(this->next, that, pp, display);
   8051 }
   8052 
   8053 static int
   8054 image_transform_png_set_invert_alpha_add(image_transform *this,
   8055     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8056 {
   8057    UNUSED(bit_depth)
   8058 
   8059    this->next = *that;
   8060    *that = this;
   8061 
   8062    /* Only has an effect on pixels with alpha: */
   8063    return (colour_type & 4) != 0;
   8064 }
   8065 
   8066 IT(invert_alpha);
   8067 #undef PT
   8068 #define PT ITSTRUCT(invert_alpha)
   8069 
   8070 #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
   8071 
   8072 /* png_set_bgr */
   8073 #ifdef PNG_READ_BGR_SUPPORTED
   8074 /* Swap R,G,B channels to order B,G,R.
   8075  *
   8076  *  png_set_bgr(png_structrp png_ptr)
   8077  *
   8078  * This only has an effect on RGB and RGBA pixels.
   8079  */
   8080 static void
   8081 image_transform_png_set_bgr_set(const image_transform *this,
   8082     transform_display *that, png_structp pp, png_infop pi)
   8083 {
   8084    png_set_bgr(pp);
   8085    this->next->set(this->next, that, pp, pi);
   8086 }
   8087 
   8088 static void
   8089 image_transform_png_set_bgr_mod(const image_transform *this,
   8090     image_pixel *that, png_const_structp pp,
   8091     const transform_display *display)
   8092 {
   8093    if (that->colour_type == PNG_COLOR_TYPE_RGB ||
   8094        that->colour_type == PNG_COLOR_TYPE_RGBA)
   8095        that->swap_rgb = 1;
   8096 
   8097    this->next->mod(this->next, that, pp, display);
   8098 }
   8099 
   8100 static int
   8101 image_transform_png_set_bgr_add(image_transform *this,
   8102     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8103 {
   8104    UNUSED(bit_depth)
   8105 
   8106    this->next = *that;
   8107    *that = this;
   8108 
   8109    return colour_type == PNG_COLOR_TYPE_RGB ||
   8110        colour_type == PNG_COLOR_TYPE_RGBA;
   8111 }
   8112 
   8113 IT(bgr);
   8114 #undef PT
   8115 #define PT ITSTRUCT(bgr)
   8116 
   8117 #endif /* PNG_READ_BGR_SUPPORTED */
   8118 
   8119 /* png_set_swap_alpha */
   8120 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   8121 /* Put the alpha channel first.
   8122  *
   8123  *  png_set_swap_alpha(png_structrp png_ptr)
   8124  *
   8125  * This only has an effect on GA and RGBA pixels.
   8126  */
   8127 static void
   8128 image_transform_png_set_swap_alpha_set(const image_transform *this,
   8129     transform_display *that, png_structp pp, png_infop pi)
   8130 {
   8131    png_set_swap_alpha(pp);
   8132    this->next->set(this->next, that, pp, pi);
   8133 }
   8134 
   8135 static void
   8136 image_transform_png_set_swap_alpha_mod(const image_transform *this,
   8137     image_pixel *that, png_const_structp pp,
   8138     const transform_display *display)
   8139 {
   8140    if (that->colour_type == PNG_COLOR_TYPE_GA ||
   8141        that->colour_type == PNG_COLOR_TYPE_RGBA)
   8142       that->alpha_first = 1;
   8143 
   8144    this->next->mod(this->next, that, pp, display);
   8145 }
   8146 
   8147 static int
   8148 image_transform_png_set_swap_alpha_add(image_transform *this,
   8149     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8150 {
   8151    UNUSED(bit_depth)
   8152 
   8153    this->next = *that;
   8154    *that = this;
   8155 
   8156    return colour_type == PNG_COLOR_TYPE_GA ||
   8157        colour_type == PNG_COLOR_TYPE_RGBA;
   8158 }
   8159 
   8160 IT(swap_alpha);
   8161 #undef PT
   8162 #define PT ITSTRUCT(swap_alpha)
   8163 
   8164 #endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */
   8165 
   8166 /* png_set_swap */
   8167 #ifdef PNG_READ_SWAP_SUPPORTED
   8168 /* Byte swap 16-bit components.
   8169  *
   8170  *  png_set_swap(png_structrp png_ptr)
   8171  */
   8172 static void
   8173 image_transform_png_set_swap_set(const image_transform *this,
   8174     transform_display *that, png_structp pp, png_infop pi)
   8175 {
   8176    png_set_swap(pp);
   8177    this->next->set(this->next, that, pp, pi);
   8178 }
   8179 
   8180 static void
   8181 image_transform_png_set_swap_mod(const image_transform *this,
   8182     image_pixel *that, png_const_structp pp,
   8183     const transform_display *display)
   8184 {
   8185    if (that->bit_depth == 16)
   8186       that->swap16 = 1;
   8187 
   8188    this->next->mod(this->next, that, pp, display);
   8189 }
   8190 
   8191 static int
   8192 image_transform_png_set_swap_add(image_transform *this,
   8193     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8194 {
   8195    UNUSED(colour_type)
   8196 
   8197    this->next = *that;
   8198    *that = this;
   8199 
   8200    return bit_depth == 16;
   8201 }
   8202 
   8203 IT(swap);
   8204 #undef PT
   8205 #define PT ITSTRUCT(swap)
   8206 
   8207 #endif /* PNG_READ_SWAP_SUPPORTED */
   8208 
   8209 #ifdef PNG_READ_FILLER_SUPPORTED
   8210 /* Add a filler byte to 8-bit Gray or 24-bit RGB images.
   8211  *
   8212  *  png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags));
   8213  *
   8214  * Flags:
   8215  *
   8216  *  PNG_FILLER_BEFORE
   8217  *  PNG_FILLER_AFTER
   8218  */
   8219 #define data ITDATA(filler)
   8220 static struct
   8221 {
   8222    png_uint_32 filler;
   8223    int         flags;
   8224 } data;
   8225 
   8226 static void
   8227 image_transform_png_set_filler_set(const image_transform *this,
   8228     transform_display *that, png_structp pp, png_infop pi)
   8229 {
   8230    /* Need a random choice for 'before' and 'after' as well as for the
   8231     * filler.  The 'filler' value has all 32 bits set, but only bit_depth
   8232     * will be used.  At this point we don't know bit_depth.
   8233     */
   8234    R32(data.filler);
   8235    data.flags = random_choice();
   8236 
   8237    png_set_filler(pp, data.filler, data.flags);
   8238 
   8239    /* The standard display handling stuff also needs to know that
   8240     * there is a filler, so set that here.
   8241     */
   8242    that->this.filler = 1;
   8243 
   8244    this->next->set(this->next, that, pp, pi);
   8245 }
   8246 
   8247 static void
   8248 image_transform_png_set_filler_mod(const image_transform *this,
   8249     image_pixel *that, png_const_structp pp,
   8250     const transform_display *display)
   8251 {
   8252    if (that->bit_depth >= 8 &&
   8253        (that->colour_type == PNG_COLOR_TYPE_RGB ||
   8254         that->colour_type == PNG_COLOR_TYPE_GRAY))
   8255    {
   8256       const unsigned int max = (1U << that->bit_depth)-1;
   8257       that->alpha = data.filler & max;
   8258       that->alphaf = ((double)that->alpha) / max;
   8259       that->alphae = 0;
   8260 
   8261       /* The filler has been stored in the alpha channel, we must record
   8262        * that this has been done for the checking later on, the color
   8263        * type is faked to have an alpha channel, but libpng won't report
   8264        * this; the app has to know the extra channel is there and this
   8265        * was recording in standard_display::filler above.
   8266        */
   8267       that->colour_type |= 4; /* alpha added */
   8268       that->alpha_first = data.flags == PNG_FILLER_BEFORE;
   8269    }
   8270 
   8271    this->next->mod(this->next, that, pp, display);
   8272 }
   8273 
   8274 static int
   8275 image_transform_png_set_filler_add(image_transform *this,
   8276     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8277 {
   8278    this->next = *that;
   8279    *that = this;
   8280 
   8281    return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
   8282            colour_type == PNG_COLOR_TYPE_GRAY);
   8283 }
   8284 
   8285 #undef data
   8286 IT(filler);
   8287 #undef PT
   8288 #define PT ITSTRUCT(filler)
   8289 
   8290 /* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */
   8291 /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
   8292 #define data ITDATA(add_alpha)
   8293 static struct
   8294 {
   8295    png_uint_32 filler;
   8296    int         flags;
   8297 } data;
   8298 
   8299 static void
   8300 image_transform_png_set_add_alpha_set(const image_transform *this,
   8301     transform_display *that, png_structp pp, png_infop pi)
   8302 {
   8303    /* Need a random choice for 'before' and 'after' as well as for the
   8304     * filler.  The 'filler' value has all 32 bits set, but only bit_depth
   8305     * will be used.  At this point we don't know bit_depth.
   8306     */
   8307    R32(data.filler);
   8308    data.flags = random_choice();
   8309 
   8310    png_set_add_alpha(pp, data.filler, data.flags);
   8311    this->next->set(this->next, that, pp, pi);
   8312 }
   8313 
   8314 static void
   8315 image_transform_png_set_add_alpha_mod(const image_transform *this,
   8316     image_pixel *that, png_const_structp pp,
   8317     const transform_display *display)
   8318 {
   8319    if (that->bit_depth >= 8 &&
   8320        (that->colour_type == PNG_COLOR_TYPE_RGB ||
   8321         that->colour_type == PNG_COLOR_TYPE_GRAY))
   8322    {
   8323       const unsigned int max = (1U << that->bit_depth)-1;
   8324       that->alpha = data.filler & max;
   8325       that->alphaf = ((double)that->alpha) / max;
   8326       that->alphae = 0;
   8327 
   8328       that->colour_type |= 4; /* alpha added */
   8329       that->alpha_first = data.flags == PNG_FILLER_BEFORE;
   8330    }
   8331 
   8332    this->next->mod(this->next, that, pp, display);
   8333 }
   8334 
   8335 static int
   8336 image_transform_png_set_add_alpha_add(image_transform *this,
   8337     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8338 {
   8339    this->next = *that;
   8340    *that = this;
   8341 
   8342    return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB ||
   8343            colour_type == PNG_COLOR_TYPE_GRAY);
   8344 }
   8345 
   8346 #undef data
   8347 IT(add_alpha);
   8348 #undef PT
   8349 #define PT ITSTRUCT(add_alpha)
   8350 
   8351 #endif /* PNG_READ_FILLER_SUPPORTED */
   8352 
   8353 /* png_set_packing */
   8354 #ifdef PNG_READ_PACK_SUPPORTED
   8355 /* Use 1 byte per pixel in 1, 2, or 4-bit depth files.
   8356  *
   8357  *  png_set_packing(png_structrp png_ptr)
   8358  *
   8359  * This should only affect grayscale and palette images with less than 8 bits
   8360  * per pixel.
   8361  */
   8362 static void
   8363 image_transform_png_set_packing_set(const image_transform *this,
   8364     transform_display *that, png_structp pp, png_infop pi)
   8365 {
   8366    png_set_packing(pp);
   8367    that->unpacked = 1;
   8368    this->next->set(this->next, that, pp, pi);
   8369 }
   8370 
   8371 static void
   8372 image_transform_png_set_packing_mod(const image_transform *this,
   8373     image_pixel *that, png_const_structp pp,
   8374     const transform_display *display)
   8375 {
   8376    /* The general expand case depends on what the colour type is,
   8377     * low bit-depth pixel values are unpacked into bytes without
   8378     * scaling, so sample_depth is not changed.
   8379     */
   8380    if (that->bit_depth < 8) /* grayscale or palette */
   8381       that->bit_depth = 8;
   8382 
   8383    this->next->mod(this->next, that, pp, display);
   8384 }
   8385 
   8386 static int
   8387 image_transform_png_set_packing_add(image_transform *this,
   8388     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8389 {
   8390    UNUSED(colour_type)
   8391 
   8392    this->next = *that;
   8393    *that = this;
   8394 
   8395    /* Nothing should happen unless the bit depth is less than 8: */
   8396    return bit_depth < 8;
   8397 }
   8398 
   8399 IT(packing);
   8400 #undef PT
   8401 #define PT ITSTRUCT(packing)
   8402 
   8403 #endif /* PNG_READ_PACK_SUPPORTED */
   8404 
   8405 /* png_set_packswap */
   8406 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   8407 /* Swap pixels packed into bytes; reverses the order on screen so that
   8408  * the high order bits correspond to the rightmost pixels.
   8409  *
   8410  *  png_set_packswap(png_structrp png_ptr)
   8411  */
   8412 static void
   8413 image_transform_png_set_packswap_set(const image_transform *this,
   8414     transform_display *that, png_structp pp, png_infop pi)
   8415 {
   8416    png_set_packswap(pp);
   8417    that->this.littleendian = 1;
   8418    this->next->set(this->next, that, pp, pi);
   8419 }
   8420 
   8421 static void
   8422 image_transform_png_set_packswap_mod(const image_transform *this,
   8423     image_pixel *that, png_const_structp pp,
   8424     const transform_display *display)
   8425 {
   8426    if (that->bit_depth < 8)
   8427       that->littleendian = 1;
   8428 
   8429    this->next->mod(this->next, that, pp, display);
   8430 }
   8431 
   8432 static int
   8433 image_transform_png_set_packswap_add(image_transform *this,
   8434     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8435 {
   8436    UNUSED(colour_type)
   8437 
   8438    this->next = *that;
   8439    *that = this;
   8440 
   8441    return bit_depth < 8;
   8442 }
   8443 
   8444 IT(packswap);
   8445 #undef PT
   8446 #define PT ITSTRUCT(packswap)
   8447 
   8448 #endif /* PNG_READ_PACKSWAP_SUPPORTED */
   8449 
   8450 
   8451 /* png_set_invert_mono */
   8452 #ifdef PNG_READ_INVERT_MONO_SUPPORTED
   8453 /* Invert the gray channel
   8454  *
   8455  *  png_set_invert_mono(png_structrp png_ptr)
   8456  */
   8457 static void
   8458 image_transform_png_set_invert_mono_set(const image_transform *this,
   8459     transform_display *that, png_structp pp, png_infop pi)
   8460 {
   8461    png_set_invert_mono(pp);
   8462    this->next->set(this->next, that, pp, pi);
   8463 }
   8464 
   8465 static void
   8466 image_transform_png_set_invert_mono_mod(const image_transform *this,
   8467     image_pixel *that, png_const_structp pp,
   8468     const transform_display *display)
   8469 {
   8470    if (that->colour_type & 4)
   8471       that->mono_inverted = 1;
   8472 
   8473    this->next->mod(this->next, that, pp, display);
   8474 }
   8475 
   8476 static int
   8477 image_transform_png_set_invert_mono_add(image_transform *this,
   8478     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8479 {
   8480    UNUSED(bit_depth)
   8481 
   8482    this->next = *that;
   8483    *that = this;
   8484 
   8485    /* Only has an effect on pixels with no colour: */
   8486    return (colour_type & 2) == 0;
   8487 }
   8488 
   8489 IT(invert_mono);
   8490 #undef PT
   8491 #define PT ITSTRUCT(invert_mono)
   8492 
   8493 #endif /* PNG_READ_INVERT_MONO_SUPPORTED */
   8494 
   8495 #ifdef PNG_READ_SHIFT_SUPPORTED
   8496 /* png_set_shift(png_structp, png_const_color_8p true_bits)
   8497  *
   8498  * The output pixels will be shifted by the given true_bits
   8499  * values.
   8500  */
   8501 #define data ITDATA(shift)
   8502 static png_color_8 data;
   8503 
   8504 static void
   8505 image_transform_png_set_shift_set(const image_transform *this,
   8506     transform_display *that, png_structp pp, png_infop pi)
   8507 {
   8508    /* Get a random set of shifts.  The shifts need to do something
   8509     * to test the transform, so they are limited to the bit depth
   8510     * of the input image.  Notice that in the following the 'gray'
   8511     * field is randomized independently.  This acts as a check that
   8512     * libpng does use the correct field.
   8513     */
   8514    const unsigned int depth = that->this.bit_depth;
   8515 
   8516    data.red = (png_byte)/*SAFE*/(random_mod(depth)+1);
   8517    data.green = (png_byte)/*SAFE*/(random_mod(depth)+1);
   8518    data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1);
   8519    data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1);
   8520    data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1);
   8521 
   8522    png_set_shift(pp, &data);
   8523    this->next->set(this->next, that, pp, pi);
   8524 }
   8525 
   8526 static void
   8527 image_transform_png_set_shift_mod(const image_transform *this,
   8528     image_pixel *that, png_const_structp pp,
   8529     const transform_display *display)
   8530 {
   8531    /* Copy the correct values into the sBIT fields, libpng does not do
   8532     * anything to palette data:
   8533     */
   8534    if (that->colour_type != PNG_COLOR_TYPE_PALETTE)
   8535    {
   8536        that->sig_bits = 1;
   8537 
   8538        /* The sBIT fields are reset to the values previously sent to
   8539         * png_set_shift according to the colour type.
   8540         * does.
   8541         */
   8542        if (that->colour_type & 2) /* RGB channels */
   8543        {
   8544           that->red_sBIT = data.red;
   8545           that->green_sBIT = data.green;
   8546           that->blue_sBIT = data.blue;
   8547        }
   8548 
   8549        else /* One grey channel */
   8550           that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray;
   8551 
   8552        that->alpha_sBIT = data.alpha;
   8553    }
   8554 
   8555    this->next->mod(this->next, that, pp, display);
   8556 }
   8557 
   8558 static int
   8559 image_transform_png_set_shift_add(image_transform *this,
   8560     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8561 {
   8562    UNUSED(bit_depth)
   8563 
   8564    this->next = *that;
   8565    *that = this;
   8566 
   8567    return colour_type != PNG_COLOR_TYPE_PALETTE;
   8568 }
   8569 
   8570 IT(shift);
   8571 #undef PT
   8572 #define PT ITSTRUCT(shift)
   8573 
   8574 #endif /* PNG_READ_SHIFT_SUPPORTED */
   8575 
   8576 #ifdef THIS_IS_THE_PROFORMA
   8577 static void
   8578 image_transform_png_set_@_set(const image_transform *this,
   8579     transform_display *that, png_structp pp, png_infop pi)
   8580 {
   8581    png_set_@(pp);
   8582    this->next->set(this->next, that, pp, pi);
   8583 }
   8584 
   8585 static void
   8586 image_transform_png_set_@_mod(const image_transform *this,
   8587     image_pixel *that, png_const_structp pp,
   8588     const transform_display *display)
   8589 {
   8590    this->next->mod(this->next, that, pp, display);
   8591 }
   8592 
   8593 static int
   8594 image_transform_png_set_@_add(image_transform *this,
   8595     const image_transform **that, png_byte colour_type, png_byte bit_depth)
   8596 {
   8597    this->next = *that;
   8598    *that = this;
   8599 
   8600    return 1;
   8601 }
   8602 
   8603 IT(@);
   8604 #endif
   8605 
   8606 
   8607 /* This may just be 'end' if all the transforms are disabled! */
   8608 static image_transform *const image_transform_first = &PT;
   8609 
   8610 static void
   8611 transform_enable(const char *name)
   8612 {
   8613    /* Everything starts out enabled, so if we see an 'enable' disabled
   8614     * everything else the first time round.
   8615     */
   8616    static int all_disabled = 0;
   8617    int found_it = 0;
   8618    image_transform *list = image_transform_first;
   8619 
   8620    while (list != &image_transform_end)
   8621    {
   8622       if (strcmp(list->name, name) == 0)
   8623       {
   8624          list->enable = 1;
   8625          found_it = 1;
   8626       }
   8627       else if (!all_disabled)
   8628          list->enable = 0;
   8629 
   8630       list = list->list;
   8631    }
   8632 
   8633    all_disabled = 1;
   8634 
   8635    if (!found_it)
   8636    {
   8637       fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n",
   8638          name);
   8639       exit(99);
   8640    }
   8641 }
   8642 
   8643 static void
   8644 transform_disable(const char *name)
   8645 {
   8646    image_transform *list = image_transform_first;
   8647 
   8648    while (list != &image_transform_end)
   8649    {
   8650       if (strcmp(list->name, name) == 0)
   8651       {
   8652          list->enable = 0;
   8653          return;
   8654       }
   8655 
   8656       list = list->list;
   8657    }
   8658 
   8659    fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n",
   8660       name);
   8661    exit(99);
   8662 }
   8663 
   8664 static void
   8665 image_transform_reset_count(void)
   8666 {
   8667    image_transform *next = image_transform_first;
   8668    int count = 0;
   8669 
   8670    while (next != &image_transform_end)
   8671    {
   8672       next->local_use = 0;
   8673       next->next = 0;
   8674       next = next->list;
   8675       ++count;
   8676    }
   8677 
   8678    /* This can only happen if we every have more than 32 transforms (excluding
   8679     * the end) in the list.
   8680     */
   8681    if (count > 32) abort();
   8682 }
   8683 
   8684 static int
   8685 image_transform_test_counter(png_uint_32 counter, unsigned int max)
   8686 {
   8687    /* Test the list to see if there is any point contining, given a current
   8688     * counter and a 'max' value.
   8689     */
   8690    image_transform *next = image_transform_first;
   8691 
   8692    while (next != &image_transform_end)
   8693    {
   8694       /* For max 0 or 1 continue until the counter overflows: */
   8695       counter >>= 1;
   8696 
   8697       /* Continue if any entry hasn't reacked the max. */
   8698       if (max > 1 && next->local_use < max)
   8699          return 1;
   8700       next = next->list;
   8701    }
   8702 
   8703    return max <= 1 && counter == 0;
   8704 }
   8705 
   8706 static png_uint_32
   8707 image_transform_add(const image_transform **this, unsigned int max,
   8708    png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos,
   8709    png_byte colour_type, png_byte bit_depth)
   8710 {
   8711    for (;;) /* until we manage to add something */
   8712    {
   8713       png_uint_32 mask;
   8714       image_transform *list;
   8715 
   8716       /* Find the next counter value, if the counter is zero this is the start
   8717        * of the list.  This routine always returns the current counter (not the
   8718        * next) so it returns 0 at the end and expects 0 at the beginning.
   8719        */
   8720       if (counter == 0) /* first time */
   8721       {
   8722          image_transform_reset_count();
   8723          if (max <= 1)
   8724             counter = 1;
   8725          else
   8726             counter = random_32();
   8727       }
   8728       else /* advance the counter */
   8729       {
   8730          switch (max)
   8731          {
   8732             case 0:  ++counter; break;
   8733             case 1:  counter <<= 1; break;
   8734             default: counter = random_32(); break;
   8735          }
   8736       }
   8737 
   8738       /* Now add all these items, if possible */
   8739       *this = &image_transform_end;
   8740       list = image_transform_first;
   8741       mask = 1;
   8742 
   8743       /* Go through the whole list adding anything that the counter selects: */
   8744       while (list != &image_transform_end)
   8745       {
   8746          if ((counter & mask) != 0 && list->enable &&
   8747              (max == 0 || list->local_use < max))
   8748          {
   8749             /* Candidate to add: */
   8750             if (list->add(list, this, colour_type, bit_depth) || max == 0)
   8751             {
   8752                /* Added, so add to the name too. */
   8753                *pos = safecat(name, sizeof_name, *pos, " +");
   8754                *pos = safecat(name, sizeof_name, *pos, list->name);
   8755             }
   8756 
   8757             else
   8758             {
   8759                /* Not useful and max>0, so remove it from *this: */
   8760                *this = list->next;
   8761                list->next = 0;
   8762 
   8763                /* And, since we know it isn't useful, stop it being added again
   8764                 * in this run:
   8765                 */
   8766                list->local_use = max;
   8767             }
   8768          }
   8769 
   8770          mask <<= 1;
   8771          list = list->list;
   8772       }
   8773 
   8774       /* Now if anything was added we have something to do. */
   8775       if (*this != &image_transform_end)
   8776          return counter;
   8777 
   8778       /* Nothing added, but was there anything in there to add? */
   8779       if (!image_transform_test_counter(counter, max))
   8780          return 0;
   8781    }
   8782 }
   8783 
   8784 static void
   8785 perform_transform_test(png_modifier *pm)
   8786 {
   8787    png_byte colour_type = 0;
   8788    png_byte bit_depth = 0;
   8789    unsigned int palette_number = 0;
   8790 
   8791    while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg,
   8792             pm->test_tRNS))
   8793    {
   8794       png_uint_32 counter = 0;
   8795       size_t base_pos;
   8796       char name[64];
   8797 
   8798       base_pos = safecat(name, sizeof name, 0, "transform:");
   8799 
   8800       for (;;)
   8801       {
   8802          size_t pos = base_pos;
   8803          const image_transform *list = 0;
   8804 
   8805          /* 'max' is currently hardwired to '1'; this should be settable on the
   8806           * command line.
   8807           */
   8808          counter = image_transform_add(&list, 1/*max*/, counter,
   8809             name, sizeof name, &pos, colour_type, bit_depth);
   8810 
   8811          if (counter == 0)
   8812             break;
   8813 
   8814          /* The command line can change this to checking interlaced images. */
   8815          do
   8816          {
   8817             pm->repeat = 0;
   8818             transform_test(pm, FILEID(colour_type, bit_depth, palette_number,
   8819                pm->interlace_type, 0, 0, 0), list, name);
   8820 
   8821             if (fail(pm))
   8822                return;
   8823          }
   8824          while (pm->repeat);
   8825       }
   8826    }
   8827 }
   8828 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
   8829 
   8830 /********************************* GAMMA TESTS ********************************/
   8831 #ifdef PNG_READ_GAMMA_SUPPORTED
   8832 /* Reader callbacks and implementations, where they differ from the standard
   8833  * ones.
   8834  */
   8835 typedef struct gamma_display
   8836 {
   8837    standard_display this;
   8838 
   8839    /* Parameters */
   8840    png_modifier*    pm;
   8841    double           file_gamma;
   8842    double           screen_gamma;
   8843    double           background_gamma;
   8844    png_byte         sbit;
   8845    int              threshold_test;
   8846    int              use_input_precision;
   8847    int              scale16;
   8848    int              expand16;
   8849    int              do_background;
   8850    png_color_16     background_color;
   8851 
   8852    /* Local variables */
   8853    double       maxerrout;
   8854    double       maxerrpc;
   8855    double       maxerrabs;
   8856 } gamma_display;
   8857 
   8858 #define ALPHA_MODE_OFFSET 4
   8859 
   8860 static void
   8861 gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id,
   8862     double file_gamma, double screen_gamma, png_byte sbit, int threshold_test,
   8863     int use_input_precision, int scale16, int expand16,
   8864     int do_background, const png_color_16 *pointer_to_the_background_color,
   8865     double background_gamma)
   8866 {
   8867    /* Standard fields */
   8868    standard_display_init(&dp->this, &pm->this, id, do_read_interlace,
   8869       pm->use_update_info);
   8870 
   8871    /* Parameter fields */
   8872    dp->pm = pm;
   8873    dp->file_gamma = file_gamma;
   8874    dp->screen_gamma = screen_gamma;
   8875    dp->background_gamma = background_gamma;
   8876    dp->sbit = sbit;
   8877    dp->threshold_test = threshold_test;
   8878    dp->use_input_precision = use_input_precision;
   8879    dp->scale16 = scale16;
   8880    dp->expand16 = expand16;
   8881    dp->do_background = do_background;
   8882    if (do_background && pointer_to_the_background_color != 0)
   8883       dp->background_color = *pointer_to_the_background_color;
   8884    else
   8885       memset(&dp->background_color, 0, sizeof dp->background_color);
   8886 
   8887    /* Local variable fields */
   8888    dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0;
   8889 }
   8890 
   8891 static void
   8892 gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi)
   8893 {
   8894    /* Reuse the standard stuff as appropriate. */
   8895    standard_info_part1(&dp->this, pp, pi);
   8896 
   8897    /* If requested strip 16 to 8 bits - this is handled automagically below
   8898     * because the output bit depth is read from the library.  Note that there
   8899     * are interactions with sBIT but, internally, libpng makes sbit at most
   8900     * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following.
   8901     */
   8902    if (dp->scale16)
   8903 #     ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
   8904          png_set_scale_16(pp);
   8905 #     else
   8906          /* The following works both in 1.5.4 and earlier versions: */
   8907 #        ifdef PNG_READ_16_TO_8_SUPPORTED
   8908             png_set_strip_16(pp);
   8909 #        else
   8910             png_error(pp, "scale16 (16 to 8 bit conversion) not supported");
   8911 #        endif
   8912 #     endif
   8913 
   8914    if (dp->expand16)
   8915 #     ifdef PNG_READ_EXPAND_16_SUPPORTED
   8916          png_set_expand_16(pp);
   8917 #     else
   8918          png_error(pp, "expand16 (8 to 16 bit conversion) not supported");
   8919 #     endif
   8920 
   8921    if (dp->do_background >= ALPHA_MODE_OFFSET)
   8922    {
   8923 #     ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   8924       {
   8925          /* This tests the alpha mode handling, if supported. */
   8926          int mode = dp->do_background - ALPHA_MODE_OFFSET;
   8927 
   8928          /* The gamma value is the output gamma, and is in the standard,
   8929           * non-inverted, represenation.  It provides a default for the PNG file
   8930           * gamma, but since the file has a gAMA chunk this does not matter.
   8931           */
   8932          const double sg = dp->screen_gamma;
   8933 #        ifndef PNG_FLOATING_POINT_SUPPORTED
   8934             const png_fixed_point g = fix(sg);
   8935 #        endif
   8936 
   8937 #        ifdef PNG_FLOATING_POINT_SUPPORTED
   8938             png_set_alpha_mode(pp, mode, sg);
   8939 #        else
   8940             png_set_alpha_mode_fixed(pp, mode, g);
   8941 #        endif
   8942 
   8943          /* However, for the standard Porter-Duff algorithm the output defaults
   8944           * to be linear, so if the test requires non-linear output it must be
   8945           * corrected here.
   8946           */
   8947          if (mode == PNG_ALPHA_STANDARD && sg != 1)
   8948          {
   8949 #           ifdef PNG_FLOATING_POINT_SUPPORTED
   8950                png_set_gamma(pp, sg, dp->file_gamma);
   8951 #           else
   8952                png_fixed_point f = fix(dp->file_gamma);
   8953                png_set_gamma_fixed(pp, g, f);
   8954 #           endif
   8955          }
   8956       }
   8957 #     else
   8958          png_error(pp, "alpha mode handling not supported");
   8959 #     endif
   8960    }
   8961 
   8962    else
   8963    {
   8964       /* Set up gamma processing. */
   8965 #     ifdef PNG_FLOATING_POINT_SUPPORTED
   8966          png_set_gamma(pp, dp->screen_gamma, dp->file_gamma);
   8967 #     else
   8968       {
   8969          png_fixed_point s = fix(dp->screen_gamma);
   8970          png_fixed_point f = fix(dp->file_gamma);
   8971          png_set_gamma_fixed(pp, s, f);
   8972       }
   8973 #     endif
   8974 
   8975       if (dp->do_background)
   8976       {
   8977 #     ifdef PNG_READ_BACKGROUND_SUPPORTED
   8978          /* NOTE: this assumes the caller provided the correct background gamma!
   8979           */
   8980          const double bg = dp->background_gamma;
   8981 #        ifndef PNG_FLOATING_POINT_SUPPORTED
   8982             const png_fixed_point g = fix(bg);
   8983 #        endif
   8984 
   8985 #        ifdef PNG_FLOATING_POINT_SUPPORTED
   8986             png_set_background(pp, &dp->background_color, dp->do_background,
   8987                0/*need_expand*/, bg);
   8988 #        else
   8989             png_set_background_fixed(pp, &dp->background_color,
   8990                dp->do_background, 0/*need_expand*/, g);
   8991 #        endif
   8992 #     else
   8993          png_error(pp, "png_set_background not supported");
   8994 #     endif
   8995       }
   8996    }
   8997 
   8998    {
   8999       int i = dp->this.use_update_info;
   9000       /* Always do one call, even if use_update_info is 0. */
   9001       do
   9002          png_read_update_info(pp, pi);
   9003       while (--i > 0);
   9004    }
   9005 
   9006    /* Now we may get a different cbRow: */
   9007    standard_info_part2(&dp->this, pp, pi, 1 /*images*/);
   9008 }
   9009 
   9010 static void PNGCBAPI
   9011 gamma_info(png_structp pp, png_infop pi)
   9012 {
   9013    gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp,
   9014       pi);
   9015 }
   9016 
   9017 /* Validate a single component value - the routine gets the input and output
   9018  * sample values as unscaled PNG component values along with a cache of all the
   9019  * information required to validate the values.
   9020  */
   9021 typedef struct validate_info
   9022 {
   9023    png_const_structp  pp;
   9024    gamma_display *dp;
   9025    png_byte sbit;
   9026    int use_input_precision;
   9027    int do_background;
   9028    int scale16;
   9029    unsigned int sbit_max;
   9030    unsigned int isbit_shift;
   9031    unsigned int outmax;
   9032 
   9033    double gamma_correction; /* Overall correction required. */
   9034    double file_inverse;     /* Inverse of file gamma. */
   9035    double screen_gamma;
   9036    double screen_inverse;   /* Inverse of screen gamma. */
   9037 
   9038    double background_red;   /* Linear background value, red or gray. */
   9039    double background_green;
   9040    double background_blue;
   9041 
   9042    double maxabs;
   9043    double maxpc;
   9044    double maxcalc;
   9045    double maxout;
   9046    double maxout_total;     /* Total including quantization error */
   9047    double outlog;
   9048    int    outquant;
   9049 }
   9050 validate_info;
   9051 
   9052 static void
   9053 init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp,
   9054     int in_depth, int out_depth)
   9055 {
   9056    const unsigned int outmax = (1U<<out_depth)-1;
   9057 
   9058    vi->pp = pp;
   9059    vi->dp = dp;
   9060 
   9061    if (dp->sbit > 0 && dp->sbit < in_depth)
   9062    {
   9063       vi->sbit = dp->sbit;
   9064       vi->isbit_shift = in_depth - dp->sbit;
   9065    }
   9066 
   9067    else
   9068    {
   9069       vi->sbit = (png_byte)in_depth;
   9070       vi->isbit_shift = 0;
   9071    }
   9072 
   9073    vi->sbit_max = (1U << vi->sbit)-1;
   9074 
   9075    /* This mimics the libpng threshold test, '0' is used to prevent gamma
   9076     * correction in the validation test.
   9077     */
   9078    vi->screen_gamma = dp->screen_gamma;
   9079    if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD)
   9080       vi->screen_gamma = vi->screen_inverse = 0;
   9081    else
   9082       vi->screen_inverse = 1/vi->screen_gamma;
   9083 
   9084    vi->use_input_precision = dp->use_input_precision;
   9085    vi->outmax = outmax;
   9086    vi->maxabs = abserr(dp->pm, in_depth, out_depth);
   9087    vi->maxpc = pcerr(dp->pm, in_depth, out_depth);
   9088    vi->maxcalc = calcerr(dp->pm, in_depth, out_depth);
   9089    vi->maxout = outerr(dp->pm, in_depth, out_depth);
   9090    vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth);
   9091    vi->maxout_total = vi->maxout + vi->outquant * .5;
   9092    vi->outlog = outlog(dp->pm, in_depth, out_depth);
   9093 
   9094    if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 ||
   9095       (dp->this.colour_type == 3 && dp->this.is_transparent) ||
   9096       ((dp->this.colour_type == 0 || dp->this.colour_type == 2) &&
   9097        dp->this.has_tRNS))
   9098    {
   9099       vi->do_background = dp->do_background;
   9100 
   9101       if (vi->do_background != 0)
   9102       {
   9103          const double bg_inverse = 1/dp->background_gamma;
   9104          double r, g, b;
   9105 
   9106          /* Caller must at least put the gray value into the red channel */
   9107          r = dp->background_color.red; r /= outmax;
   9108          g = dp->background_color.green; g /= outmax;
   9109          b = dp->background_color.blue; b /= outmax;
   9110 
   9111 #     if 0
   9112          /* libpng doesn't do this optimization, if we do pngvalid will fail.
   9113           */
   9114          if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD)
   9115 #     endif
   9116          {
   9117             r = pow(r, bg_inverse);
   9118             g = pow(g, bg_inverse);
   9119             b = pow(b, bg_inverse);
   9120          }
   9121 
   9122          vi->background_red = r;
   9123          vi->background_green = g;
   9124          vi->background_blue = b;
   9125       }
   9126    }
   9127    else /* Do not expect any background processing */
   9128       vi->do_background = 0;
   9129 
   9130    if (vi->do_background == 0)
   9131       vi->background_red = vi->background_green = vi->background_blue = 0;
   9132 
   9133    vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma);
   9134    if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD)
   9135       vi->gamma_correction = 0;
   9136 
   9137    vi->file_inverse = 1/dp->file_gamma;
   9138    if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD)
   9139       vi->file_inverse = 0;
   9140 
   9141    vi->scale16 = dp->scale16;
   9142 }
   9143 
   9144 /* This function handles composition of a single non-alpha component.  The
   9145  * argument is the input sample value, in the range 0..1, and the alpha value.
   9146  * The result is the composed, linear, input sample.  If alpha is less than zero
   9147  * this is the alpha component and the function should not be called!
   9148  */
   9149 static double
   9150 gamma_component_compose(int do_background, double input_sample, double alpha,
   9151    double background, int *compose)
   9152 {
   9153    switch (do_background)
   9154    {
   9155 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   9156       case PNG_BACKGROUND_GAMMA_SCREEN:
   9157       case PNG_BACKGROUND_GAMMA_FILE:
   9158       case PNG_BACKGROUND_GAMMA_UNIQUE:
   9159          /* Standard PNG background processing. */
   9160          if (alpha < 1)
   9161          {
   9162             if (alpha > 0)
   9163             {
   9164                input_sample = input_sample * alpha + background * (1-alpha);
   9165                if (compose != NULL)
   9166                   *compose = 1;
   9167             }
   9168 
   9169             else
   9170                input_sample = background;
   9171          }
   9172          break;
   9173 #endif
   9174 
   9175 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9176       case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
   9177       case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
   9178          /* The components are premultiplied in either case and the output is
   9179           * gamma encoded (to get standard Porter-Duff we expect the output
   9180           * gamma to be set to 1.0!)
   9181           */
   9182       case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
   9183          /* The optimization is that the partial-alpha entries are linear
   9184           * while the opaque pixels are gamma encoded, but this only affects the
   9185           * output encoding.
   9186           */
   9187          if (alpha < 1)
   9188          {
   9189             if (alpha > 0)
   9190             {
   9191                input_sample *= alpha;
   9192                if (compose != NULL)
   9193                   *compose = 1;
   9194             }
   9195 
   9196             else
   9197                input_sample = 0;
   9198          }
   9199          break;
   9200 #endif
   9201 
   9202       default:
   9203          /* Standard cases where no compositing is done (so the component
   9204           * value is already correct.)
   9205           */
   9206          UNUSED(alpha)
   9207          UNUSED(background)
   9208          UNUSED(compose)
   9209          break;
   9210    }
   9211 
   9212    return input_sample;
   9213 }
   9214 
   9215 /* This API returns the encoded *input* component, in the range 0..1 */
   9216 static double
   9217 gamma_component_validate(const char *name, const validate_info *vi,
   9218     const unsigned int id, const unsigned int od,
   9219     const double alpha /* <0 for the alpha channel itself */,
   9220     const double background /* component background value */)
   9221 {
   9222    const unsigned int isbit = id >> vi->isbit_shift;
   9223    const unsigned int sbit_max = vi->sbit_max;
   9224    const unsigned int outmax = vi->outmax;
   9225    const int do_background = vi->do_background;
   9226 
   9227    double i;
   9228 
   9229    /* First check on the 'perfect' result obtained from the digitized input
   9230     * value, id, and compare this against the actual digitized result, 'od'.
   9231     * 'i' is the input result in the range 0..1:
   9232     */
   9233    i = isbit; i /= sbit_max;
   9234 
   9235    /* Check for the fast route: if we don't do any background composition or if
   9236     * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then
   9237     * just use the gamma_correction field to correct to the final output gamma.
   9238     */
   9239    if (alpha == 1 /* opaque pixel component */ || !do_background
   9240 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9241       || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG
   9242 #endif
   9243       || (alpha < 0 /* alpha channel */
   9244 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9245       && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN
   9246 #endif
   9247       ))
   9248    {
   9249       /* Then get the gamma corrected version of 'i' and compare to 'od', any
   9250        * error less than .5 is insignificant - just quantization of the output
   9251        * value to the nearest digital value (nevertheless the error is still
   9252        * recorded - it's interesting ;-)
   9253        */
   9254       double encoded_sample = i;
   9255       double encoded_error;
   9256 
   9257       /* alpha less than 0 indicates the alpha channel, which is always linear
   9258        */
   9259       if (alpha >= 0 && vi->gamma_correction > 0)
   9260          encoded_sample = pow(encoded_sample, vi->gamma_correction);
   9261       encoded_sample *= outmax;
   9262 
   9263       encoded_error = fabs(od-encoded_sample);
   9264 
   9265       if (encoded_error > vi->dp->maxerrout)
   9266          vi->dp->maxerrout = encoded_error;
   9267 
   9268       if (encoded_error < vi->maxout_total && encoded_error < vi->outlog)
   9269          return i;
   9270    }
   9271 
   9272    /* The slow route - attempt to do linear calculations. */
   9273    /* There may be an error, or background processing is required, so calculate
   9274     * the actual sample values - unencoded light intensity values.  Note that in
   9275     * practice these are not completely unencoded because they include a
   9276     * 'viewing correction' to decrease or (normally) increase the perceptual
   9277     * contrast of the image.  There's nothing we can do about this - we don't
   9278     * know what it is - so assume the unencoded value is perceptually linear.
   9279     */
   9280    {
   9281       double input_sample = i; /* In range 0..1 */
   9282       double output, error, encoded_sample, encoded_error;
   9283       double es_lo, es_hi;
   9284       int compose = 0;           /* Set to one if composition done */
   9285       int output_is_encoded;     /* Set if encoded to screen gamma */
   9286       int log_max_error = 1;     /* Check maximum error values */
   9287       png_const_charp pass = 0;  /* Reason test passes (or 0 for fail) */
   9288 
   9289       /* Convert to linear light (with the above caveat.)  The alpha channel is
   9290        * already linear.
   9291        */
   9292       if (alpha >= 0)
   9293       {
   9294          int tcompose;
   9295 
   9296          if (vi->file_inverse > 0)
   9297             input_sample = pow(input_sample, vi->file_inverse);
   9298 
   9299          /* Handle the compose processing: */
   9300          tcompose = 0;
   9301          input_sample = gamma_component_compose(do_background, input_sample,
   9302             alpha, background, &tcompose);
   9303 
   9304          if (tcompose)
   9305             compose = 1;
   9306       }
   9307 
   9308       /* And similarly for the output value, but we need to check the background
   9309        * handling to linearize it correctly.
   9310        */
   9311       output = od;
   9312       output /= outmax;
   9313 
   9314       output_is_encoded = vi->screen_gamma > 0;
   9315 
   9316       if (alpha < 0) /* The alpha channel */
   9317       {
   9318 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9319          if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN)
   9320 #endif
   9321          {
   9322             /* In all other cases the output alpha channel is linear already,
   9323              * don't log errors here, they are much larger in linear data.
   9324              */
   9325             output_is_encoded = 0;
   9326             log_max_error = 0;
   9327          }
   9328       }
   9329 
   9330 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9331       else /* A component */
   9332       {
   9333          if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED &&
   9334             alpha < 1) /* the optimized case - linear output */
   9335          {
   9336             if (alpha > 0) log_max_error = 0;
   9337             output_is_encoded = 0;
   9338          }
   9339       }
   9340 #endif
   9341 
   9342       if (output_is_encoded)
   9343          output = pow(output, vi->screen_gamma);
   9344 
   9345       /* Calculate (or recalculate) the encoded_sample value and repeat the
   9346        * check above (unnecessary if we took the fast route, but harmless.)
   9347        */
   9348       encoded_sample = input_sample;
   9349       if (output_is_encoded)
   9350          encoded_sample = pow(encoded_sample, vi->screen_inverse);
   9351       encoded_sample *= outmax;
   9352 
   9353       encoded_error = fabs(od-encoded_sample);
   9354 
   9355       /* Don't log errors in the alpha channel, or the 'optimized' case,
   9356        * neither are significant to the overall perception.
   9357        */
   9358       if (log_max_error && encoded_error > vi->dp->maxerrout)
   9359          vi->dp->maxerrout = encoded_error;
   9360 
   9361       if (encoded_error < vi->maxout_total)
   9362       {
   9363          if (encoded_error < vi->outlog)
   9364             return i;
   9365 
   9366          /* Test passed but error is bigger than the log limit, record why the
   9367           * test passed:
   9368           */
   9369          pass = "less than maxout:\n";
   9370       }
   9371 
   9372       /* i: the original input value in the range 0..1
   9373        *
   9374        * pngvalid calculations:
   9375        *  input_sample: linear result; i linearized and composed, range 0..1
   9376        *  encoded_sample: encoded result; input_sample scaled to ouput bit depth
   9377        *
   9378        * libpng calculations:
   9379        *  output: linear result; od scaled to 0..1 and linearized
   9380        *  od: encoded result from libpng
   9381        */
   9382 
   9383       /* Now we have the numbers for real errors, both absolute values as as a
   9384        * percentage of the correct value (output):
   9385        */
   9386       error = fabs(input_sample-output);
   9387 
   9388       if (log_max_error && error > vi->dp->maxerrabs)
   9389          vi->dp->maxerrabs = error;
   9390 
   9391       /* The following is an attempt to ignore the tendency of quantization to
   9392        * dominate the percentage errors for lower result values:
   9393        */
   9394       if (log_max_error && input_sample > .5)
   9395       {
   9396          double percentage_error = error/input_sample;
   9397          if (percentage_error > vi->dp->maxerrpc)
   9398             vi->dp->maxerrpc = percentage_error;
   9399       }
   9400 
   9401       /* Now calculate the digitization limits for 'encoded_sample' using the
   9402        * 'max' values.  Note that maxout is in the encoded space but maxpc and
   9403        * maxabs are in linear light space.
   9404        *
   9405        * First find the maximum error in linear light space, range 0..1:
   9406        */
   9407       {
   9408          double tmp = input_sample * vi->maxpc;
   9409          if (tmp < vi->maxabs) tmp = vi->maxabs;
   9410          /* If 'compose' is true the composition was done in linear space using
   9411           * integer arithmetic.  This introduces an extra error of +/- 0.5 (at
   9412           * least) in the integer space used.  'maxcalc' records this, taking
   9413           * into account the possibility that even for 16 bit output 8 bit space
   9414           * may have been used.
   9415           */
   9416          if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc;
   9417 
   9418          /* The 'maxout' value refers to the encoded result, to compare with
   9419           * this encode input_sample adjusted by the maximum error (tmp) above.
   9420           */
   9421          es_lo = encoded_sample - vi->maxout;
   9422 
   9423          if (es_lo > 0 && input_sample-tmp > 0)
   9424          {
   9425             double low_value = input_sample-tmp;
   9426             if (output_is_encoded)
   9427                low_value = pow(low_value, vi->screen_inverse);
   9428             low_value *= outmax;
   9429             if (low_value < es_lo) es_lo = low_value;
   9430 
   9431             /* Quantize this appropriately: */
   9432             es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant;
   9433          }
   9434 
   9435          else
   9436             es_lo = 0;
   9437 
   9438          es_hi = encoded_sample + vi->maxout;
   9439 
   9440          if (es_hi < outmax && input_sample+tmp < 1)
   9441          {
   9442             double high_value = input_sample+tmp;
   9443             if (output_is_encoded)
   9444                high_value = pow(high_value, vi->screen_inverse);
   9445             high_value *= outmax;
   9446             if (high_value > es_hi) es_hi = high_value;
   9447 
   9448             es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant;
   9449          }
   9450 
   9451          else
   9452             es_hi = outmax;
   9453       }
   9454 
   9455       /* The primary test is that the final encoded value returned by the
   9456        * library should be between the two limits (inclusive) that were
   9457        * calculated above.
   9458        */
   9459       if (od >= es_lo && od <= es_hi)
   9460       {
   9461          /* The value passes, but we may need to log the information anyway. */
   9462          if (encoded_error < vi->outlog)
   9463             return i;
   9464 
   9465          if (pass == 0)
   9466             pass = "within digitization limits:\n";
   9467       }
   9468 
   9469       {
   9470          /* There has been an error in processing, or we need to log this
   9471           * value.
   9472           */
   9473          double is_lo, is_hi;
   9474 
   9475          /* pass is set at this point if either of the tests above would have
   9476           * passed.  Don't do these additional tests here - just log the
   9477           * original [es_lo..es_hi] values.
   9478           */
   9479          if (pass == 0 && vi->use_input_precision && vi->dp->sbit)
   9480          {
   9481             /* Ok, something is wrong - this actually happens in current libpng
   9482              * 16-to-8 processing.  Assume that the input value (id, adjusted
   9483              * for sbit) can be anywhere between value-.5 and value+.5 - quite a
   9484              * large range if sbit is low.
   9485              *
   9486              * NOTE: at present because the libpng gamma table stuff has been
   9487              * changed to use a rounding algorithm to correct errors in 8-bit
   9488              * calculations the precise sbit calculation (a shift) has been
   9489              * lost.  This can result in up to a +/-1 error in the presence of
   9490              * an sbit less than the bit depth.
   9491              */
   9492 #           if PNG_LIBPNG_VER < 10700
   9493 #              define SBIT_ERROR .5
   9494 #           else
   9495 #              define SBIT_ERROR 1.
   9496 #           endif
   9497             double tmp = (isbit - SBIT_ERROR)/sbit_max;
   9498 
   9499             if (tmp <= 0)
   9500                tmp = 0;
   9501 
   9502             else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
   9503                tmp = pow(tmp, vi->file_inverse);
   9504 
   9505             tmp = gamma_component_compose(do_background, tmp, alpha, background,
   9506                NULL);
   9507 
   9508             if (output_is_encoded && tmp > 0 && tmp < 1)
   9509                tmp = pow(tmp, vi->screen_inverse);
   9510 
   9511             is_lo = ceil(outmax * tmp - vi->maxout_total);
   9512 
   9513             if (is_lo < 0)
   9514                is_lo = 0;
   9515 
   9516             tmp = (isbit + SBIT_ERROR)/sbit_max;
   9517 
   9518             if (tmp >= 1)
   9519                tmp = 1;
   9520 
   9521             else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1)
   9522                tmp = pow(tmp, vi->file_inverse);
   9523 
   9524             tmp = gamma_component_compose(do_background, tmp, alpha, background,
   9525                NULL);
   9526 
   9527             if (output_is_encoded && tmp > 0 && tmp < 1)
   9528                tmp = pow(tmp, vi->screen_inverse);
   9529 
   9530             is_hi = floor(outmax * tmp + vi->maxout_total);
   9531 
   9532             if (is_hi > outmax)
   9533                is_hi = outmax;
   9534 
   9535             if (!(od < is_lo || od > is_hi))
   9536             {
   9537                if (encoded_error < vi->outlog)
   9538                   return i;
   9539 
   9540                pass = "within input precision limits:\n";
   9541             }
   9542 
   9543             /* One last chance.  If this is an alpha channel and the 16to8
   9544              * option has been used and 'inaccurate' scaling is used then the
   9545              * bit reduction is obtained by simply using the top 8 bits of the
   9546              * value.
   9547              *
   9548              * This is only done for older libpng versions when the 'inaccurate'
   9549              * (chop) method of scaling was used.
   9550              */
   9551 #           ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
   9552 #              if PNG_LIBPNG_VER < 10504
   9553                   /* This may be required for other components in the future,
   9554                    * but at present the presence of gamma correction effectively
   9555                    * prevents the errors in the component scaling (I don't quite
   9556                    * understand why, but since it's better this way I care not
   9557                    * to ask, JB 20110419.)
   9558                    */
   9559                   if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 &&
   9560                      vi->sbit + vi->isbit_shift == 16)
   9561                   {
   9562                      tmp = ((id >> 8) - .5)/255;
   9563 
   9564                      if (tmp > 0)
   9565                      {
   9566                         is_lo = ceil(outmax * tmp - vi->maxout_total);
   9567                         if (is_lo < 0) is_lo = 0;
   9568                      }
   9569 
   9570                      else
   9571                         is_lo = 0;
   9572 
   9573                      tmp = ((id >> 8) + .5)/255;
   9574 
   9575                      if (tmp < 1)
   9576                      {
   9577                         is_hi = floor(outmax * tmp + vi->maxout_total);
   9578                         if (is_hi > outmax) is_hi = outmax;
   9579                      }
   9580 
   9581                      else
   9582                         is_hi = outmax;
   9583 
   9584                      if (!(od < is_lo || od > is_hi))
   9585                      {
   9586                         if (encoded_error < vi->outlog)
   9587                            return i;
   9588 
   9589                         pass = "within 8 bit limits:\n";
   9590                      }
   9591                   }
   9592 #              endif
   9593 #           endif
   9594          }
   9595          else /* !use_input_precision */
   9596             is_lo = es_lo, is_hi = es_hi;
   9597 
   9598          /* Attempt to output a meaningful error/warning message: the message
   9599           * output depends on the background/composite operation being performed
   9600           * because this changes what parameters were actually used above.
   9601           */
   9602          {
   9603             size_t pos = 0;
   9604             /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal
   9605              * places.  Just use outmax to work out which.
   9606              */
   9607             int precision = (outmax >= 1000 ? 6 : 3);
   9608             int use_input=1, use_background=0, do_compose=0;
   9609             char msg[256];
   9610 
   9611             if (pass != 0)
   9612                pos = safecat(msg, sizeof msg, pos, "\n\t");
   9613 
   9614             /* Set up the various flags, the output_is_encoded flag above
   9615              * is also used below.  do_compose is just a double check.
   9616              */
   9617             switch (do_background)
   9618             {
   9619 #           ifdef PNG_READ_BACKGROUND_SUPPORTED
   9620                case PNG_BACKGROUND_GAMMA_SCREEN:
   9621                case PNG_BACKGROUND_GAMMA_FILE:
   9622                case PNG_BACKGROUND_GAMMA_UNIQUE:
   9623                   use_background = (alpha >= 0 && alpha < 1);
   9624                   /*FALL THROUGH*/
   9625 #           endif
   9626 #           ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   9627                case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
   9628                case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
   9629                case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
   9630 #           endif /* ALPHA_MODE_SUPPORTED */
   9631                do_compose = (alpha > 0 && alpha < 1);
   9632                use_input = (alpha != 0);
   9633                break;
   9634 
   9635             default:
   9636                break;
   9637             }
   9638 
   9639             /* Check the 'compose' flag */
   9640             if (compose != do_compose)
   9641                png_error(vi->pp, "internal error (compose)");
   9642 
   9643             /* 'name' is the component name */
   9644             pos = safecat(msg, sizeof msg, pos, name);
   9645             pos = safecat(msg, sizeof msg, pos, "(");
   9646             pos = safecatn(msg, sizeof msg, pos, id);
   9647             if (use_input || pass != 0/*logging*/)
   9648             {
   9649                if (isbit != id)
   9650                {
   9651                   /* sBIT has reduced the precision of the input: */
   9652                   pos = safecat(msg, sizeof msg, pos, ", sbit(");
   9653                   pos = safecatn(msg, sizeof msg, pos, vi->sbit);
   9654                   pos = safecat(msg, sizeof msg, pos, "): ");
   9655                   pos = safecatn(msg, sizeof msg, pos, isbit);
   9656                }
   9657                pos = safecat(msg, sizeof msg, pos, "/");
   9658                /* The output is either "id/max" or "id sbit(sbit): isbit/max" */
   9659                pos = safecatn(msg, sizeof msg, pos, vi->sbit_max);
   9660             }
   9661             pos = safecat(msg, sizeof msg, pos, ")");
   9662 
   9663             /* A component may have been multiplied (in linear space) by the
   9664              * alpha value, 'compose' says whether this is relevant.
   9665              */
   9666             if (compose || pass != 0)
   9667             {
   9668                /* If any form of composition is being done report our
   9669                 * calculated linear value here (the code above doesn't record
   9670                 * the input value before composition is performed, so what
   9671                 * gets reported is the value after composition.)
   9672                 */
   9673                if (use_input || pass != 0)
   9674                {
   9675                   if (vi->file_inverse > 0)
   9676                   {
   9677                      pos = safecat(msg, sizeof msg, pos, "^");
   9678                      pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2);
   9679                   }
   9680 
   9681                   else
   9682                      pos = safecat(msg, sizeof msg, pos, "[linear]");
   9683 
   9684                   pos = safecat(msg, sizeof msg, pos, "*(alpha)");
   9685                   pos = safecatd(msg, sizeof msg, pos, alpha, precision);
   9686                }
   9687 
   9688                /* Now record the *linear* background value if it was used
   9689                 * (this function is not passed the original, non-linear,
   9690                 * value but it is contained in the test name.)
   9691                 */
   9692                if (use_background)
   9693                {
   9694                   pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " ");
   9695                   pos = safecat(msg, sizeof msg, pos, "(background)");
   9696                   pos = safecatd(msg, sizeof msg, pos, background, precision);
   9697                   pos = safecat(msg, sizeof msg, pos, "*");
   9698                   pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision);
   9699                }
   9700             }
   9701 
   9702             /* Report the calculated value (input_sample) and the linearized
   9703              * libpng value (output) unless this is just a component gamma
   9704              * correction.
   9705              */
   9706             if (compose || alpha < 0 || pass != 0)
   9707             {
   9708                pos = safecat(msg, sizeof msg, pos,
   9709                   pass != 0 ? " =\n\t" : " = ");
   9710                pos = safecatd(msg, sizeof msg, pos, input_sample, precision);
   9711                pos = safecat(msg, sizeof msg, pos, " (libpng: ");
   9712                pos = safecatd(msg, sizeof msg, pos, output, precision);
   9713                pos = safecat(msg, sizeof msg, pos, ")");
   9714 
   9715                /* Finally report the output gamma encoding, if any. */
   9716                if (output_is_encoded)
   9717                {
   9718                   pos = safecat(msg, sizeof msg, pos, " ^");
   9719                   pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2);
   9720                   pos = safecat(msg, sizeof msg, pos, "(to screen) =");
   9721                }
   9722 
   9723                else
   9724                   pos = safecat(msg, sizeof msg, pos, " [screen is linear] =");
   9725             }
   9726 
   9727             if ((!compose && alpha >= 0) || pass != 0)
   9728             {
   9729                if (pass != 0) /* logging */
   9730                   pos = safecat(msg, sizeof msg, pos, "\n\t[overall:");
   9731 
   9732                /* This is the non-composition case, the internal linear
   9733                 * values are irrelevant (though the log below will reveal
   9734                 * them.)  Output a much shorter warning/error message and report
   9735                 * the overall gamma correction.
   9736                 */
   9737                if (vi->gamma_correction > 0)
   9738                {
   9739                   pos = safecat(msg, sizeof msg, pos, " ^");
   9740                   pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2);
   9741                   pos = safecat(msg, sizeof msg, pos, "(gamma correction) =");
   9742                }
   9743 
   9744                else
   9745                   pos = safecat(msg, sizeof msg, pos,
   9746                      " [no gamma correction] =");
   9747 
   9748                if (pass != 0)
   9749                   pos = safecat(msg, sizeof msg, pos, "]");
   9750             }
   9751 
   9752             /* This is our calculated encoded_sample which should (but does
   9753              * not) match od:
   9754              */
   9755             pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " ");
   9756             pos = safecatd(msg, sizeof msg, pos, is_lo, 1);
   9757             pos = safecat(msg, sizeof msg, pos, " < ");
   9758             pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1);
   9759             pos = safecat(msg, sizeof msg, pos, " (libpng: ");
   9760             pos = safecatn(msg, sizeof msg, pos, od);
   9761             pos = safecat(msg, sizeof msg, pos, ")");
   9762             pos = safecat(msg, sizeof msg, pos, "/");
   9763             pos = safecatn(msg, sizeof msg, pos, outmax);
   9764             pos = safecat(msg, sizeof msg, pos, " < ");
   9765             pos = safecatd(msg, sizeof msg, pos, is_hi, 1);
   9766 
   9767             if (pass == 0) /* The error condition */
   9768             {
   9769 #              ifdef PNG_WARNINGS_SUPPORTED
   9770                   png_warning(vi->pp, msg);
   9771 #              else
   9772                   store_warning(vi->pp, msg);
   9773 #              endif
   9774             }
   9775 
   9776             else /* logging this value */
   9777                store_verbose(&vi->dp->pm->this, vi->pp, pass, msg);
   9778          }
   9779       }
   9780    }
   9781 
   9782    return i;
   9783 }
   9784 
   9785 static void
   9786 gamma_image_validate(gamma_display *dp, png_const_structp pp,
   9787    png_infop pi)
   9788 {
   9789    /* Get some constants derived from the input and output file formats: */
   9790    const png_store* const ps = dp->this.ps;
   9791    const png_byte in_ct = dp->this.colour_type;
   9792    const png_byte in_bd = dp->this.bit_depth;
   9793    const png_uint_32 w = dp->this.w;
   9794    const png_uint_32 h = dp->this.h;
   9795    const size_t cbRow = dp->this.cbRow;
   9796    const png_byte out_ct = png_get_color_type(pp, pi);
   9797    const png_byte out_bd = png_get_bit_depth(pp, pi);
   9798 
   9799    /* There are three sources of error, firstly the quantization in the
   9800     * file encoding, determined by sbit and/or the file depth, secondly
   9801     * the output (screen) gamma and thirdly the output file encoding.
   9802     *
   9803     * Since this API receives the screen and file gamma in double
   9804     * precision it is possible to calculate an exact answer given an input
   9805     * pixel value.  Therefore we assume that the *input* value is exact -
   9806     * sample/maxsample - calculate the corresponding gamma corrected
   9807     * output to the limits of double precision arithmetic and compare with
   9808     * what libpng returns.
   9809     *
   9810     * Since the library must quantize the output to 8 or 16 bits there is
   9811     * a fundamental limit on the accuracy of the output of +/-.5 - this
   9812     * quantization limit is included in addition to the other limits
   9813     * specified by the paramaters to the API.  (Effectively, add .5
   9814     * everywhere.)
   9815     *
   9816     * The behavior of the 'sbit' paramter is defined by section 12.5
   9817     * (sample depth scaling) of the PNG spec.  That section forces the
   9818     * decoder to assume that the PNG values have been scaled if sBIT is
   9819     * present:
   9820     *
   9821     *     png-sample = floor( input-sample * (max-out/max-in) + .5);
   9822     *
   9823     * This means that only a subset of the possible PNG values should
   9824     * appear in the input. However, the spec allows the encoder to use a
   9825     * variety of approximations to the above and doesn't require any
   9826     * restriction of the values produced.
   9827     *
   9828     * Nevertheless the spec requires that the upper 'sBIT' bits of the
   9829     * value stored in a PNG file be the original sample bits.
   9830     * Consequently the code below simply scales the top sbit bits by
   9831     * (1<<sbit)-1 to obtain an original sample value.
   9832     *
   9833     * Because there is limited precision in the input it is arguable that
   9834     * an acceptable result is any valid result from input-.5 to input+.5.
   9835     * The basic tests below do not do this, however if 'use_input_precision'
   9836     * is set a subsequent test is performed above.
   9837     */
   9838    const unsigned int samples_per_pixel = (out_ct & 2U) ? 3U : 1U;
   9839    int processing;
   9840    png_uint_32 y;
   9841    const store_palette_entry *in_palette = dp->this.palette;
   9842    const int in_is_transparent = dp->this.is_transparent;
   9843    int process_tRNS;
   9844    int out_npalette = -1;
   9845    int out_is_transparent = 0; /* Just refers to the palette case */
   9846    store_palette out_palette;
   9847    validate_info vi;
   9848 
   9849    /* Check for row overwrite errors */
   9850    store_image_check(dp->this.ps, pp, 0);
   9851 
   9852    /* Supply the input and output sample depths here - 8 for an indexed image,
   9853     * otherwise the bit depth.
   9854     */
   9855    init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd);
   9856 
   9857    processing = (vi.gamma_correction > 0 && !dp->threshold_test)
   9858       || in_bd != out_bd || in_ct != out_ct || vi.do_background;
   9859    process_tRNS = dp->this.has_tRNS && vi.do_background;
   9860 
   9861    /* TODO: FIX THIS: MAJOR BUG!  If the transformations all happen inside
   9862     * the palette there is no way of finding out, because libpng fails to
   9863     * update the palette on png_read_update_info.  Indeed, libpng doesn't
   9864     * even do the required work until much later, when it doesn't have any
   9865     * info pointer.  Oops.  For the moment 'processing' is turned off if
   9866     * out_ct is palette.
   9867     */
   9868    if (in_ct == 3 && out_ct == 3)
   9869       processing = 0;
   9870 
   9871    if (processing && out_ct == 3)
   9872       out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi);
   9873 
   9874    for (y=0; y<h; ++y)
   9875    {
   9876       png_const_bytep pRow = store_image_row(ps, pp, 0, y);
   9877       png_byte std[STANDARD_ROWMAX];
   9878 
   9879       transform_row(pp, std, in_ct, in_bd, y);
   9880 
   9881       if (processing)
   9882       {
   9883          unsigned int x;
   9884 
   9885          for (x=0; x<w; ++x)
   9886          {
   9887             double alpha = 1; /* serves as a flag value */
   9888 
   9889             /* Record the palette index for index images. */
   9890             const unsigned int in_index =
   9891                in_ct == 3 ? sample(std, 3, in_bd, x, 0, 0, 0) : 256;
   9892             const unsigned int out_index =
   9893                out_ct == 3 ? sample(std, 3, out_bd, x, 0, 0, 0) : 256;
   9894 
   9895             /* Handle input alpha - png_set_background will cause the output
   9896              * alpha to disappear so there is nothing to check.
   9897              */
   9898             if ((in_ct & PNG_COLOR_MASK_ALPHA) != 0 ||
   9899                 (in_ct == 3 && in_is_transparent))
   9900             {
   9901                const unsigned int input_alpha = in_ct == 3 ?
   9902                   dp->this.palette[in_index].alpha :
   9903                   sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0);
   9904 
   9905                unsigned int output_alpha = 65536 /* as a flag value */;
   9906 
   9907                if (out_ct == 3)
   9908                {
   9909                   if (out_is_transparent)
   9910                      output_alpha = out_palette[out_index].alpha;
   9911                }
   9912 
   9913                else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0)
   9914                   output_alpha = sample(pRow, out_ct, out_bd, x,
   9915                      samples_per_pixel, 0, 0);
   9916 
   9917                if (output_alpha != 65536)
   9918                   alpha = gamma_component_validate("alpha", &vi, input_alpha,
   9919                      output_alpha, -1/*alpha*/, 0/*background*/);
   9920 
   9921                else /* no alpha in output */
   9922                {
   9923                   /* This is a copy of the calculation of 'i' above in order to
   9924                    * have the alpha value to use in the background calculation.
   9925                    */
   9926                   alpha = input_alpha >> vi.isbit_shift;
   9927                   alpha /= vi.sbit_max;
   9928                }
   9929             }
   9930 
   9931             else if (process_tRNS)
   9932             {
   9933                /* alpha needs to be set appropriately for this pixel, it is
   9934                 * currently 1 and needs to be 0 for an input pixel which matches
   9935                 * the values in tRNS.
   9936                 */
   9937                switch (in_ct)
   9938                {
   9939                   case 0: /* gray */
   9940                      if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
   9941                            dp->this.transparent.red)
   9942                         alpha = 0;
   9943                      break;
   9944 
   9945                   case 2: /* RGB */
   9946                      if (sample(std, in_ct, in_bd, x, 0, 0, 0) ==
   9947                            dp->this.transparent.red &&
   9948                          sample(std, in_ct, in_bd, x, 1, 0, 0) ==
   9949                            dp->this.transparent.green &&
   9950                          sample(std, in_ct, in_bd, x, 2, 0, 0) ==
   9951                            dp->this.transparent.blue)
   9952                         alpha = 0;
   9953                      break;
   9954 
   9955                   default:
   9956                      break;
   9957                }
   9958             }
   9959 
   9960             /* Handle grayscale or RGB components. */
   9961             if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */
   9962                (void)gamma_component_validate("gray", &vi,
   9963                   sample(std, in_ct, in_bd, x, 0, 0, 0),
   9964                   sample(pRow, out_ct, out_bd, x, 0, 0, 0),
   9965                   alpha/*component*/, vi.background_red);
   9966             else /* RGB or palette */
   9967             {
   9968                (void)gamma_component_validate("red", &vi,
   9969                   in_ct == 3 ? in_palette[in_index].red :
   9970                      sample(std, in_ct, in_bd, x, 0, 0, 0),
   9971                   out_ct == 3 ? out_palette[out_index].red :
   9972                      sample(pRow, out_ct, out_bd, x, 0, 0, 0),
   9973                   alpha/*component*/, vi.background_red);
   9974 
   9975                (void)gamma_component_validate("green", &vi,
   9976                   in_ct == 3 ? in_palette[in_index].green :
   9977                      sample(std, in_ct, in_bd, x, 1, 0, 0),
   9978                   out_ct == 3 ? out_palette[out_index].green :
   9979                      sample(pRow, out_ct, out_bd, x, 1, 0, 0),
   9980                   alpha/*component*/, vi.background_green);
   9981 
   9982                (void)gamma_component_validate("blue", &vi,
   9983                   in_ct == 3 ? in_palette[in_index].blue :
   9984                      sample(std, in_ct, in_bd, x, 2, 0, 0),
   9985                   out_ct == 3 ? out_palette[out_index].blue :
   9986                      sample(pRow, out_ct, out_bd, x, 2, 0, 0),
   9987                   alpha/*component*/, vi.background_blue);
   9988             }
   9989          }
   9990       }
   9991 
   9992       else if (memcmp(std, pRow, cbRow) != 0)
   9993       {
   9994          char msg[64];
   9995 
   9996          /* No transform is expected on the threshold tests. */
   9997          sprintf(msg, "gamma: below threshold row %lu changed",
   9998             (unsigned long)y);
   9999 
   10000          png_error(pp, msg);
   10001       }
   10002    } /* row (y) loop */
   10003 
   10004    dp->this.ps->validated = 1;
   10005 }
   10006 
   10007 static void PNGCBAPI
   10008 gamma_end(png_structp ppIn, png_infop pi)
   10009 {
   10010    png_const_structp pp = ppIn;
   10011    gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp));
   10012 
   10013    if (!dp->this.speed)
   10014       gamma_image_validate(dp, pp, pi);
   10015    else
   10016       dp->this.ps->validated = 1;
   10017 }
   10018 
   10019 /* A single test run checking a gamma transformation.
   10020  *
   10021  * maxabs: maximum absolute error as a fraction
   10022  * maxout: maximum output error in the output units
   10023  * maxpc:  maximum percentage error (as a percentage)
   10024  */
   10025 static void
   10026 gamma_test(png_modifier *pmIn, const png_byte colour_typeIn,
   10027     const png_byte bit_depthIn, const int palette_numberIn,
   10028     const int interlace_typeIn,
   10029     const double file_gammaIn, const double screen_gammaIn,
   10030     const png_byte sbitIn, const int threshold_testIn,
   10031     const char *name,
   10032     const int use_input_precisionIn, const int scale16In,
   10033     const int expand16In, const int do_backgroundIn,
   10034     const png_color_16 *bkgd_colorIn, double bkgd_gammaIn)
   10035 {
   10036    gamma_display d;
   10037    context(&pmIn->this, fault);
   10038 
   10039    gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn,
   10040       palette_numberIn, interlace_typeIn, 0, 0, 0),
   10041       file_gammaIn, screen_gammaIn, sbitIn,
   10042       threshold_testIn, use_input_precisionIn, scale16In,
   10043       expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn);
   10044 
   10045    Try
   10046    {
   10047       png_structp pp;
   10048       png_infop pi;
   10049       gama_modification gama_mod;
   10050       srgb_modification srgb_mod;
   10051       sbit_modification sbit_mod;
   10052 
   10053       /* For the moment don't use the png_modifier support here. */
   10054       d.pm->encoding_counter = 0;
   10055       modifier_set_encoding(d.pm); /* Just resets everything */
   10056       d.pm->current_gamma = d.file_gamma;
   10057 
   10058       /* Make an appropriate modifier to set the PNG file gamma to the
   10059        * given gamma value and the sBIT chunk to the given precision.
   10060        */
   10061       d.pm->modifications = NULL;
   10062       gama_modification_init(&gama_mod, d.pm, d.file_gamma);
   10063       srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/);
   10064       if (d.sbit > 0)
   10065          sbit_modification_init(&sbit_mod, d.pm, d.sbit);
   10066 
   10067       modification_reset(d.pm->modifications);
   10068 
   10069       /* Get a png_struct for reading the image. */
   10070       pp = set_modifier_for_read(d.pm, &pi, d.this.id, name);
   10071       standard_palette_init(&d.this);
   10072 
   10073       /* Introduce the correct read function. */
   10074       if (d.pm->this.progressive)
   10075       {
   10076          /* Share the row function with the standard implementation. */
   10077          png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row,
   10078             gamma_end);
   10079 
   10080          /* Now feed data into the reader until we reach the end: */
   10081          modifier_progressive_read(d.pm, pp, pi);
   10082       }
   10083       else
   10084       {
   10085          /* modifier_read expects a png_modifier* */
   10086          png_set_read_fn(pp, d.pm, modifier_read);
   10087 
   10088          /* Check the header values: */
   10089          png_read_info(pp, pi);
   10090 
   10091          /* Process the 'info' requirements. Only one image is generated */
   10092          gamma_info_imp(&d, pp, pi);
   10093 
   10094          sequential_row(&d.this, pp, pi, -1, 0);
   10095 
   10096          if (!d.this.speed)
   10097             gamma_image_validate(&d, pp, pi);
   10098          else
   10099             d.this.ps->validated = 1;
   10100       }
   10101 
   10102       modifier_reset(d.pm);
   10103 
   10104       if (d.pm->log && !d.threshold_test && !d.this.speed)
   10105          fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n",
   10106             d.this.bit_depth, colour_types[d.this.colour_type], name,
   10107             d.maxerrout, d.maxerrabs, 100*d.maxerrpc);
   10108 
   10109       /* Log the summary values too. */
   10110       if (d.this.colour_type == 0 || d.this.colour_type == 4)
   10111       {
   10112          switch (d.this.bit_depth)
   10113          {
   10114          case 1:
   10115             break;
   10116 
   10117          case 2:
   10118             if (d.maxerrout > d.pm->error_gray_2)
   10119                d.pm->error_gray_2 = d.maxerrout;
   10120 
   10121             break;
   10122 
   10123          case 4:
   10124             if (d.maxerrout > d.pm->error_gray_4)
   10125                d.pm->error_gray_4 = d.maxerrout;
   10126 
   10127             break;
   10128 
   10129          case 8:
   10130             if (d.maxerrout > d.pm->error_gray_8)
   10131                d.pm->error_gray_8 = d.maxerrout;
   10132 
   10133             break;
   10134 
   10135          case 16:
   10136             if (d.maxerrout > d.pm->error_gray_16)
   10137                d.pm->error_gray_16 = d.maxerrout;
   10138 
   10139             break;
   10140 
   10141          default:
   10142             png_error(pp, "bad bit depth (internal: 1)");
   10143          }
   10144       }
   10145 
   10146       else if (d.this.colour_type == 2 || d.this.colour_type == 6)
   10147       {
   10148          switch (d.this.bit_depth)
   10149          {
   10150          case 8:
   10151 
   10152             if (d.maxerrout > d.pm->error_color_8)
   10153                d.pm->error_color_8 = d.maxerrout;
   10154 
   10155             break;
   10156 
   10157          case 16:
   10158 
   10159             if (d.maxerrout > d.pm->error_color_16)
   10160                d.pm->error_color_16 = d.maxerrout;
   10161 
   10162             break;
   10163 
   10164          default:
   10165             png_error(pp, "bad bit depth (internal: 2)");
   10166          }
   10167       }
   10168 
   10169       else if (d.this.colour_type == 3)
   10170       {
   10171          if (d.maxerrout > d.pm->error_indexed)
   10172             d.pm->error_indexed = d.maxerrout;
   10173       }
   10174    }
   10175 
   10176    Catch(fault)
   10177       modifier_reset(voidcast(png_modifier*,(void*)fault));
   10178 }
   10179 
   10180 static void gamma_threshold_test(png_modifier *pm, png_byte colour_type,
   10181     png_byte bit_depth, int interlace_type, double file_gamma,
   10182     double screen_gamma)
   10183 {
   10184    size_t pos = 0;
   10185    char name[64];
   10186    pos = safecat(name, sizeof name, pos, "threshold ");
   10187    pos = safecatd(name, sizeof name, pos, file_gamma, 3);
   10188    pos = safecat(name, sizeof name, pos, "/");
   10189    pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
   10190 
   10191    (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type,
   10192       file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name,
   10193       0 /*no input precision*/,
   10194       0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/,
   10195       0 /*no background gamma*/);
   10196 }
   10197 
   10198 static void
   10199 perform_gamma_threshold_tests(png_modifier *pm)
   10200 {
   10201    png_byte colour_type = 0;
   10202    png_byte bit_depth = 0;
   10203    unsigned int palette_number = 0;
   10204 
   10205    /* Don't test more than one instance of each palette - it's pointless, in
   10206     * fact this test is somewhat excessive since libpng doesn't make this
   10207     * decision based on colour type or bit depth!
   10208     *
   10209     * CHANGED: now test two palettes and, as a side effect, images with and
   10210     * without tRNS.
   10211     */
   10212    while (next_format(&colour_type, &bit_depth, &palette_number,
   10213                       pm->test_lbg_gamma_threshold, pm->test_tRNS))
   10214       if (palette_number < 2)
   10215    {
   10216       double test_gamma = 1.0;
   10217       while (test_gamma >= .4)
   10218       {
   10219          /* There's little point testing the interlacing vs non-interlacing,
   10220           * but this can be set from the command line.
   10221           */
   10222          gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
   10223             test_gamma, 1/test_gamma);
   10224          test_gamma *= .95;
   10225       }
   10226 
   10227       /* And a special test for sRGB */
   10228       gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type,
   10229           .45455, 2.2);
   10230 
   10231       if (fail(pm))
   10232          return;
   10233    }
   10234 }
   10235 
   10236 static void gamma_transform_test(png_modifier *pm,
   10237    const png_byte colour_type, const png_byte bit_depth,
   10238    const int palette_number,
   10239    const int interlace_type, const double file_gamma,
   10240    const double screen_gamma, const png_byte sbit,
   10241    const int use_input_precision, const int scale16)
   10242 {
   10243    size_t pos = 0;
   10244    char name[64];
   10245 
   10246    if (sbit != bit_depth && sbit != 0)
   10247    {
   10248       pos = safecat(name, sizeof name, pos, "sbit(");
   10249       pos = safecatn(name, sizeof name, pos, sbit);
   10250       pos = safecat(name, sizeof name, pos, ") ");
   10251    }
   10252 
   10253    else
   10254       pos = safecat(name, sizeof name, pos, "gamma ");
   10255 
   10256    if (scale16)
   10257       pos = safecat(name, sizeof name, pos, "16to8 ");
   10258 
   10259    pos = safecatd(name, sizeof name, pos, file_gamma, 3);
   10260    pos = safecat(name, sizeof name, pos, "->");
   10261    pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
   10262 
   10263    gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
   10264       file_gamma, screen_gamma, sbit, 0, name, use_input_precision,
   10265       scale16, pm->test_gamma_expand16, 0 , 0, 0);
   10266 }
   10267 
   10268 static void perform_gamma_transform_tests(png_modifier *pm)
   10269 {
   10270    png_byte colour_type = 0;
   10271    png_byte bit_depth = 0;
   10272    unsigned int palette_number = 0;
   10273 
   10274    while (next_format(&colour_type, &bit_depth, &palette_number,
   10275                       pm->test_lbg_gamma_transform, pm->test_tRNS))
   10276    {
   10277       unsigned int i, j;
   10278 
   10279       for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
   10280          if (i != j)
   10281          {
   10282             gamma_transform_test(pm, colour_type, bit_depth, palette_number,
   10283                pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/,
   10284                pm->use_input_precision, 0 /*do not scale16*/);
   10285 
   10286             if (fail(pm))
   10287                return;
   10288          }
   10289    }
   10290 }
   10291 
   10292 static void perform_gamma_sbit_tests(png_modifier *pm)
   10293 {
   10294    png_byte sbit;
   10295 
   10296    /* The only interesting cases are colour and grayscale, alpha is ignored here
   10297     * for overall speed.  Only bit depths where sbit is less than the bit depth
   10298     * are tested.
   10299     */
   10300    for (sbit=pm->sbitlow; sbit<(1<<READ_BDHI); ++sbit)
   10301    {
   10302       png_byte colour_type = 0, bit_depth = 0;
   10303       unsigned int npalette = 0;
   10304 
   10305       while (next_format(&colour_type, &bit_depth, &npalette,
   10306                          pm->test_lbg_gamma_sbit, pm->test_tRNS))
   10307          if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 &&
   10308             ((colour_type == 3 && sbit < 8) ||
   10309             (colour_type != 3 && sbit < bit_depth)))
   10310       {
   10311          unsigned int i;
   10312 
   10313          for (i=0; i<pm->ngamma_tests; ++i)
   10314          {
   10315             unsigned int j;
   10316 
   10317             for (j=0; j<pm->ngamma_tests; ++j) if (i != j)
   10318             {
   10319                gamma_transform_test(pm, colour_type, bit_depth, npalette,
   10320                   pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
   10321                   sbit, pm->use_input_precision_sbit, 0 /*scale16*/);
   10322 
   10323                if (fail(pm))
   10324                   return;
   10325             }
   10326          }
   10327       }
   10328    }
   10329 }
   10330 
   10331 /* Note that this requires a 16 bit source image but produces 8 bit output, so
   10332  * we only need the 16bit write support, but the 16 bit images are only
   10333  * generated if DO_16BIT is defined.
   10334  */
   10335 #ifdef DO_16BIT
   10336 static void perform_gamma_scale16_tests(png_modifier *pm)
   10337 {
   10338 #  ifndef PNG_MAX_GAMMA_8
   10339 #     define PNG_MAX_GAMMA_8 11
   10340 #  endif
   10341 #  if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700
   10342 #     define SBIT_16_TO_8 PNG_MAX_GAMMA_8
   10343 #  else
   10344 #     define SBIT_16_TO_8 16
   10345 #  endif
   10346    /* Include the alpha cases here. Note that sbit matches the internal value
   10347     * used by the library - otherwise we will get spurious errors from the
   10348     * internal sbit style approximation.
   10349     *
   10350     * The threshold test is here because otherwise the 16 to 8 conversion will
   10351     * proceed *without* gamma correction, and the tests above will fail (but not
   10352     * by much) - this could be fixed, it only appears with the -g option.
   10353     */
   10354    unsigned int i, j;
   10355    for (i=0; i<pm->ngamma_tests; ++i)
   10356    {
   10357       for (j=0; j<pm->ngamma_tests; ++j)
   10358       {
   10359          if (i != j &&
   10360              fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD)
   10361          {
   10362             gamma_transform_test(pm, 0, 16, 0, pm->interlace_type,
   10363                1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
   10364                pm->use_input_precision_16to8, 1 /*scale16*/);
   10365 
   10366             if (fail(pm))
   10367                return;
   10368 
   10369             gamma_transform_test(pm, 2, 16, 0, pm->interlace_type,
   10370                1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
   10371                pm->use_input_precision_16to8, 1 /*scale16*/);
   10372 
   10373             if (fail(pm))
   10374                return;
   10375 
   10376             gamma_transform_test(pm, 4, 16, 0, pm->interlace_type,
   10377                1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
   10378                pm->use_input_precision_16to8, 1 /*scale16*/);
   10379 
   10380             if (fail(pm))
   10381                return;
   10382 
   10383             gamma_transform_test(pm, 6, 16, 0, pm->interlace_type,
   10384                1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8,
   10385                pm->use_input_precision_16to8, 1 /*scale16*/);
   10386 
   10387             if (fail(pm))
   10388                return;
   10389          }
   10390       }
   10391    }
   10392 }
   10393 #endif /* 16 to 8 bit conversion */
   10394 
   10395 #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
   10396    defined(PNG_READ_ALPHA_MODE_SUPPORTED)
   10397 static void gamma_composition_test(png_modifier *pm,
   10398    const png_byte colour_type, const png_byte bit_depth,
   10399    const int palette_number,
   10400    const int interlace_type, const double file_gamma,
   10401    const double screen_gamma,
   10402    const int use_input_precision, const int do_background,
   10403    const int expand_16)
   10404 {
   10405    size_t pos = 0;
   10406    png_const_charp base;
   10407    double bg;
   10408    char name[128];
   10409    png_color_16 background;
   10410 
   10411    /* Make up a name and get an appropriate background gamma value. */
   10412    switch (do_background)
   10413    {
   10414       default:
   10415          base = "";
   10416          bg = 4; /* should not be used */
   10417          break;
   10418       case PNG_BACKGROUND_GAMMA_SCREEN:
   10419          base = " bckg(Screen):";
   10420          bg = 1/screen_gamma;
   10421          break;
   10422       case PNG_BACKGROUND_GAMMA_FILE:
   10423          base = " bckg(File):";
   10424          bg = file_gamma;
   10425          break;
   10426       case PNG_BACKGROUND_GAMMA_UNIQUE:
   10427          base = " bckg(Unique):";
   10428          /* This tests the handling of a unique value, the math is such that the
   10429           * value tends to be <1, but is neither screen nor file (even if they
   10430           * match!)
   10431           */
   10432          bg = (file_gamma + screen_gamma) / 3;
   10433          break;
   10434 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   10435       case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG:
   10436          base = " alpha(PNG)";
   10437          bg = 4; /* should not be used */
   10438          break;
   10439       case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD:
   10440          base = " alpha(Porter-Duff)";
   10441          bg = 4; /* should not be used */
   10442          break;
   10443       case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED:
   10444          base = " alpha(Optimized)";
   10445          bg = 4; /* should not be used */
   10446          break;
   10447       case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN:
   10448          base = " alpha(Broken)";
   10449          bg = 4; /* should not be used */
   10450          break;
   10451 #endif
   10452    }
   10453 
   10454    /* Use random background values - the background is always presented in the
   10455     * output space (8 or 16 bit components).
   10456     */
   10457    if (expand_16 || bit_depth == 16)
   10458    {
   10459       png_uint_32 r = random_32();
   10460 
   10461       background.red = (png_uint_16)r;
   10462       background.green = (png_uint_16)(r >> 16);
   10463       r = random_32();
   10464       background.blue = (png_uint_16)r;
   10465       background.gray = (png_uint_16)(r >> 16);
   10466 
   10467       /* In earlier libpng versions, those where DIGITIZE is set, any background
   10468        * gamma correction in the expand16 case was done using 8-bit gamma
   10469        * correction tables, resulting in larger errors.  To cope with those
   10470        * cases use a 16-bit background value which will handle this gamma
   10471        * correction.
   10472        */
   10473 #     if DIGITIZE
   10474          if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE ||
   10475                            do_background == PNG_BACKGROUND_GAMMA_FILE) &&
   10476             fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD)
   10477          {
   10478             /* The background values will be looked up in an 8-bit table to do
   10479              * the gamma correction, so only select values which are an exact
   10480              * match for the 8-bit table entries:
   10481              */
   10482             background.red = (png_uint_16)((background.red >> 8) * 257);
   10483             background.green = (png_uint_16)((background.green >> 8) * 257);
   10484             background.blue = (png_uint_16)((background.blue >> 8) * 257);
   10485             background.gray = (png_uint_16)((background.gray >> 8) * 257);
   10486          }
   10487 #     endif
   10488    }
   10489 
   10490    else /* 8 bit colors */
   10491    {
   10492       png_uint_32 r = random_32();
   10493 
   10494       background.red = (png_byte)r;
   10495       background.green = (png_byte)(r >> 8);
   10496       background.blue = (png_byte)(r >> 16);
   10497       background.gray = (png_byte)(r >> 24);
   10498    }
   10499 
   10500    background.index = 193; /* rgb(193,193,193) to detect errors */
   10501 
   10502    if (!(colour_type & PNG_COLOR_MASK_COLOR))
   10503    {
   10504       /* Because, currently, png_set_background is always called with
   10505        * 'need_expand' false in this case and because the gamma test itself
   10506        * doesn't cause an expand to 8-bit for lower bit depths the colour must
   10507        * be reduced to the correct range.
   10508        */
   10509       if (bit_depth < 8)
   10510          background.gray &= (png_uint_16)((1U << bit_depth)-1);
   10511 
   10512       /* Grayscale input, we do not convert to RGB (TBD), so we must set the
   10513        * background to gray - else libpng seems to fail.
   10514        */
   10515       background.red = background.green = background.blue = background.gray;
   10516    }
   10517 
   10518    pos = safecat(name, sizeof name, pos, "gamma ");
   10519    pos = safecatd(name, sizeof name, pos, file_gamma, 3);
   10520    pos = safecat(name, sizeof name, pos, "->");
   10521    pos = safecatd(name, sizeof name, pos, screen_gamma, 3);
   10522 
   10523    pos = safecat(name, sizeof name, pos, base);
   10524    if (do_background < ALPHA_MODE_OFFSET)
   10525    {
   10526       /* Include the background color and gamma in the name: */
   10527       pos = safecat(name, sizeof name, pos, "(");
   10528       /* This assumes no expand gray->rgb - the current code won't handle that!
   10529        */
   10530       if (colour_type & PNG_COLOR_MASK_COLOR)
   10531       {
   10532          pos = safecatn(name, sizeof name, pos, background.red);
   10533          pos = safecat(name, sizeof name, pos, ",");
   10534          pos = safecatn(name, sizeof name, pos, background.green);
   10535          pos = safecat(name, sizeof name, pos, ",");
   10536          pos = safecatn(name, sizeof name, pos, background.blue);
   10537       }
   10538       else
   10539          pos = safecatn(name, sizeof name, pos, background.gray);
   10540       pos = safecat(name, sizeof name, pos, ")^");
   10541       pos = safecatd(name, sizeof name, pos, bg, 3);
   10542    }
   10543 
   10544    gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type,
   10545       file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision,
   10546       0/*strip 16*/, expand_16, do_background, &background, bg);
   10547 }
   10548 
   10549 
   10550 static void
   10551 perform_gamma_composition_tests(png_modifier *pm, int do_background,
   10552    int expand_16)
   10553 {
   10554    png_byte colour_type = 0;
   10555    png_byte bit_depth = 0;
   10556    unsigned int palette_number = 0;
   10557 
   10558    /* Skip the non-alpha cases - there is no setting of a transparency colour at
   10559     * present.
   10560     *
   10561     * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do,
   10562     * however the palette case fails miserably so is commented out below.
   10563     */
   10564    while (next_format(&colour_type, &bit_depth, &palette_number,
   10565                       pm->test_lbg_gamma_composition, pm->test_tRNS))
   10566       if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0
   10567 #if 0 /* TODO: FIXME */
   10568           /*TODO: FIXME: this should work */
   10569           || colour_type == 3
   10570 #endif
   10571           || (colour_type != 3 && palette_number != 0))
   10572    {
   10573       unsigned int i, j;
   10574 
   10575       /* Don't skip the i==j case here - it's relevant. */
   10576       for (i=0; i<pm->ngamma_tests; ++i) for (j=0; j<pm->ngamma_tests; ++j)
   10577       {
   10578          gamma_composition_test(pm, colour_type, bit_depth, palette_number,
   10579             pm->interlace_type, 1/pm->gammas[i], pm->gammas[j],
   10580             pm->use_input_precision, do_background, expand_16);
   10581 
   10582          if (fail(pm))
   10583             return;
   10584       }
   10585    }
   10586 }
   10587 #endif /* READ_BACKGROUND || READ_ALPHA_MODE */
   10588 
   10589 static void
   10590 init_gamma_errors(png_modifier *pm)
   10591 {
   10592    /* Use -1 to catch tests that were not actually run */
   10593    pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.;
   10594    pm->error_color_8 = -1.;
   10595    pm->error_indexed = -1.;
   10596    pm->error_gray_16 = pm->error_color_16 = -1.;
   10597 }
   10598 
   10599 static void
   10600 print_one(const char *leader, double err)
   10601 {
   10602    if (err != -1.)
   10603       printf(" %s %.5f\n", leader, err);
   10604 }
   10605 
   10606 static void
   10607 summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth,
   10608    int indexed)
   10609 {
   10610    fflush(stderr);
   10611 
   10612    if (who)
   10613       printf("\nGamma correction with %s:\n", who);
   10614 
   10615    else
   10616       printf("\nBasic gamma correction:\n");
   10617 
   10618    if (low_bit_depth)
   10619    {
   10620       print_one(" 2 bit gray: ", pm->error_gray_2);
   10621       print_one(" 4 bit gray: ", pm->error_gray_4);
   10622       print_one(" 8 bit gray: ", pm->error_gray_8);
   10623       print_one(" 8 bit color:", pm->error_color_8);
   10624       if (indexed)
   10625          print_one(" indexed:    ", pm->error_indexed);
   10626    }
   10627 
   10628    print_one("16 bit gray: ", pm->error_gray_16);
   10629    print_one("16 bit color:", pm->error_color_16);
   10630 
   10631    fflush(stdout);
   10632 }
   10633 
   10634 static void
   10635 perform_gamma_test(png_modifier *pm, int summary)
   10636 {
   10637    /*TODO: remove this*/
   10638    /* Save certain values for the temporary overrides below. */
   10639    unsigned int calculations_use_input_precision =
   10640       pm->calculations_use_input_precision;
   10641 #  ifdef PNG_READ_BACKGROUND_SUPPORTED
   10642       double maxout8 = pm->maxout8;
   10643 #  endif
   10644 
   10645    /* First some arbitrary no-transform tests: */
   10646    if (!pm->this.speed && pm->test_gamma_threshold)
   10647    {
   10648       perform_gamma_threshold_tests(pm);
   10649 
   10650       if (fail(pm))
   10651          return;
   10652    }
   10653 
   10654    /* Now some real transforms. */
   10655    if (pm->test_gamma_transform)
   10656    {
   10657       if (summary)
   10658       {
   10659          fflush(stderr);
   10660          printf("Gamma correction error summary\n\n");
   10661          printf("The printed value is the maximum error in the pixel values\n");
   10662          printf("calculated by the libpng gamma correction code.  The error\n");
   10663          printf("is calculated as the difference between the output pixel\n");
   10664          printf("value (always an integer) and the ideal value from the\n");
   10665          printf("libpng specification (typically not an integer).\n\n");
   10666 
   10667          printf("Expect this value to be less than .5 for 8 bit formats,\n");
   10668          printf("less than 1 for formats with fewer than 8 bits and a small\n");
   10669          printf("number (typically less than 5) for the 16 bit formats.\n");
   10670          printf("For performance reasons the value for 16 bit formats\n");
   10671          printf("increases when the image file includes an sBIT chunk.\n");
   10672          fflush(stdout);
   10673       }
   10674 
   10675       init_gamma_errors(pm);
   10676       /*TODO: remove this.  Necessary because the current libpng
   10677        * implementation works in 8 bits:
   10678        */
   10679       if (pm->test_gamma_expand16)
   10680          pm->calculations_use_input_precision = 1;
   10681       perform_gamma_transform_tests(pm);
   10682       if (!calculations_use_input_precision)
   10683          pm->calculations_use_input_precision = 0;
   10684 
   10685       if (summary)
   10686          summarize_gamma_errors(pm, 0/*who*/, 1/*low bit depth*/, 1/*indexed*/);
   10687 
   10688       if (fail(pm))
   10689          return;
   10690    }
   10691 
   10692    /* The sbit tests produce much larger errors: */
   10693    if (pm->test_gamma_sbit)
   10694    {
   10695       init_gamma_errors(pm);
   10696       perform_gamma_sbit_tests(pm);
   10697 
   10698       if (summary)
   10699          summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/);
   10700 
   10701       if (fail(pm))
   10702          return;
   10703    }
   10704 
   10705 #ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */
   10706    if (pm->test_gamma_scale16)
   10707    {
   10708       /* The 16 to 8 bit strip operations: */
   10709       init_gamma_errors(pm);
   10710       perform_gamma_scale16_tests(pm);
   10711 
   10712       if (summary)
   10713       {
   10714          fflush(stderr);
   10715          printf("\nGamma correction with 16 to 8 bit reduction:\n");
   10716          printf(" 16 bit gray:  %.5f\n", pm->error_gray_16);
   10717          printf(" 16 bit color: %.5f\n", pm->error_color_16);
   10718          fflush(stdout);
   10719       }
   10720 
   10721       if (fail(pm))
   10722          return;
   10723    }
   10724 #endif
   10725 
   10726 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   10727    if (pm->test_gamma_background)
   10728    {
   10729       init_gamma_errors(pm);
   10730 
   10731       /*TODO: remove this.  Necessary because the current libpng
   10732        * implementation works in 8 bits:
   10733        */
   10734       if (pm->test_gamma_expand16)
   10735       {
   10736          pm->calculations_use_input_precision = 1;
   10737          pm->maxout8 = .499; /* because the 16 bit background is smashed */
   10738       }
   10739       perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE,
   10740          pm->test_gamma_expand16);
   10741       if (!calculations_use_input_precision)
   10742          pm->calculations_use_input_precision = 0;
   10743       pm->maxout8 = maxout8;
   10744 
   10745       if (summary)
   10746          summarize_gamma_errors(pm, "background", 1, 0/*indexed*/);
   10747 
   10748       if (fail(pm))
   10749          return;
   10750    }
   10751 #endif
   10752 
   10753 #ifdef PNG_READ_ALPHA_MODE_SUPPORTED
   10754    if (pm->test_gamma_alpha_mode)
   10755    {
   10756       int do_background;
   10757 
   10758       init_gamma_errors(pm);
   10759 
   10760       /*TODO: remove this.  Necessary because the current libpng
   10761        * implementation works in 8 bits:
   10762        */
   10763       if (pm->test_gamma_expand16)
   10764          pm->calculations_use_input_precision = 1;
   10765       for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD;
   10766          do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm);
   10767          ++do_background)
   10768          perform_gamma_composition_tests(pm, do_background,
   10769             pm->test_gamma_expand16);
   10770       if (!calculations_use_input_precision)
   10771          pm->calculations_use_input_precision = 0;
   10772 
   10773       if (summary)
   10774          summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/);
   10775 
   10776       if (fail(pm))
   10777          return;
   10778    }
   10779 #endif
   10780 }
   10781 #endif /* PNG_READ_GAMMA_SUPPORTED */
   10782 #endif /* PNG_READ_SUPPORTED */
   10783 
   10784 /* INTERLACE MACRO VALIDATION */
   10785 /* This is copied verbatim from the specification, it is simply the pass
   10786  * number in which each pixel in each 8x8 tile appears.  The array must
   10787  * be indexed adam7[y][x] and notice that the pass numbers are based at
   10788  * 1, not 0 - the base libpng uses.
   10789  */
   10790 static const
   10791 png_byte adam7[8][8] =
   10792 {
   10793    { 1,6,4,6,2,6,4,6 },
   10794    { 7,7,7,7,7,7,7,7 },
   10795    { 5,6,5,6,5,6,5,6 },
   10796    { 7,7,7,7,7,7,7,7 },
   10797    { 3,6,4,6,3,6,4,6 },
   10798    { 7,7,7,7,7,7,7,7 },
   10799    { 5,6,5,6,5,6,5,6 },
   10800    { 7,7,7,7,7,7,7,7 }
   10801 };
   10802 
   10803 /* This routine validates all the interlace support macros in png.h for
   10804  * a variety of valid PNG widths and heights.  It uses a number of similarly
   10805  * named internal routines that feed off the above array.
   10806  */
   10807 static png_uint_32
   10808 png_pass_start_row(int pass)
   10809 {
   10810    int x, y;
   10811    ++pass;
   10812    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
   10813       return y;
   10814    return 0xf;
   10815 }
   10816 
   10817 static png_uint_32
   10818 png_pass_start_col(int pass)
   10819 {
   10820    int x, y;
   10821    ++pass;
   10822    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
   10823       return x;
   10824    return 0xf;
   10825 }
   10826 
   10827 static int
   10828 png_pass_row_shift(int pass)
   10829 {
   10830    int x, y, base=(-1), inc=8;
   10831    ++pass;
   10832    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
   10833    {
   10834       if (base == (-1))
   10835          base = y;
   10836       else if (base == y)
   10837          {}
   10838       else if (inc == y-base)
   10839          base=y;
   10840       else if (inc == 8)
   10841          inc = y-base, base=y;
   10842       else if (inc != y-base)
   10843          return 0xff; /* error - more than one 'inc' value! */
   10844    }
   10845 
   10846    if (base == (-1)) return 0xfe; /* error - no row in pass! */
   10847 
   10848    /* The shift is always 1, 2 or 3 - no pass has all the rows! */
   10849    switch (inc)
   10850    {
   10851 case 2: return 1;
   10852 case 4: return 2;
   10853 case 8: return 3;
   10854 default: break;
   10855    }
   10856 
   10857    /* error - unrecognized 'inc' */
   10858    return (inc << 8) + 0xfd;
   10859 }
   10860 
   10861 static int
   10862 png_pass_col_shift(int pass)
   10863 {
   10864    int x, y, base=(-1), inc=8;
   10865    ++pass;
   10866    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
   10867    {
   10868       if (base == (-1))
   10869          base = x;
   10870       else if (base == x)
   10871          {}
   10872       else if (inc == x-base)
   10873          base=x;
   10874       else if (inc == 8)
   10875          inc = x-base, base=x;
   10876       else if (inc != x-base)
   10877          return 0xff; /* error - more than one 'inc' value! */
   10878    }
   10879 
   10880    if (base == (-1)) return 0xfe; /* error - no row in pass! */
   10881 
   10882    /* The shift is always 1, 2 or 3 - no pass has all the rows! */
   10883    switch (inc)
   10884    {
   10885 case 1: return 0; /* pass 7 has all the columns */
   10886 case 2: return 1;
   10887 case 4: return 2;
   10888 case 8: return 3;
   10889 default: break;
   10890    }
   10891 
   10892    /* error - unrecognized 'inc' */
   10893    return (inc << 8) + 0xfd;
   10894 }
   10895 
   10896 static png_uint_32
   10897 png_row_from_pass_row(png_uint_32 yIn, int pass)
   10898 {
   10899    /* By examination of the array: */
   10900    switch (pass)
   10901    {
   10902 case 0: return yIn * 8;
   10903 case 1: return yIn * 8;
   10904 case 2: return yIn * 8 + 4;
   10905 case 3: return yIn * 4;
   10906 case 4: return yIn * 4 + 2;
   10907 case 5: return yIn * 2;
   10908 case 6: return yIn * 2 + 1;
   10909 default: break;
   10910    }
   10911 
   10912    return 0xff; /* bad pass number */
   10913 }
   10914 
   10915 static png_uint_32
   10916 png_col_from_pass_col(png_uint_32 xIn, int pass)
   10917 {
   10918    /* By examination of the array: */
   10919    switch (pass)
   10920    {
   10921 case 0: return xIn * 8;
   10922 case 1: return xIn * 8 + 4;
   10923 case 2: return xIn * 4;
   10924 case 3: return xIn * 4 + 2;
   10925 case 4: return xIn * 2;
   10926 case 5: return xIn * 2 + 1;
   10927 case 6: return xIn;
   10928 default: break;
   10929    }
   10930 
   10931    return 0xff; /* bad pass number */
   10932 }
   10933 
   10934 static int
   10935 png_row_in_interlace_pass(png_uint_32 y, int pass)
   10936 {
   10937    /* Is row 'y' in pass 'pass'? */
   10938    int x;
   10939    y &= 7;
   10940    ++pass;
   10941    for (x=0; x<8; ++x) if (adam7[y][x] == pass)
   10942       return 1;
   10943 
   10944    return 0;
   10945 }
   10946 
   10947 static int
   10948 png_col_in_interlace_pass(png_uint_32 x, int pass)
   10949 {
   10950    /* Is column 'x' in pass 'pass'? */
   10951    int y;
   10952    x &= 7;
   10953    ++pass;
   10954    for (y=0; y<8; ++y) if (adam7[y][x] == pass)
   10955       return 1;
   10956 
   10957    return 0;
   10958 }
   10959 
   10960 static png_uint_32
   10961 png_pass_rows(png_uint_32 height, int pass)
   10962 {
   10963    png_uint_32 tiles = height>>3;
   10964    png_uint_32 rows = 0;
   10965    unsigned int x, y;
   10966 
   10967    height &= 7;
   10968    ++pass;
   10969    for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass)
   10970    {
   10971       rows += tiles;
   10972       if (y < height) ++rows;
   10973       break; /* i.e. break the 'x', column, loop. */
   10974    }
   10975 
   10976    return rows;
   10977 }
   10978 
   10979 static png_uint_32
   10980 png_pass_cols(png_uint_32 width, int pass)
   10981 {
   10982    png_uint_32 tiles = width>>3;
   10983    png_uint_32 cols = 0;
   10984    unsigned int x, y;
   10985 
   10986    width &= 7;
   10987    ++pass;
   10988    for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass)
   10989    {
   10990       cols += tiles;
   10991       if (x < width) ++cols;
   10992       break; /* i.e. break the 'y', row, loop. */
   10993    }
   10994 
   10995    return cols;
   10996 }
   10997 
   10998 static void
   10999 perform_interlace_macro_validation(void)
   11000 {
   11001    /* The macros to validate, first those that depend only on pass:
   11002     *
   11003     * PNG_PASS_START_ROW(pass)
   11004     * PNG_PASS_START_COL(pass)
   11005     * PNG_PASS_ROW_SHIFT(pass)
   11006     * PNG_PASS_COL_SHIFT(pass)
   11007     */
   11008    int pass;
   11009 
   11010    for (pass=0; pass<7; ++pass)
   11011    {
   11012       png_uint_32 m, f, v;
   11013 
   11014       m = PNG_PASS_START_ROW(pass);
   11015       f = png_pass_start_row(pass);
   11016       if (m != f)
   11017       {
   11018          fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f);
   11019          exit(99);
   11020       }
   11021 
   11022       m = PNG_PASS_START_COL(pass);
   11023       f = png_pass_start_col(pass);
   11024       if (m != f)
   11025       {
   11026          fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f);
   11027          exit(99);
   11028       }
   11029 
   11030       m = PNG_PASS_ROW_SHIFT(pass);
   11031       f = png_pass_row_shift(pass);
   11032       if (m != f)
   11033       {
   11034          fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f);
   11035          exit(99);
   11036       }
   11037 
   11038       m = PNG_PASS_COL_SHIFT(pass);
   11039       f = png_pass_col_shift(pass);
   11040       if (m != f)
   11041       {
   11042          fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f);
   11043          exit(99);
   11044       }
   11045 
   11046       /* Macros that depend on the image or sub-image height too:
   11047        *
   11048        * PNG_PASS_ROWS(height, pass)
   11049        * PNG_PASS_COLS(width, pass)
   11050        * PNG_ROW_FROM_PASS_ROW(yIn, pass)
   11051        * PNG_COL_FROM_PASS_COL(xIn, pass)
   11052        * PNG_ROW_IN_INTERLACE_PASS(y, pass)
   11053        * PNG_COL_IN_INTERLACE_PASS(x, pass)
   11054        */
   11055       for (v=0;;)
   11056       {
   11057          /* First the base 0 stuff: */
   11058          m = PNG_ROW_FROM_PASS_ROW(v, pass);
   11059          f = png_row_from_pass_row(v, pass);
   11060          if (m != f)
   11061          {
   11062             fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n",
   11063                v, pass, m, f);
   11064             exit(99);
   11065          }
   11066 
   11067          m = PNG_COL_FROM_PASS_COL(v, pass);
   11068          f = png_col_from_pass_col(v, pass);
   11069          if (m != f)
   11070          {
   11071             fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n",
   11072                v, pass, m, f);
   11073             exit(99);
   11074          }
   11075 
   11076          m = PNG_ROW_IN_INTERLACE_PASS(v, pass);
   11077          f = png_row_in_interlace_pass(v, pass);
   11078          if (m != f)
   11079          {
   11080             fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
   11081                v, pass, m, f);
   11082             exit(99);
   11083          }
   11084 
   11085          m = PNG_COL_IN_INTERLACE_PASS(v, pass);
   11086          f = png_col_in_interlace_pass(v, pass);
   11087          if (m != f)
   11088          {
   11089             fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n",
   11090                v, pass, m, f);
   11091             exit(99);
   11092          }
   11093 
   11094          /* Then the base 1 stuff: */
   11095          ++v;
   11096          m = PNG_PASS_ROWS(v, pass);
   11097          f = png_pass_rows(v, pass);
   11098          if (m != f)
   11099          {
   11100             fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n",
   11101                v, pass, m, f);
   11102             exit(99);
   11103          }
   11104 
   11105          m = PNG_PASS_COLS(v, pass);
   11106          f = png_pass_cols(v, pass);
   11107          if (m != f)
   11108          {
   11109             fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n",
   11110                v, pass, m, f);
   11111             exit(99);
   11112          }
   11113 
   11114          /* Move to the next v - the stepping algorithm starts skipping
   11115           * values above 1024.
   11116           */
   11117          if (v > 1024)
   11118          {
   11119             if (v == PNG_UINT_31_MAX)
   11120                break;
   11121 
   11122             v = (v << 1) ^ v;
   11123             if (v >= PNG_UINT_31_MAX)
   11124                v = PNG_UINT_31_MAX-1;
   11125          }
   11126       }
   11127    }
   11128 }
   11129 
   11130 /* Test color encodings. These values are back-calculated from the published
   11131  * chromaticities.  The values are accurate to about 14 decimal places; 15 are
   11132  * given.  These values are much more accurate than the ones given in the spec,
   11133  * which typically don't exceed 4 decimal places.  This allows testing of the
   11134  * libpng code to its theoretical accuracy of 4 decimal places.  (If pngvalid
   11135  * used the published errors the 'slack' permitted would have to be +/-.5E-4 or
   11136  * more.)
   11137  *
   11138  * The png_modifier code assumes that encodings[0] is sRGB and treats it
   11139  * specially: do not change the first entry in this list!
   11140  */
   11141 static const color_encoding test_encodings[] =
   11142 {
   11143 /* sRGB: must be first in this list! */
   11144 /*gamma:*/ { 1/2.2,
   11145 /*red:  */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 },
   11146 /*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 },
   11147 /*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} },
   11148 /* Kodak ProPhoto (wide gamut) */
   11149 /*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/,
   11150 /*red:  */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 },
   11151 /*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 },
   11152 /*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} },
   11153 /* Adobe RGB (1998) */
   11154 /*gamma:*/ { 1/(2+51./256),
   11155 /*red:  */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 },
   11156 /*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 },
   11157 /*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} },
   11158 /* Adobe Wide Gamut RGB */
   11159 /*gamma:*/ { 1/(2+51./256),
   11160 /*red:  */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 },
   11161 /*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 },
   11162 /*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} },
   11163 /* Fake encoding which selects just the green channel */
   11164 /*gamma:*/ { 1.45/2.2, /* the 'Mac' gamma */
   11165 /*red:  */ { 0.716500716779386, 0.000000000000000, 0.000000000000000 },
   11166 /*green:*/ { 0.101020574397477, 1.000000000000000, 0.051211818965388 },
   11167 /*blue: */ { 0.146774385252705, 0.000000000000000, 0.773892783545073} },
   11168 };
   11169 
   11170 /* signal handler
   11171  *
   11172  * This attempts to trap signals and escape without crashing.  It needs a
   11173  * context pointer so that it can throw an exception (call longjmp) to recover
   11174  * from the condition; this is handled by making the png_modifier used by 'main'
   11175  * into a global variable.
   11176  */
   11177 static png_modifier pm;
   11178 
   11179 static void signal_handler(int signum)
   11180 {
   11181 
   11182    size_t pos = 0;
   11183    char msg[64];
   11184 
   11185    pos = safecat(msg, sizeof msg, pos, "caught signal: ");
   11186 
   11187    switch (signum)
   11188    {
   11189       case SIGABRT:
   11190          pos = safecat(msg, sizeof msg, pos, "abort");
   11191          break;
   11192 
   11193       case SIGFPE:
   11194          pos = safecat(msg, sizeof msg, pos, "floating point exception");
   11195          break;
   11196 
   11197       case SIGILL:
   11198          pos = safecat(msg, sizeof msg, pos, "illegal instruction");
   11199          break;
   11200 
   11201       case SIGINT:
   11202          pos = safecat(msg, sizeof msg, pos, "interrupt");
   11203          break;
   11204 
   11205       case SIGSEGV:
   11206          pos = safecat(msg, sizeof msg, pos, "invalid memory access");
   11207          break;
   11208 
   11209       case SIGTERM:
   11210          pos = safecat(msg, sizeof msg, pos, "termination request");
   11211          break;
   11212 
   11213       default:
   11214          pos = safecat(msg, sizeof msg, pos, "unknown ");
   11215          pos = safecatn(msg, sizeof msg, pos, signum);
   11216          break;
   11217    }
   11218 
   11219    store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/);
   11220 
   11221    /* And finally throw an exception so we can keep going, unless this is
   11222     * SIGTERM in which case stop now.
   11223     */
   11224    if (signum != SIGTERM)
   11225    {
   11226       struct exception_context *the_exception_context =
   11227          &pm.this.exception_context;
   11228 
   11229       Throw &pm.this;
   11230    }
   11231 
   11232    else
   11233       exit(1);
   11234 }
   11235 
   11236 /* main program */
   11237 int main(int argc, char **argv)
   11238 {
   11239    int summary = 1;  /* Print the error summary at the end */
   11240    int memstats = 0; /* Print memory statistics at the end */
   11241 
   11242    /* Create the given output file on success: */
   11243    const char *touch = NULL;
   11244 
   11245    /* This is an array of standard gamma values (believe it or not I've seen
   11246     * every one of these mentioned somewhere.)
   11247     *
   11248     * In the following list the most useful values are first!
   11249     */
   11250    static double
   11251       gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9};
   11252 
   11253    /* This records the command and arguments: */
   11254    size_t cp = 0;
   11255    char command[1024];
   11256 
   11257    anon_context(&pm.this);
   11258 
   11259    gnu_volatile(summary)
   11260    gnu_volatile(memstats)
   11261    gnu_volatile(touch)
   11262 
   11263    /* Add appropriate signal handlers, just the ANSI specified ones: */
   11264    signal(SIGABRT, signal_handler);
   11265    signal(SIGFPE, signal_handler);
   11266    signal(SIGILL, signal_handler);
   11267    signal(SIGINT, signal_handler);
   11268    signal(SIGSEGV, signal_handler);
   11269    signal(SIGTERM, signal_handler);
   11270 
   11271 #ifdef HAVE_FEENABLEEXCEPT
   11272    /* Only required to enable FP exceptions on platforms where they start off
   11273     * disabled; this is not necessary but if it is not done pngvalid will likely
   11274     * end up ignoring FP conditions that other platforms fault.
   11275     */
   11276    feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
   11277 #endif
   11278 
   11279    modifier_init(&pm);
   11280 
   11281    /* Preallocate the image buffer, because we know how big it needs to be,
   11282     * note that, for testing purposes, it is deliberately mis-aligned by tag
   11283     * bytes either side.  All rows have an additional five bytes of padding for
   11284     * overwrite checking.
   11285     */
   11286    store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX);
   11287 
   11288    /* Don't give argv[0], it's normally some horrible libtool string: */
   11289    cp = safecat(command, sizeof command, cp, "pngvalid");
   11290 
   11291    /* Default to error on warning: */
   11292    pm.this.treat_warnings_as_errors = 1;
   11293 
   11294    /* Default assume_16_bit_calculations appropriately; this tells the checking
   11295     * code that 16-bit arithmetic is used for 8-bit samples when it would make a
   11296     * difference.
   11297     */
   11298    pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700;
   11299 
   11300    /* Currently 16 bit expansion happens at the end of the pipeline, so the
   11301     * calculations are done in the input bit depth not the output.
   11302     *
   11303     * TODO: fix this
   11304     */
   11305    pm.calculations_use_input_precision = 1U;
   11306 
   11307    /* Store the test gammas */
   11308    pm.gammas = gammas;
   11309    pm.ngammas = ARRAY_SIZE(gammas);
   11310    pm.ngamma_tests = 0; /* default to off */
   11311 
   11312    /* Low bit depth gray images don't do well in the gamma tests, until
   11313     * this is fixed turn them off for some gamma cases:
   11314     */
   11315 #  ifdef PNG_WRITE_tRNS_SUPPORTED
   11316       pm.test_tRNS = 1;
   11317 #  endif
   11318    pm.test_lbg = PNG_LIBPNG_VER >= 10600;
   11319    pm.test_lbg_gamma_threshold = 1;
   11320    pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600;
   11321    pm.test_lbg_gamma_sbit = 1;
   11322    pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700;
   11323 
   11324    /* And the test encodings */
   11325    pm.encodings = test_encodings;
   11326    pm.nencodings = ARRAY_SIZE(test_encodings);
   11327 
   11328 #  if PNG_LIBPNG_VER < 10700
   11329       pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */
   11330 #  else
   11331       pm.sbitlow = 1U;
   11332 #  endif
   11333 
   11334    /* The following allows results to pass if they correspond to anything in the
   11335     * transformed range [input-.5,input+.5]; this is is required because of the
   11336     * way libpng treates the 16_TO_8 flag when building the gamma tables in
   11337     * releases up to 1.6.0.
   11338     *
   11339     * TODO: review this
   11340     */
   11341    pm.use_input_precision_16to8 = 1U;
   11342    pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */
   11343 
   11344    /* Some default values (set the behavior for 'make check' here).
   11345     * These values simply control the maximum error permitted in the gamma
   11346     * transformations.  The practial limits for human perception are described
   11347     * below (the setting for maxpc16), however for 8 bit encodings it isn't
   11348     * possible to meet the accepted capabilities of human vision - i.e. 8 bit
   11349     * images can never be good enough, regardless of encoding.
   11350     */
   11351    pm.maxout8 = .1;     /* Arithmetic error in *encoded* value */
   11352    pm.maxabs8 = .00005; /* 1/20000 */
   11353    pm.maxcalc8 = 1./255;  /* +/-1 in 8 bits for compose errors */
   11354    pm.maxpc8 = .499;    /* I.e., .499% fractional error */
   11355    pm.maxout16 = .499;  /* Error in *encoded* value */
   11356    pm.maxabs16 = .00005;/* 1/20000 */
   11357    pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */
   11358 #  if PNG_LIBPNG_VER < 10700
   11359       pm.maxcalcG = 1./((1<<PNG_MAX_GAMMA_8)-1);
   11360 #  else
   11361       pm.maxcalcG = 1./((1<<16)-1);
   11362 #  endif
   11363 
   11364    /* NOTE: this is a reasonable perceptual limit. We assume that humans can
   11365     * perceive light level differences of 1% over a 100:1 range, so we need to
   11366     * maintain 1 in 10000 accuracy (in linear light space), which is what the
   11367     * following guarantees.  It also allows significantly higher errors at
   11368     * higher 16 bit values, which is important for performance.  The actual
   11369     * maximum 16 bit error is about +/-1.9 in the fixed point implementation but
   11370     * this is only allowed for values >38149 by the following:
   11371     */
   11372    pm.maxpc16 = .005;   /* I.e., 1/200% - 1/20000 */
   11373 
   11374    /* Now parse the command line options. */
   11375    while (--argc >= 1)
   11376    {
   11377       int catmore = 0; /* Set if the argument has an argument. */
   11378 
   11379       /* Record each argument for posterity: */
   11380       cp = safecat(command, sizeof command, cp, " ");
   11381       cp = safecat(command, sizeof command, cp, *++argv);
   11382 
   11383       if (strcmp(*argv, "-v") == 0)
   11384          pm.this.verbose = 1;
   11385 
   11386       else if (strcmp(*argv, "-l") == 0)
   11387          pm.log = 1;
   11388 
   11389       else if (strcmp(*argv, "-q") == 0)
   11390          summary = pm.this.verbose = pm.log = 0;
   11391 
   11392       else if (strcmp(*argv, "-w") == 0 ||
   11393                strcmp(*argv, "--strict") == 0)
   11394          pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */
   11395 
   11396       else if (strcmp(*argv, "--nostrict") == 0)
   11397          pm.this.treat_warnings_as_errors = 0;
   11398 
   11399       else if (strcmp(*argv, "--speed") == 0)
   11400          pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0,
   11401             summary = 0;
   11402 
   11403       else if (strcmp(*argv, "--memory") == 0)
   11404          memstats = 1;
   11405 
   11406       else if (strcmp(*argv, "--size") == 0)
   11407          pm.test_size = 1;
   11408 
   11409       else if (strcmp(*argv, "--nosize") == 0)
   11410          pm.test_size = 0;
   11411 
   11412       else if (strcmp(*argv, "--standard") == 0)
   11413          pm.test_standard = 1;
   11414 
   11415       else if (strcmp(*argv, "--nostandard") == 0)
   11416          pm.test_standard = 0;
   11417 
   11418       else if (strcmp(*argv, "--transform") == 0)
   11419          pm.test_transform = 1;
   11420 
   11421       else if (strcmp(*argv, "--notransform") == 0)
   11422          pm.test_transform = 0;
   11423 
   11424 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   11425       else if (strncmp(*argv, "--transform-disable=",
   11426          sizeof "--transform-disable") == 0)
   11427          {
   11428          pm.test_transform = 1;
   11429          transform_disable(*argv + sizeof "--transform-disable");
   11430          }
   11431 
   11432       else if (strncmp(*argv, "--transform-enable=",
   11433          sizeof "--transform-enable") == 0)
   11434          {
   11435          pm.test_transform = 1;
   11436          transform_enable(*argv + sizeof "--transform-enable");
   11437          }
   11438 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
   11439 
   11440       else if (strcmp(*argv, "--gamma") == 0)
   11441          {
   11442          /* Just do two gamma tests here (2.2 and linear) for speed: */
   11443          pm.ngamma_tests = 2U;
   11444          pm.test_gamma_threshold = 1;
   11445          pm.test_gamma_transform = 1;
   11446          pm.test_gamma_sbit = 1;
   11447          pm.test_gamma_scale16 = 1;
   11448          pm.test_gamma_background = 1; /* composition */
   11449          pm.test_gamma_alpha_mode = 1;
   11450          }
   11451 
   11452       else if (strcmp(*argv, "--nogamma") == 0)
   11453          pm.ngamma_tests = 0;
   11454 
   11455       else if (strcmp(*argv, "--gamma-threshold") == 0)
   11456          pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1;
   11457 
   11458       else if (strcmp(*argv, "--nogamma-threshold") == 0)
   11459          pm.test_gamma_threshold = 0;
   11460 
   11461       else if (strcmp(*argv, "--gamma-transform") == 0)
   11462          pm.ngamma_tests = 2U, pm.test_gamma_transform = 1;
   11463 
   11464       else if (strcmp(*argv, "--nogamma-transform") == 0)
   11465          pm.test_gamma_transform = 0;
   11466 
   11467       else if (strcmp(*argv, "--gamma-sbit") == 0)
   11468          pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1;
   11469 
   11470       else if (strcmp(*argv, "--nogamma-sbit") == 0)
   11471          pm.test_gamma_sbit = 0;
   11472 
   11473       else if (strcmp(*argv, "--gamma-16-to-8") == 0)
   11474          pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1;
   11475 
   11476       else if (strcmp(*argv, "--nogamma-16-to-8") == 0)
   11477          pm.test_gamma_scale16 = 0;
   11478 
   11479       else if (strcmp(*argv, "--gamma-background") == 0)
   11480          pm.ngamma_tests = 2U, pm.test_gamma_background = 1;
   11481 
   11482       else if (strcmp(*argv, "--nogamma-background") == 0)
   11483          pm.test_gamma_background = 0;
   11484 
   11485       else if (strcmp(*argv, "--gamma-alpha-mode") == 0)
   11486          pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1;
   11487 
   11488       else if (strcmp(*argv, "--nogamma-alpha-mode") == 0)
   11489          pm.test_gamma_alpha_mode = 0;
   11490 
   11491       else if (strcmp(*argv, "--expand16") == 0)
   11492          pm.test_gamma_expand16 = 1;
   11493 
   11494       else if (strcmp(*argv, "--noexpand16") == 0)
   11495          pm.test_gamma_expand16 = 0;
   11496 
   11497       else if (strcmp(*argv, "--low-depth-gray") == 0)
   11498          pm.test_lbg = pm.test_lbg_gamma_threshold =
   11499             pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
   11500             pm.test_lbg_gamma_composition = 1;
   11501 
   11502       else if (strcmp(*argv, "--nolow-depth-gray") == 0)
   11503          pm.test_lbg = pm.test_lbg_gamma_threshold =
   11504             pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit =
   11505             pm.test_lbg_gamma_composition = 0;
   11506 
   11507 #     ifdef PNG_WRITE_tRNS_SUPPORTED
   11508          else if (strcmp(*argv, "--tRNS") == 0)
   11509             pm.test_tRNS = 1;
   11510 #     endif
   11511 
   11512       else if (strcmp(*argv, "--notRNS") == 0)
   11513          pm.test_tRNS = 0;
   11514 
   11515       else if (strcmp(*argv, "--more-gammas") == 0)
   11516          pm.ngamma_tests = 3U;
   11517 
   11518       else if (strcmp(*argv, "--all-gammas") == 0)
   11519          pm.ngamma_tests = pm.ngammas;
   11520 
   11521       else if (strcmp(*argv, "--progressive-read") == 0)
   11522          pm.this.progressive = 1;
   11523 
   11524       else if (strcmp(*argv, "--use-update-info") == 0)
   11525          ++pm.use_update_info; /* Can call multiple times */
   11526 
   11527       else if (strcmp(*argv, "--interlace") == 0)
   11528       {
   11529 #        if CAN_WRITE_INTERLACE
   11530             pm.interlace_type = PNG_INTERLACE_ADAM7;
   11531 #        else /* !CAN_WRITE_INTERLACE */
   11532             fprintf(stderr, "pngvalid: no write interlace support\n");
   11533             return SKIP;
   11534 #        endif /* !CAN_WRITE_INTERLACE */
   11535       }
   11536 
   11537       else if (strcmp(*argv, "--use-input-precision") == 0)
   11538          pm.use_input_precision = 1U;
   11539 
   11540       else if (strcmp(*argv, "--use-calculation-precision") == 0)
   11541          pm.use_input_precision = 0;
   11542 
   11543       else if (strcmp(*argv, "--calculations-use-input-precision") == 0)
   11544          pm.calculations_use_input_precision = 1U;
   11545 
   11546       else if (strcmp(*argv, "--assume-16-bit-calculations") == 0)
   11547          pm.assume_16_bit_calculations = 1U;
   11548 
   11549       else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0)
   11550          pm.calculations_use_input_precision =
   11551             pm.assume_16_bit_calculations = 0;
   11552 
   11553       else if (strcmp(*argv, "--exhaustive") == 0)
   11554          pm.test_exhaustive = 1;
   11555 
   11556       else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0)
   11557          --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1;
   11558 
   11559       else if (argc > 1 && strcmp(*argv, "--touch") == 0)
   11560          --argc, touch = *++argv, catmore = 1;
   11561 
   11562       else if (argc > 1 && strncmp(*argv, "--max", 5) == 0)
   11563       {
   11564          --argc;
   11565 
   11566          if (strcmp(5+*argv, "abs8") == 0)
   11567             pm.maxabs8 = atof(*++argv);
   11568 
   11569          else if (strcmp(5+*argv, "abs16") == 0)
   11570             pm.maxabs16 = atof(*++argv);
   11571 
   11572          else if (strcmp(5+*argv, "calc8") == 0)
   11573             pm.maxcalc8 = atof(*++argv);
   11574 
   11575          else if (strcmp(5+*argv, "calc16") == 0)
   11576             pm.maxcalc16 = atof(*++argv);
   11577 
   11578          else if (strcmp(5+*argv, "out8") == 0)
   11579             pm.maxout8 = atof(*++argv);
   11580 
   11581          else if (strcmp(5+*argv, "out16") == 0)
   11582             pm.maxout16 = atof(*++argv);
   11583 
   11584          else if (strcmp(5+*argv, "pc8") == 0)
   11585             pm.maxpc8 = atof(*++argv);
   11586 
   11587          else if (strcmp(5+*argv, "pc16") == 0)
   11588             pm.maxpc16 = atof(*++argv);
   11589 
   11590          else
   11591          {
   11592             fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv);
   11593             exit(99);
   11594          }
   11595 
   11596          catmore = 1;
   11597       }
   11598 
   11599       else if (strcmp(*argv, "--log8") == 0)
   11600          --argc, pm.log8 = atof(*++argv), catmore = 1;
   11601 
   11602       else if (strcmp(*argv, "--log16") == 0)
   11603          --argc, pm.log16 = atof(*++argv), catmore = 1;
   11604 
   11605 #ifdef PNG_SET_OPTION_SUPPORTED
   11606       else if (strncmp(*argv, "--option=", 9) == 0)
   11607       {
   11608          /* Syntax of the argument is <option>:{on|off} */
   11609          const char *arg = 9+*argv;
   11610          unsigned char option=0, setting=0;
   11611 
   11612 #ifdef PNG_ARM_NEON
   11613          if (strncmp(arg, "arm-neon:", 9) == 0)
   11614             option = PNG_ARM_NEON, arg += 9;
   11615 
   11616          else
   11617 #endif
   11618 #ifdef PNG_EXTENSIONS
   11619          if (strncmp(arg, "extensions:", 11) == 0)
   11620             option = PNG_EXTENSIONS, arg += 11;
   11621 
   11622          else
   11623 #endif
   11624 #ifdef PNG_MAXIMUM_INFLATE_WINDOW
   11625          if (strncmp(arg, "max-inflate-window:", 19) == 0)
   11626             option = PNG_MAXIMUM_INFLATE_WINDOW, arg += 19;
   11627 
   11628          else
   11629 #endif
   11630          {
   11631             fprintf(stderr, "pngvalid: %s: %s: unknown option\n", *argv, arg);
   11632             exit(99);
   11633          }
   11634 
   11635          if (strcmp(arg, "off") == 0)
   11636             setting = PNG_OPTION_OFF;
   11637 
   11638          else if (strcmp(arg, "on") == 0)
   11639             setting = PNG_OPTION_ON;
   11640 
   11641          else
   11642          {
   11643             fprintf(stderr,
   11644                "pngvalid: %s: %s: unknown setting (use 'on' or 'off')\n",
   11645                *argv, arg);
   11646             exit(99);
   11647          }
   11648 
   11649          pm.this.options[pm.this.noptions].option = option;
   11650          pm.this.options[pm.this.noptions++].setting = setting;
   11651       }
   11652 #endif /* PNG_SET_OPTION_SUPPORTED */
   11653 
   11654       else
   11655       {
   11656          fprintf(stderr, "pngvalid: %s: unknown argument\n", *argv);
   11657          exit(99);
   11658       }
   11659 
   11660       if (catmore) /* consumed an extra *argv */
   11661       {
   11662          cp = safecat(command, sizeof command, cp, " ");
   11663          cp = safecat(command, sizeof command, cp, *argv);
   11664       }
   11665    }
   11666 
   11667    /* If pngvalid is run with no arguments default to a reasonable set of the
   11668     * tests.
   11669     */
   11670    if (pm.test_standard == 0 && pm.test_size == 0 && pm.test_transform == 0 &&
   11671       pm.ngamma_tests == 0)
   11672    {
   11673       /* Make this do all the tests done in the test shell scripts with the same
   11674        * parameters, where possible.  The limitation is that all the progressive
   11675        * read and interlace stuff has to be done in separate runs, so only the
   11676        * basic 'standard' and 'size' tests are done.
   11677        */
   11678       pm.test_standard = 1;
   11679       pm.test_size = 1;
   11680       pm.test_transform = 1;
   11681       pm.ngamma_tests = 2U;
   11682    }
   11683 
   11684    if (pm.ngamma_tests > 0 &&
   11685       pm.test_gamma_threshold == 0 && pm.test_gamma_transform == 0 &&
   11686       pm.test_gamma_sbit == 0 && pm.test_gamma_scale16 == 0 &&
   11687       pm.test_gamma_background == 0 && pm.test_gamma_alpha_mode == 0)
   11688    {
   11689       pm.test_gamma_threshold = 1;
   11690       pm.test_gamma_transform = 1;
   11691       pm.test_gamma_sbit = 1;
   11692       pm.test_gamma_scale16 = 1;
   11693       pm.test_gamma_background = 1;
   11694       pm.test_gamma_alpha_mode = 1;
   11695    }
   11696 
   11697    else if (pm.ngamma_tests == 0)
   11698    {
   11699       /* Nothing to test so turn everything off: */
   11700       pm.test_gamma_threshold = 0;
   11701       pm.test_gamma_transform = 0;
   11702       pm.test_gamma_sbit = 0;
   11703       pm.test_gamma_scale16 = 0;
   11704       pm.test_gamma_background = 0;
   11705       pm.test_gamma_alpha_mode = 0;
   11706    }
   11707 
   11708    Try
   11709    {
   11710       /* Make useful base images */
   11711       make_transform_images(&pm);
   11712 
   11713       /* Perform the standard and gamma tests. */
   11714       if (pm.test_standard)
   11715       {
   11716          perform_interlace_macro_validation();
   11717          perform_formatting_test(&pm.this);
   11718 #        ifdef PNG_READ_SUPPORTED
   11719             perform_standard_test(&pm);
   11720 #        endif
   11721          perform_error_test(&pm);
   11722       }
   11723 
   11724       /* Various oddly sized images: */
   11725       if (pm.test_size)
   11726       {
   11727          make_size_images(&pm.this);
   11728 #        ifdef PNG_READ_SUPPORTED
   11729             perform_size_test(&pm);
   11730 #        endif
   11731       }
   11732 
   11733 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
   11734       /* Combinatorial transforms: */
   11735       if (pm.test_transform)
   11736          perform_transform_test(&pm);
   11737 #endif /* PNG_READ_TRANSFORMS_SUPPORTED */
   11738 
   11739 #ifdef PNG_READ_GAMMA_SUPPORTED
   11740       if (pm.ngamma_tests > 0)
   11741          perform_gamma_test(&pm, summary);
   11742 #endif
   11743    }
   11744 
   11745    Catch_anonymous
   11746    {
   11747       fprintf(stderr, "pngvalid: test aborted (probably failed in cleanup)\n");
   11748       if (!pm.this.verbose)
   11749       {
   11750          if (pm.this.error[0] != 0)
   11751             fprintf(stderr, "pngvalid: first error: %s\n", pm.this.error);
   11752 
   11753          fprintf(stderr, "pngvalid: run with -v to see what happened\n");
   11754       }
   11755       exit(1);
   11756    }
   11757 
   11758    if (summary)
   11759    {
   11760       printf("%s: %s (%s point arithmetic)\n",
   11761          (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
   11762             pm.this.nwarnings)) ? "FAIL" : "PASS",
   11763          command,
   11764 #if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || PNG_LIBPNG_VER < 10500
   11765          "floating"
   11766 #else
   11767          "fixed"
   11768 #endif
   11769          );
   11770    }
   11771 
   11772    if (memstats)
   11773    {
   11774       printf("Allocated memory statistics (in bytes):\n"
   11775          "\tread  %lu maximum single, %lu peak, %lu total\n"
   11776          "\twrite %lu maximum single, %lu peak, %lu total\n",
   11777          (unsigned long)pm.this.read_memory_pool.max_max,
   11778          (unsigned long)pm.this.read_memory_pool.max_limit,
   11779          (unsigned long)pm.this.read_memory_pool.max_total,
   11780          (unsigned long)pm.this.write_memory_pool.max_max,
   11781          (unsigned long)pm.this.write_memory_pool.max_limit,
   11782          (unsigned long)pm.this.write_memory_pool.max_total);
   11783    }
   11784 
   11785    /* Do this here to provoke memory corruption errors in memory not directly
   11786     * allocated by libpng - not a complete test, but better than nothing.
   11787     */
   11788    store_delete(&pm.this);
   11789 
   11790    /* Error exit if there are any errors, and maybe if there are any
   11791     * warnings.
   11792     */
   11793    if (pm.this.nerrors || (pm.this.treat_warnings_as_errors &&
   11794        pm.this.nwarnings))
   11795    {
   11796       if (!pm.this.verbose)
   11797          fprintf(stderr, "pngvalid: %s\n", pm.this.error);
   11798 
   11799       fprintf(stderr, "pngvalid: %d errors, %d warnings\n", pm.this.nerrors,
   11800           pm.this.nwarnings);
   11801 
   11802       exit(1);
   11803    }
   11804 
   11805    /* Success case. */
   11806    if (touch != NULL)
   11807    {
   11808       FILE *fsuccess = fopen(touch, "wt");
   11809 
   11810       if (fsuccess != NULL)
   11811       {
   11812          int error = 0;
   11813          fprintf(fsuccess, "PNG validation succeeded\n");
   11814          fflush(fsuccess);
   11815          error = ferror(fsuccess);
   11816 
   11817          if (fclose(fsuccess) || error)
   11818          {
   11819             fprintf(stderr, "%s: write failed\n", touch);
   11820             exit(1);
   11821          }
   11822       }
   11823 
   11824       else
   11825       {
   11826          fprintf(stderr, "%s: open failed\n", touch);
   11827          exit(1);
   11828       }
   11829    }
   11830 
   11831    /* This is required because some very minimal configurations do not use it:
   11832     */
   11833    UNUSED(fail)
   11834    return 0;
   11835 }
   11836 #else /* write or low level APIs not supported */
   11837 int main(void)
   11838 {
   11839    fprintf(stderr,
   11840       "pngvalid: no low level write support in libpng, all tests skipped\n");
   11841    /* So the test is skipped: */
   11842    return SKIP;
   11843 }
   11844 #endif
   11845