Home | History | Annotate | Download | only in libtests
      1 /*-
      2  * pngstest.c
      3  *
      4  * Last changed in libpng 1.6.31 [July 27, 2017]
      5  * Copyright (c) 2013-2017 John Cunningham Bowler
      6  *
      7  * This code is released under the libpng license.
      8  * For conditions of distribution and use, see the disclaimer
      9  * and license in png.h
     10  *
     11  * Test for the PNG 'simplified' APIs.
     12  */
     13 #define _ISOC90_SOURCE 1
     14 #define MALLOC_CHECK_ 2/*glibc facility: turn on debugging*/
     15 
     16 #include <stddef.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <stdio.h>
     20 #include <errno.h>
     21 #include <ctype.h>
     22 #include <math.h>
     23 
     24 #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
     25 #  include <config.h>
     26 #endif
     27 
     28 /* Define the following to use this test against your installed libpng, rather
     29  * than the one being built here:
     30  */
     31 #ifdef PNG_FREESTANDING_TESTS
     32 #  include <png.h>
     33 #else
     34 #  include "../../png.h"
     35 #endif
     36 
     37 /* 1.6.1 added support for the configure test harness, which uses 77 to indicate
     38  * a skipped test, in earlier versions we need to succeed on a skipped test, so:
     39  */
     40 #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H)
     41 #  define SKIP 77
     42 #else
     43 #  define SKIP 0
     44 #endif
     45 
     46 #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */
     47 #include "../tools/sRGB.h"
     48 
     49 /* KNOWN ISSUES
     50  *
     51  * These defines switch on alternate algorithms for format conversions to match
     52  * the current libpng implementation; they are set to allow pngstest to pass
     53  * even though libpng is producing answers that are not as correct as they
     54  * should be.
     55  */
     56 #define ALLOW_UNUSED_GPC 0
     57    /* If true include unused static GPC functions and declare an external array
     58     * of them to hide the fact that they are unused.  This is for development
     59     * use while testing the correct function to use to take into account libpng
     60     * misbehavior, such as using a simple power law to correct sRGB to linear.
     61     */
     62 
     63 /* The following is to support direct compilation of this file as C++ */
     64 #ifdef __cplusplus
     65 #  define voidcast(type, value) static_cast<type>(value)
     66 #  define aligncastconst(type, value) \
     67       static_cast<type>(static_cast<const void*>(value))
     68 #else
     69 #  define voidcast(type, value) (value)
     70 #  define aligncastconst(type, value) ((const void*)(value))
     71 #endif /* __cplusplus */
     72 
     73 /* During parallel runs of pngstest each temporary file needs a unique name,
     74  * this is used to permit uniqueness using a command line argument which can be
     75  * up to 22 characters long.
     76  */
     77 static char tmpf[23] = "TMP";
     78 
     79 /* Generate random bytes.  This uses a boring repeatable algorithm and it
     80  * is implemented here so that it gives the same set of numbers on every
     81  * architecture.  It's a linear congruential generator (Knuth or Sedgewick
     82  * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and
     83  * Hill, "The Art of Electronics".
     84  */
     85 static void
     86 make_random_bytes(png_uint_32* seed, void* pv, size_t size)
     87 {
     88    png_uint_32 u0 = seed[0], u1 = seed[1];
     89    png_bytep bytes = voidcast(png_bytep, pv);
     90 
     91    /* There are thirty three bits, the next bit in the sequence is bit-33 XOR
     92     * bit-20.  The top 1 bit is in u1, the bottom 32 are in u0.
     93     */
     94    size_t i;
     95    for (i=0; i<size; ++i)
     96    {
     97       /* First generate 8 new bits then shift them in at the end. */
     98       png_uint_32 u = ((u0 >> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff;
     99       u1 <<= 8;
    100       u1 |= u0 >> 24;
    101       u0 <<= 8;
    102       u0 |= u;
    103       *bytes++ = (png_byte)u;
    104    }
    105 
    106    seed[0] = u0;
    107    seed[1] = u1;
    108 }
    109 
    110 static png_uint_32 color_seed[2];
    111 
    112 static void
    113 reseed(void)
    114 {
    115    color_seed[0] = 0x12345678U;
    116    color_seed[1] = 0x9abcdefU;
    117 }
    118 
    119 static void
    120 random_color(png_colorp color)
    121 {
    122    make_random_bytes(color_seed, color, sizeof *color);
    123 }
    124 
    125 /* Math support - neither Cygwin nor Visual Studio have C99 support and we need
    126  * a predictable rounding function, so make one here:
    127  */
    128 static double
    129 closestinteger(double x)
    130 {
    131    return floor(x + .5);
    132 }
    133 
    134 /* Cast support: remove GCC whines. */
    135 static png_byte
    136 u8d(double d)
    137 {
    138    d = closestinteger(d);
    139    return (png_byte)d;
    140 }
    141 
    142 static png_uint_16
    143 u16d(double d)
    144 {
    145    d = closestinteger(d);
    146    return (png_uint_16)d;
    147 }
    148 
    149 /* sRGB support: use exact calculations rounded to the nearest int, see the
    150  * fesetround() call in main().  sRGB_to_d optimizes the 8 to 16-bit conversion.
    151  */
    152 static double sRGB_to_d[256];
    153 static double g22_to_d[256];
    154 
    155 static void
    156 init_sRGB_to_d(void)
    157 {
    158    int i;
    159 
    160    sRGB_to_d[0] = 0;
    161    for (i=1; i<255; ++i)
    162       sRGB_to_d[i] = linear_from_sRGB(i/255.);
    163    sRGB_to_d[255] = 1;
    164 
    165    g22_to_d[0] = 0;
    166    for (i=1; i<255; ++i)
    167       g22_to_d[i] = pow(i/255., 1/.45455);
    168    g22_to_d[255] = 1;
    169 }
    170 
    171 static png_byte
    172 sRGB(double linear /*range 0.0 .. 1.0*/)
    173 {
    174    return u8d(255 * sRGB_from_linear(linear));
    175 }
    176 
    177 static png_byte
    178 isRGB(int fixed_linear)
    179 {
    180    return sRGB(fixed_linear / 65535.);
    181 }
    182 
    183 #if 0 /* not used */
    184 static png_byte
    185 unpremultiply(int component, int alpha)
    186 {
    187    if (alpha <= component)
    188       return 255; /* Arbitrary, but consistent with the libpng code */
    189 
    190    else if (alpha >= 65535)
    191       return isRGB(component);
    192 
    193    else
    194       return sRGB((double)component / alpha);
    195 }
    196 #endif
    197 
    198 static png_uint_16
    199 ilinear(int fixed_srgb)
    200 {
    201    return u16d(65535 * sRGB_to_d[fixed_srgb]);
    202 }
    203 
    204 static png_uint_16
    205 ilineara(int fixed_srgb, int alpha)
    206 {
    207    return u16d((257 * alpha) * sRGB_to_d[fixed_srgb]);
    208 }
    209 
    210 static png_uint_16
    211 ilinear_g22(int fixed_srgb)
    212 {
    213    return u16d(65535 * g22_to_d[fixed_srgb]);
    214 }
    215 
    216 #if ALLOW_UNUSED_GPC
    217 static png_uint_16
    218 ilineara_g22(int fixed_srgb, int alpha)
    219 {
    220    return u16d((257 * alpha) * g22_to_d[fixed_srgb]);
    221 }
    222 #endif
    223 
    224 static double
    225 YfromRGBint(int ir, int ig, int ib)
    226 {
    227    double r = ir;
    228    double g = ig;
    229    double b = ib;
    230    return YfromRGB(r, g, b);
    231 }
    232 
    233 #if 0 /* unused */
    234 /* The error that results from using a 2.2 power law in place of the correct
    235  * sRGB transform, given an 8-bit value which might be either sRGB or power-law.
    236  */
    237 static int
    238 power_law_error8(int value)
    239 {
    240    if (value > 0 && value < 255)
    241    {
    242       double vd = value / 255.;
    243       double e = fabs(
    244          pow(sRGB_to_d[value], 1/2.2) - sRGB_from_linear(pow(vd, 2.2)));
    245 
    246       /* Always allow an extra 1 here for rounding errors */
    247       e = 1+floor(255 * e);
    248       return (int)e;
    249    }
    250 
    251    return 0;
    252 }
    253 
    254 static int error_in_sRGB_roundtrip = 56; /* by experiment */
    255 static int
    256 power_law_error16(int value)
    257 {
    258    if (value > 0 && value < 65535)
    259    {
    260       /* Round trip the value through an 8-bit representation but using
    261        * non-matching to/from conversions.
    262        */
    263       double vd = value / 65535.;
    264       double e = fabs(
    265          pow(sRGB_from_linear(vd), 2.2) - linear_from_sRGB(pow(vd, 1/2.2)));
    266 
    267       /* Always allow an extra 1 here for rounding errors */
    268       e = error_in_sRGB_roundtrip+floor(65535 * e);
    269       return (int)e;
    270    }
    271 
    272    return 0;
    273 }
    274 
    275 static int
    276 compare_8bit(int v1, int v2, int error_limit, int multiple_algorithms)
    277 {
    278    int e = abs(v1-v2);
    279    int ev1, ev2;
    280 
    281    if (e <= error_limit)
    282       return 1;
    283 
    284    if (!multiple_algorithms)
    285       return 0;
    286 
    287    ev1 = power_law_error8(v1);
    288    if (e <= ev1)
    289       return 1;
    290 
    291    ev2 = power_law_error8(v2);
    292    if (e <= ev2)
    293       return 1;
    294 
    295    return 0;
    296 }
    297 
    298 static int
    299 compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms)
    300 {
    301    int e = abs(v1-v2);
    302    int ev1, ev2;
    303 
    304    if (e <= error_limit)
    305       return 1;
    306 
    307    /* "multiple_algorithms" in this case means that a color-map has been
    308     * involved somewhere, so we can deduce that the values were forced to 8-bit
    309     * (like the via_linear case for 8-bit.)
    310     */
    311    if (!multiple_algorithms)
    312       return 0;
    313 
    314    ev1 = power_law_error16(v1);
    315    if (e <= ev1)
    316       return 1;
    317 
    318    ev2 = power_law_error16(v2);
    319    if (e <= ev2)
    320       return 1;
    321 
    322    return 0;
    323 }
    324 #endif /* unused */
    325 
    326 #define USE_FILE 1       /* else memory */
    327 #define USE_STDIO 2      /* else use file name */
    328 #define STRICT 4         /* fail on warnings too */
    329 #define VERBOSE 8
    330 #define KEEP_TMPFILES 16 /* else delete temporary files */
    331 #define KEEP_GOING 32
    332 #define ACCUMULATE 64
    333 #define FAST_WRITE 128
    334 #define sRGB_16BIT 256
    335 #define NO_RESEED  512   /* do not reseed on each new file */
    336 #define GBG_ERROR 1024   /* do not ignore the gamma+background_rgb_to_gray
    337                           * libpng warning. */
    338 
    339 static void
    340 print_opts(png_uint_32 opts)
    341 {
    342    if (opts & USE_FILE)
    343       printf(" --file");
    344    if (opts & USE_STDIO)
    345       printf(" --stdio");
    346    if (!(opts & STRICT))
    347       printf(" --nostrict");
    348    if (opts & VERBOSE)
    349       printf(" --verbose");
    350    if (opts & KEEP_TMPFILES)
    351       printf(" --preserve");
    352    if (opts & KEEP_GOING)
    353       printf(" --keep-going");
    354    if (opts & ACCUMULATE)
    355       printf(" --accumulate");
    356    if (!(opts & FAST_WRITE)) /* --fast is currently the default */
    357       printf(" --slow");
    358    if (opts & sRGB_16BIT)
    359       printf(" --sRGB-16bit");
    360    if (opts & NO_RESEED)
    361       printf(" --noreseed");
    362 #if PNG_LIBPNG_VER < 10700 /* else on by default */
    363    if (opts & GBG_ERROR)
    364       printf(" --fault-gbg-warning");
    365 #endif
    366 }
    367 
    368 #define FORMAT_NO_CHANGE 0x80000000 /* additional flag */
    369 
    370 /* A name table for all the formats - defines the format of the '+' arguments to
    371  * pngstest.
    372  */
    373 #define FORMAT_COUNT 64
    374 #define FORMAT_MASK 0x3f
    375 static PNG_CONST char * PNG_CONST format_names[FORMAT_COUNT] =
    376 {
    377    "sRGB-gray",
    378    "sRGB-gray+alpha",
    379    "sRGB-rgb",
    380    "sRGB-rgb+alpha",
    381    "linear-gray",
    382    "linear-gray+alpha",
    383    "linear-rgb",
    384    "linear-rgb+alpha",
    385 
    386    "color-mapped-sRGB-gray",
    387    "color-mapped-sRGB-gray+alpha",
    388    "color-mapped-sRGB-rgb",
    389    "color-mapped-sRGB-rgb+alpha",
    390    "color-mapped-linear-gray",
    391    "color-mapped-linear-gray+alpha",
    392    "color-mapped-linear-rgb",
    393    "color-mapped-linear-rgb+alpha",
    394 
    395    "sRGB-gray",
    396    "sRGB-gray+alpha",
    397    "sRGB-bgr",
    398    "sRGB-bgr+alpha",
    399    "linear-gray",
    400    "linear-gray+alpha",
    401    "linear-bgr",
    402    "linear-bgr+alpha",
    403 
    404    "color-mapped-sRGB-gray",
    405    "color-mapped-sRGB-gray+alpha",
    406    "color-mapped-sRGB-bgr",
    407    "color-mapped-sRGB-bgr+alpha",
    408    "color-mapped-linear-gray",
    409    "color-mapped-linear-gray+alpha",
    410    "color-mapped-linear-bgr",
    411    "color-mapped-linear-bgr+alpha",
    412 
    413    "sRGB-gray",
    414    "alpha+sRGB-gray",
    415    "sRGB-rgb",
    416    "alpha+sRGB-rgb",
    417    "linear-gray",
    418    "alpha+linear-gray",
    419    "linear-rgb",
    420    "alpha+linear-rgb",
    421 
    422    "color-mapped-sRGB-gray",
    423    "color-mapped-alpha+sRGB-gray",
    424    "color-mapped-sRGB-rgb",
    425    "color-mapped-alpha+sRGB-rgb",
    426    "color-mapped-linear-gray",
    427    "color-mapped-alpha+linear-gray",
    428    "color-mapped-linear-rgb",
    429    "color-mapped-alpha+linear-rgb",
    430 
    431    "sRGB-gray",
    432    "alpha+sRGB-gray",
    433    "sRGB-bgr",
    434    "alpha+sRGB-bgr",
    435    "linear-gray",
    436    "alpha+linear-gray",
    437    "linear-bgr",
    438    "alpha+linear-bgr",
    439 
    440    "color-mapped-sRGB-gray",
    441    "color-mapped-alpha+sRGB-gray",
    442    "color-mapped-sRGB-bgr",
    443    "color-mapped-alpha+sRGB-bgr",
    444    "color-mapped-linear-gray",
    445    "color-mapped-alpha+linear-gray",
    446    "color-mapped-linear-bgr",
    447    "color-mapped-alpha+linear-bgr",
    448 };
    449 
    450 /* Decode an argument to a format number. */
    451 static png_uint_32
    452 formatof(const char *arg)
    453 {
    454    char *ep;
    455    unsigned long format = strtoul(arg, &ep, 0);
    456 
    457    if (ep > arg && *ep == 0 && format < FORMAT_COUNT)
    458       return (png_uint_32)format;
    459 
    460    else for (format=0; format < FORMAT_COUNT; ++format)
    461    {
    462       if (strcmp(format_names[format], arg) == 0)
    463          return (png_uint_32)format;
    464    }
    465 
    466    fprintf(stderr, "pngstest: format name '%s' invalid\n", arg);
    467    return FORMAT_COUNT;
    468 }
    469 
    470 /* Bitset/test functions for formats */
    471 #define FORMAT_SET_COUNT (FORMAT_COUNT / 32)
    472 typedef struct
    473 {
    474    png_uint_32 bits[FORMAT_SET_COUNT];
    475 }
    476 format_list;
    477 
    478 static void format_init(format_list *pf)
    479 {
    480    int i;
    481    for (i=0; i<FORMAT_SET_COUNT; ++i)
    482       pf->bits[i] = 0; /* All off */
    483 }
    484 
    485 #if 0 /* currently unused */
    486 static void format_clear(format_list *pf)
    487 {
    488    int i;
    489    for (i=0; i<FORMAT_SET_COUNT; ++i)
    490       pf->bits[i] = 0;
    491 }
    492 #endif
    493 
    494 static int format_is_initial(format_list *pf)
    495 {
    496    int i;
    497    for (i=0; i<FORMAT_SET_COUNT; ++i)
    498       if (pf->bits[i] != 0)
    499          return 0;
    500 
    501    return 1;
    502 }
    503 
    504 static int format_set(format_list *pf, png_uint_32 format)
    505 {
    506    if (format < FORMAT_COUNT)
    507       return pf->bits[format >> 5] |= ((png_uint_32)1) << (format & 31);
    508 
    509    return 0;
    510 }
    511 
    512 #if 0 /* currently unused */
    513 static int format_unset(format_list *pf, png_uint_32 format)
    514 {
    515    if (format < FORMAT_COUNT)
    516       return pf->bits[format >> 5] &= ~((png_uint_32)1) << (format & 31);
    517 
    518    return 0;
    519 }
    520 #endif
    521 
    522 static int format_isset(format_list *pf, png_uint_32 format)
    523 {
    524    return format < FORMAT_COUNT &&
    525       (pf->bits[format >> 5] & (((png_uint_32)1) << (format & 31))) != 0;
    526 }
    527 
    528 static void format_default(format_list *pf, int redundant)
    529 {
    530    if (redundant)
    531    {
    532       int i;
    533 
    534       /* set everything, including flags that are pointless */
    535       for (i=0; i<FORMAT_SET_COUNT; ++i)
    536          pf->bits[i] = ~(png_uint_32)0;
    537    }
    538 
    539    else
    540    {
    541       png_uint_32 f;
    542 
    543       for (f=0; f<FORMAT_COUNT; ++f)
    544       {
    545          /* Eliminate redundant and unsupported settings. */
    546 #        ifdef PNG_FORMAT_BGR_SUPPORTED
    547             /* BGR is meaningless if no color: */
    548             if ((f & PNG_FORMAT_FLAG_COLOR) == 0 &&
    549                (f & PNG_FORMAT_FLAG_BGR) != 0)
    550 #        else
    551             if ((f & 0x10U/*HACK: fixed value*/) != 0)
    552 #        endif
    553             continue;
    554 
    555          /* AFIRST is meaningless if no alpha: */
    556 #        ifdef PNG_FORMAT_AFIRST_SUPPORTED
    557             if ((f & PNG_FORMAT_FLAG_ALPHA) == 0 &&
    558                (f & PNG_FORMAT_FLAG_AFIRST) != 0)
    559 #        else
    560             if ((f & 0x20U/*HACK: fixed value*/) != 0)
    561 #        endif
    562             continue;
    563 
    564          format_set(pf, f);
    565       }
    566    }
    567 }
    568 
    569 /* THE Image STRUCTURE */
    570 /* The super-class of a png_image, contains the decoded image plus the input
    571  * data necessary to re-read the file with a different format.
    572  */
    573 typedef struct
    574 {
    575    png_image   image;
    576    png_uint_32 opts;
    577    const char *file_name;
    578    int         stride_extra;
    579    FILE       *input_file;
    580    png_voidp   input_memory;
    581    png_size_t  input_memory_size;
    582    png_bytep   buffer;
    583    ptrdiff_t   stride;
    584    png_size_t  bufsize;
    585    png_size_t  allocsize;
    586    char        tmpfile_name[32];
    587    png_uint_16 colormap[256*4];
    588 }
    589 Image;
    590 
    591 /* Initializer: also sets the permitted error limit for 16-bit operations. */
    592 static void
    593 newimage(Image *image)
    594 {
    595    memset(image, 0, sizeof *image);
    596 }
    597 
    598 /* Reset the image to be read again - only needs to rewind the FILE* at present.
    599  */
    600 static void
    601 resetimage(Image *image)
    602 {
    603    if (image->input_file != NULL)
    604       rewind(image->input_file);
    605 }
    606 
    607 /* Free the image buffer; the buffer is re-used on a re-read, this is just for
    608  * cleanup.
    609  */
    610 static void
    611 freebuffer(Image *image)
    612 {
    613    if (image->buffer) free(image->buffer);
    614    image->buffer = NULL;
    615    image->bufsize = 0;
    616    image->allocsize = 0;
    617 }
    618 
    619 /* Delete function; cleans out all the allocated data and the temporary file in
    620  * the image.
    621  */
    622 static void
    623 freeimage(Image *image)
    624 {
    625    freebuffer(image);
    626    png_image_free(&image->image);
    627 
    628    if (image->input_file != NULL)
    629    {
    630       fclose(image->input_file);
    631       image->input_file = NULL;
    632    }
    633 
    634    if (image->input_memory != NULL)
    635    {
    636       free(image->input_memory);
    637       image->input_memory = NULL;
    638       image->input_memory_size = 0;
    639    }
    640 
    641    if (image->tmpfile_name[0] != 0 && (image->opts & KEEP_TMPFILES) == 0)
    642    {
    643       (void)remove(image->tmpfile_name);
    644       image->tmpfile_name[0] = 0;
    645    }
    646 }
    647 
    648 /* This is actually a re-initializer; allows an image structure to be re-used by
    649  * freeing everything that relates to an old image.
    650  */
    651 static void initimage(Image *image, png_uint_32 opts, const char *file_name,
    652    int stride_extra)
    653 {
    654    freeimage(image);
    655    memset(&image->image, 0, sizeof image->image);
    656    image->opts = opts;
    657    image->file_name = file_name;
    658    image->stride_extra = stride_extra;
    659 }
    660 
    661 /* Make sure the image buffer is big enough; allows re-use of the buffer if the
    662  * image is re-read.
    663  */
    664 #define BUFFER_INIT8 73
    665 static void
    666 allocbuffer(Image *image)
    667 {
    668    png_size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride);
    669 
    670    if (size+32 > image->bufsize)
    671    {
    672       freebuffer(image);
    673       image->buffer = voidcast(png_bytep, malloc(size+32));
    674       if (image->buffer == NULL)
    675       {
    676          fflush(stdout);
    677          fprintf(stderr,
    678             "simpletest: out of memory allocating %lu(+32) byte buffer\n",
    679             (unsigned long)size);
    680          exit(1);
    681       }
    682       image->bufsize = size+32;
    683    }
    684 
    685    memset(image->buffer, 95, image->bufsize);
    686    memset(image->buffer+16, BUFFER_INIT8, size);
    687    image->allocsize = size;
    688 }
    689 
    690 /* Make sure 16 bytes match the given byte. */
    691 static int
    692 check16(png_const_bytep bp, int b)
    693 {
    694    int i = 16;
    695 
    696    do
    697       if (*bp != b) return 1;
    698    while (--i);
    699 
    700    return 0;
    701 }
    702 
    703 /* Check for overwrite in the image buffer. */
    704 static void
    705 checkbuffer(Image *image, const char *arg)
    706 {
    707    if (check16(image->buffer, 95))
    708    {
    709       fflush(stdout);
    710       fprintf(stderr, "%s: overwrite at start of image buffer\n", arg);
    711       exit(1);
    712    }
    713 
    714    if (check16(image->buffer+16+image->allocsize, 95))
    715    {
    716       fflush(stdout);
    717       fprintf(stderr, "%s: overwrite at end of image buffer\n", arg);
    718       exit(1);
    719    }
    720 }
    721 
    722 /* ERROR HANDLING */
    723 /* Log a terminal error, also frees the libpng part of the image if necessary.
    724  */
    725 static int
    726 logerror(Image *image, const char *a1, const char *a2, const char *a3)
    727 {
    728    fflush(stdout);
    729    if (image->image.warning_or_error)
    730       fprintf(stderr, "%s%s%s: %s\n", a1, a2, a3, image->image.message);
    731 
    732    else
    733       fprintf(stderr, "%s%s%s\n", a1, a2, a3);
    734 
    735    if (image->image.opaque != NULL)
    736    {
    737       fprintf(stderr, "%s: image opaque pointer non-NULL on error\n",
    738          image->file_name);
    739       png_image_free(&image->image);
    740    }
    741 
    742    return 0;
    743 }
    744 
    745 /* Log an error and close a file (just a utility to do both things in one
    746  * function call.)
    747  */
    748 static int
    749 logclose(Image *image, FILE *f, const char *name, const char *operation)
    750 {
    751    int e = errno;
    752 
    753    fclose(f);
    754    return logerror(image, name, operation, strerror(e));
    755 }
    756 
    757 /* Make sure the png_image has been freed - validates that libpng is doing what
    758  * the spec says and freeing the image.
    759  */
    760 static int
    761 checkopaque(Image *image)
    762 {
    763    if (image->image.opaque != NULL)
    764    {
    765       png_image_free(&image->image);
    766       return logerror(image, image->file_name, ": opaque not NULL", "");
    767    }
    768 
    769    /* Separate out the gamma+background_rgb_to_gray warning because it may
    770     * produce opaque component errors:
    771     */
    772    else if (image->image.warning_or_error != 0 &&
    773             (strcmp(image->image.message,
    774                "libpng does not support gamma+background+rgb_to_gray") == 0 ?
    775                   (image->opts & GBG_ERROR) != 0 : (image->opts & STRICT) != 0))
    776       return logerror(image, image->file_name, (image->opts & GBG_ERROR) != 0 ?
    777                       " --fault-gbg-warning" : " --strict", "");
    778 
    779    else
    780       return 1;
    781 }
    782 
    783 /* IMAGE COMPARISON/CHECKING */
    784 /* Compare the pixels of two images, which should be the same but aren't.  The
    785  * images must have been checked for a size match.
    786  */
    787 typedef struct
    788 {
    789    /* The components, for grayscale images the gray value is in 'g' and if alpha
    790     * is not present 'a' is set to 255 or 65535 according to format.
    791     */
    792    int         r, g, b, a;
    793 } Pixel;
    794 
    795 typedef struct
    796 {
    797    /* The background as the original sRGB 8-bit value converted to the final
    798     * integer format and as a double precision linear value in the range 0..1
    799     * for with partially transparent pixels.
    800     */
    801    int ir, ig, ib;
    802    double dr, dg, db; /* linear r,g,b scaled to 0..1 */
    803 } Background;
    804 
    805 /* Basic image formats; control the data but not the layout thereof. */
    806 #define BASE_FORMATS\
    807    (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_LINEAR)
    808 
    809 /* Read a Pixel from a buffer.  The code below stores the correct routine for
    810  * the format in a function pointer, these are the routines:
    811  */
    812 static void
    813 gp_g8(Pixel *p, png_const_voidp pb)
    814 {
    815    png_const_bytep pp = voidcast(png_const_bytep, pb);
    816 
    817    p->r = p->g = p->b = pp[0];
    818    p->a = 255;
    819 }
    820 
    821 static void
    822 gp_ga8(Pixel *p, png_const_voidp pb)
    823 {
    824    png_const_bytep pp = voidcast(png_const_bytep, pb);
    825 
    826    p->r = p->g = p->b = pp[0];
    827    p->a = pp[1];
    828 }
    829 
    830 #ifdef PNG_FORMAT_AFIRST_SUPPORTED
    831 static void
    832 gp_ag8(Pixel *p, png_const_voidp pb)
    833 {
    834    png_const_bytep pp = voidcast(png_const_bytep, pb);
    835 
    836    p->r = p->g = p->b = pp[1];
    837    p->a = pp[0];
    838 }
    839 #endif
    840 
    841 static void
    842 gp_rgb8(Pixel *p, png_const_voidp pb)
    843 {
    844    png_const_bytep pp = voidcast(png_const_bytep, pb);
    845 
    846    p->r = pp[0];
    847    p->g = pp[1];
    848    p->b = pp[2];
    849    p->a = 255;
    850 }
    851 
    852 #ifdef PNG_FORMAT_BGR_SUPPORTED
    853 static void
    854 gp_bgr8(Pixel *p, png_const_voidp pb)
    855 {
    856    png_const_bytep pp = voidcast(png_const_bytep, pb);
    857 
    858    p->r = pp[2];
    859    p->g = pp[1];
    860    p->b = pp[0];
    861    p->a = 255;
    862 }
    863 #endif
    864 
    865 static void
    866 gp_rgba8(Pixel *p, png_const_voidp pb)
    867 {
    868    png_const_bytep pp = voidcast(png_const_bytep, pb);
    869 
    870    p->r = pp[0];
    871    p->g = pp[1];
    872    p->b = pp[2];
    873    p->a = pp[3];
    874 }
    875 
    876 #ifdef PNG_FORMAT_BGR_SUPPORTED
    877 static void
    878 gp_bgra8(Pixel *p, png_const_voidp pb)
    879 {
    880    png_const_bytep pp = voidcast(png_const_bytep, pb);
    881 
    882    p->r = pp[2];
    883    p->g = pp[1];
    884    p->b = pp[0];
    885    p->a = pp[3];
    886 }
    887 #endif
    888 
    889 #ifdef PNG_FORMAT_AFIRST_SUPPORTED
    890 static void
    891 gp_argb8(Pixel *p, png_const_voidp pb)
    892 {
    893    png_const_bytep pp = voidcast(png_const_bytep, pb);
    894 
    895    p->r = pp[1];
    896    p->g = pp[2];
    897    p->b = pp[3];
    898    p->a = pp[0];
    899 }
    900 #endif
    901 
    902 #if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)
    903 static void
    904 gp_abgr8(Pixel *p, png_const_voidp pb)
    905 {
    906    png_const_bytep pp = voidcast(png_const_bytep, pb);
    907 
    908    p->r = pp[3];
    909    p->g = pp[2];
    910    p->b = pp[1];
    911    p->a = pp[0];
    912 }
    913 #endif
    914 
    915 static void
    916 gp_g16(Pixel *p, png_const_voidp pb)
    917 {
    918    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    919 
    920    p->r = p->g = p->b = pp[0];
    921    p->a = 65535;
    922 }
    923 
    924 static void
    925 gp_ga16(Pixel *p, png_const_voidp pb)
    926 {
    927    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    928 
    929    p->r = p->g = p->b = pp[0];
    930    p->a = pp[1];
    931 }
    932 
    933 #ifdef PNG_FORMAT_AFIRST_SUPPORTED
    934 static void
    935 gp_ag16(Pixel *p, png_const_voidp pb)
    936 {
    937    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    938 
    939    p->r = p->g = p->b = pp[1];
    940    p->a = pp[0];
    941 }
    942 #endif
    943 
    944 static void
    945 gp_rgb16(Pixel *p, png_const_voidp pb)
    946 {
    947    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    948 
    949    p->r = pp[0];
    950    p->g = pp[1];
    951    p->b = pp[2];
    952    p->a = 65535;
    953 }
    954 
    955 #ifdef PNG_FORMAT_BGR_SUPPORTED
    956 static void
    957 gp_bgr16(Pixel *p, png_const_voidp pb)
    958 {
    959    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    960 
    961    p->r = pp[2];
    962    p->g = pp[1];
    963    p->b = pp[0];
    964    p->a = 65535;
    965 }
    966 #endif
    967 
    968 static void
    969 gp_rgba16(Pixel *p, png_const_voidp pb)
    970 {
    971    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    972 
    973    p->r = pp[0];
    974    p->g = pp[1];
    975    p->b = pp[2];
    976    p->a = pp[3];
    977 }
    978 
    979 #ifdef PNG_FORMAT_BGR_SUPPORTED
    980 static void
    981 gp_bgra16(Pixel *p, png_const_voidp pb)
    982 {
    983    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    984 
    985    p->r = pp[2];
    986    p->g = pp[1];
    987    p->b = pp[0];
    988    p->a = pp[3];
    989 }
    990 #endif
    991 
    992 #ifdef PNG_FORMAT_AFIRST_SUPPORTED
    993 static void
    994 gp_argb16(Pixel *p, png_const_voidp pb)
    995 {
    996    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
    997 
    998    p->r = pp[1];
    999    p->g = pp[2];
   1000    p->b = pp[3];
   1001    p->a = pp[0];
   1002 }
   1003 #endif
   1004 
   1005 #if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED)
   1006 static void
   1007 gp_abgr16(Pixel *p, png_const_voidp pb)
   1008 {
   1009    png_const_uint_16p pp = voidcast(png_const_uint_16p, pb);
   1010 
   1011    p->r = pp[3];
   1012    p->g = pp[2];
   1013    p->b = pp[1];
   1014    p->a = pp[0];
   1015 }
   1016 #endif
   1017 
   1018 /* Given a format, return the correct one of the above functions. */
   1019 static void (*
   1020 get_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb)
   1021 {
   1022    /* The color-map flag is irrelevant here - the caller of the function
   1023     * returned must either pass the buffer or, for a color-mapped image, the
   1024     * correct entry in the color-map.
   1025     */
   1026    if (format & PNG_FORMAT_FLAG_LINEAR)
   1027    {
   1028       if (format & PNG_FORMAT_FLAG_COLOR)
   1029       {
   1030 #        ifdef PNG_FORMAT_BGR_SUPPORTED
   1031             if (format & PNG_FORMAT_FLAG_BGR)
   1032             {
   1033                if (format & PNG_FORMAT_FLAG_ALPHA)
   1034                {
   1035 #                 ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1036                      if (format & PNG_FORMAT_FLAG_AFIRST)
   1037                         return gp_abgr16;
   1038 
   1039                      else
   1040 #                 endif
   1041                      return gp_bgra16;
   1042                }
   1043 
   1044                else
   1045                   return gp_bgr16;
   1046             }
   1047 
   1048             else
   1049 #        endif
   1050          {
   1051             if (format & PNG_FORMAT_FLAG_ALPHA)
   1052             {
   1053 #              ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1054                   if (format & PNG_FORMAT_FLAG_AFIRST)
   1055                      return gp_argb16;
   1056 
   1057                   else
   1058 #              endif
   1059                   return gp_rgba16;
   1060             }
   1061 
   1062             else
   1063                return gp_rgb16;
   1064          }
   1065       }
   1066 
   1067       else
   1068       {
   1069          if (format & PNG_FORMAT_FLAG_ALPHA)
   1070          {
   1071 #           ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1072                if (format & PNG_FORMAT_FLAG_AFIRST)
   1073                   return gp_ag16;
   1074 
   1075                else
   1076 #           endif
   1077                return gp_ga16;
   1078          }
   1079 
   1080          else
   1081             return gp_g16;
   1082       }
   1083    }
   1084 
   1085    else
   1086    {
   1087       if (format & PNG_FORMAT_FLAG_COLOR)
   1088       {
   1089 #        ifdef PNG_FORMAT_BGR_SUPPORTED
   1090             if (format & PNG_FORMAT_FLAG_BGR)
   1091             {
   1092                if (format & PNG_FORMAT_FLAG_ALPHA)
   1093                {
   1094 #                 ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1095                      if (format & PNG_FORMAT_FLAG_AFIRST)
   1096                         return gp_abgr8;
   1097 
   1098                      else
   1099 #                 endif
   1100                      return gp_bgra8;
   1101                }
   1102 
   1103                else
   1104                   return gp_bgr8;
   1105             }
   1106 
   1107             else
   1108 #        endif
   1109          {
   1110             if (format & PNG_FORMAT_FLAG_ALPHA)
   1111             {
   1112 #              ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1113                   if (format & PNG_FORMAT_FLAG_AFIRST)
   1114                      return gp_argb8;
   1115 
   1116                   else
   1117 #              endif
   1118                   return gp_rgba8;
   1119             }
   1120 
   1121             else
   1122                return gp_rgb8;
   1123          }
   1124       }
   1125 
   1126       else
   1127       {
   1128          if (format & PNG_FORMAT_FLAG_ALPHA)
   1129          {
   1130 #           ifdef PNG_FORMAT_AFIRST_SUPPORTED
   1131                if (format & PNG_FORMAT_FLAG_AFIRST)
   1132                   return gp_ag8;
   1133 
   1134                else
   1135 #           endif
   1136                return gp_ga8;
   1137          }
   1138 
   1139          else
   1140             return gp_g8;
   1141       }
   1142    }
   1143 }
   1144 
   1145 /* Convertion between pixel formats.  The code above effectively eliminates the
   1146  * component ordering changes leaving three basic changes:
   1147  *
   1148  * 1) Remove an alpha channel by pre-multiplication or compositing on a
   1149  *    background color.  (Adding an alpha channel is a no-op.)
   1150  *
   1151  * 2) Remove color by mapping to grayscale.  (Grayscale to color is a no-op.)
   1152  *
   1153  * 3) Convert between 8-bit and 16-bit components.  (Both directtions are
   1154  *    relevant.)
   1155  *
   1156  * This gives the following base format conversion matrix:
   1157  *
   1158  *   OUT:    ----- 8-bit -----    ----- 16-bit -----
   1159  *   IN     G    GA   RGB  RGBA  G    GA   RGB  RGBA
   1160  *  8 G     .    .    .    .     lin  lin  lin  lin
   1161  *  8 GA    bckg .    bckc .     pre' pre  pre' pre
   1162  *  8 RGB   g8   g8   .    .     glin glin lin  lin
   1163  *  8 RGBA  g8b  g8   bckc .     gpr' gpre pre' pre
   1164  * 16 G     sRGB sRGB sRGB sRGB  .    .    .    .
   1165  * 16 GA    b16g unpg b16c unpc  A    .    A    .
   1166  * 16 RGB   sG   sG   sRGB sRGB  g16  g16  .    .
   1167  * 16 RGBA  gb16 sGp  cb16 sCp   g16  g16' A    .
   1168  *
   1169  *  8-bit to 8-bit:
   1170  * bckg: composite on gray background
   1171  * bckc: composite on color background
   1172  * g8:   convert sRGB components to sRGB grayscale
   1173  * g8b:  convert sRGB components to grayscale and composite on gray background
   1174  *
   1175  *  8-bit to 16-bit:
   1176  * lin:  make sRGB components linear, alpha := 65535
   1177  * pre:  make sRGB components linear and premultiply by alpha  (scale alpha)
   1178  * pre': as 'pre' but alpha := 65535
   1179  * glin: make sRGB components linear, convert to grayscale, alpha := 65535
   1180  * gpre: make sRGB components grayscale and linear and premultiply by alpha
   1181  * gpr': as 'gpre' but alpha := 65535
   1182  *
   1183  *  16-bit to 8-bit:
   1184  * sRGB: convert linear components to sRGB, alpha := 255
   1185  * unpg: unpremultiply gray component and convert to sRGB (scale alpha)
   1186  * unpc: unpremultiply color components and convert to sRGB (scale alpha)
   1187  * b16g: composite linear onto gray background and convert the result to sRGB
   1188  * b16c: composite linear onto color background and convert the result to sRGB
   1189  * sG:   convert linear RGB to sRGB grayscale
   1190  * sGp:  unpremultiply RGB then convert to sRGB grayscale
   1191  * sCp:  unpremultiply RGB then convert to sRGB
   1192  * gb16: composite linear onto background and convert to sRGB grayscale
   1193  *       (order doesn't matter, the composite and grayscale operations permute)
   1194  * cb16: composite linear onto background and convert to sRGB
   1195  *
   1196  *  16-bit to 16-bit:
   1197  * A:    set alpha to 65535
   1198  * g16:  convert linear RGB to linear grayscale (alpha := 65535)
   1199  * g16': as 'g16' but alpha is unchanged
   1200  */
   1201 /* Simple copy: */
   1202 static void
   1203 gpc_noop(Pixel *out, const Pixel *in, const Background *back)
   1204 {
   1205    (void)back;
   1206    out->r = in->r;
   1207    out->g = in->g;
   1208    out->b = in->b;
   1209    out->a = in->a;
   1210 }
   1211 
   1212 #if ALLOW_UNUSED_GPC
   1213 static void
   1214 gpc_nop8(Pixel *out, const Pixel *in, const Background *back)
   1215 {
   1216    (void)back;
   1217    if (in->a == 0)
   1218       out->r = out->g = out->b = 255;
   1219 
   1220    else
   1221    {
   1222       out->r = in->r;
   1223       out->g = in->g;
   1224       out->b = in->b;
   1225    }
   1226 
   1227    out->a = in->a;
   1228 }
   1229 #endif
   1230 
   1231 #if ALLOW_UNUSED_GPC
   1232 static void
   1233 gpc_nop6(Pixel *out, const Pixel *in, const Background *back)
   1234 {
   1235    (void)back;
   1236    if (in->a == 0)
   1237       out->r = out->g = out->b = 65535;
   1238 
   1239    else
   1240    {
   1241       out->r = in->r;
   1242       out->g = in->g;
   1243       out->b = in->b;
   1244    }
   1245 
   1246    out->a = in->a;
   1247 }
   1248 #endif
   1249 
   1250 /* 8-bit to 8-bit conversions */
   1251 /* bckg: composite on gray background */
   1252 static void
   1253 gpc_bckg(Pixel *out, const Pixel *in, const Background *back)
   1254 {
   1255    if (in->a <= 0)
   1256       out->r = out->g = out->b = back->ig;
   1257 
   1258    else if (in->a >= 255)
   1259       out->r = out->g = out->b = in->g;
   1260 
   1261    else
   1262    {
   1263       double a = in->a / 255.;
   1264 
   1265       out->r = out->g = out->b = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));
   1266    }
   1267 
   1268    out->a = 255;
   1269 }
   1270 
   1271 /* bckc: composite on color background */
   1272 static void
   1273 gpc_bckc(Pixel *out, const Pixel *in, const Background *back)
   1274 {
   1275    if (in->a <= 0)
   1276    {
   1277       out->r = back->ir;
   1278       out->g = back->ig;
   1279       out->b = back->ib;
   1280    }
   1281 
   1282    else if (in->a >= 255)
   1283    {
   1284       out->r = in->r;
   1285       out->g = in->g;
   1286       out->b = in->b;
   1287    }
   1288 
   1289    else
   1290    {
   1291       double a = in->a / 255.;
   1292 
   1293       out->r = sRGB(sRGB_to_d[in->r] * a + back->dr * (1-a));
   1294       out->g = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a));
   1295       out->b = sRGB(sRGB_to_d[in->b] * a + back->db * (1-a));
   1296    }
   1297 
   1298    out->a = 255;
   1299 }
   1300 
   1301 /* g8: convert sRGB components to sRGB grayscale */
   1302 static void
   1303 gpc_g8(Pixel *out, const Pixel *in, const Background *back)
   1304 {
   1305    (void)back;
   1306 
   1307    if (in->r == in->g && in->g == in->b)
   1308       out->r = out->g = out->b = in->g;
   1309 
   1310    else
   1311       out->r = out->g = out->b =
   1312          sRGB(YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
   1313 
   1314    out->a = in->a;
   1315 }
   1316 
   1317 /* g8b: convert sRGB components to grayscale and composite on gray background */
   1318 static void
   1319 gpc_g8b(Pixel *out, const Pixel *in, const Background *back)
   1320 {
   1321    if (in->a <= 0)
   1322       out->r = out->g = out->b = back->ig;
   1323 
   1324    else if (in->a >= 255)
   1325    {
   1326       if (in->r == in->g && in->g == in->b)
   1327          out->r = out->g = out->b = in->g;
   1328 
   1329       else
   1330          out->r = out->g = out->b = sRGB(YfromRGB(
   1331             sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
   1332    }
   1333 
   1334    else
   1335    {
   1336       double a = in->a/255.;
   1337 
   1338       out->r = out->g = out->b = sRGB(a * YfromRGB(sRGB_to_d[in->r],
   1339          sRGB_to_d[in->g], sRGB_to_d[in->b]) + back->dg * (1-a));
   1340    }
   1341 
   1342    out->a = 255;
   1343 }
   1344 
   1345 /* 8-bit to 16-bit conversions */
   1346 /* lin: make sRGB components linear, alpha := 65535 */
   1347 static void
   1348 gpc_lin(Pixel *out, const Pixel *in, const Background *back)
   1349 {
   1350    (void)back;
   1351 
   1352    out->r = ilinear(in->r);
   1353 
   1354    if (in->g == in->r)
   1355    {
   1356       out->g = out->r;
   1357 
   1358       if (in->b == in->r)
   1359          out->b = out->r;
   1360 
   1361       else
   1362          out->b = ilinear(in->b);
   1363    }
   1364 
   1365    else
   1366    {
   1367       out->g = ilinear(in->g);
   1368 
   1369       if (in->b == in->r)
   1370          out->b = out->r;
   1371 
   1372       else if (in->b == in->g)
   1373          out->b = out->g;
   1374 
   1375       else
   1376          out->b = ilinear(in->b);
   1377    }
   1378 
   1379    out->a = 65535;
   1380 }
   1381 
   1382 /* pre: make sRGB components linear and premultiply by alpha (scale alpha) */
   1383 static void
   1384 gpc_pre(Pixel *out, const Pixel *in, const Background *back)
   1385 {
   1386    (void)back;
   1387 
   1388    out->r = ilineara(in->r, in->a);
   1389 
   1390    if (in->g == in->r)
   1391    {
   1392       out->g = out->r;
   1393 
   1394       if (in->b == in->r)
   1395          out->b = out->r;
   1396 
   1397       else
   1398          out->b = ilineara(in->b, in->a);
   1399    }
   1400 
   1401    else
   1402    {
   1403       out->g = ilineara(in->g, in->a);
   1404 
   1405       if (in->b == in->r)
   1406          out->b = out->r;
   1407 
   1408       else if (in->b == in->g)
   1409          out->b = out->g;
   1410 
   1411       else
   1412          out->b = ilineara(in->b, in->a);
   1413    }
   1414 
   1415    out->a = in->a * 257;
   1416 }
   1417 
   1418 /* pre': as 'pre' but alpha := 65535 */
   1419 static void
   1420 gpc_preq(Pixel *out, const Pixel *in, const Background *back)
   1421 {
   1422    (void)back;
   1423 
   1424    out->r = ilineara(in->r, in->a);
   1425 
   1426    if (in->g == in->r)
   1427    {
   1428       out->g = out->r;
   1429 
   1430       if (in->b == in->r)
   1431          out->b = out->r;
   1432 
   1433       else
   1434          out->b = ilineara(in->b, in->a);
   1435    }
   1436 
   1437    else
   1438    {
   1439       out->g = ilineara(in->g, in->a);
   1440 
   1441       if (in->b == in->r)
   1442          out->b = out->r;
   1443 
   1444       else if (in->b == in->g)
   1445          out->b = out->g;
   1446 
   1447       else
   1448          out->b = ilineara(in->b, in->a);
   1449    }
   1450 
   1451    out->a = 65535;
   1452 }
   1453 
   1454 /* glin: make sRGB components linear, convert to grayscale, alpha := 65535 */
   1455 static void
   1456 gpc_glin(Pixel *out, const Pixel *in, const Background *back)
   1457 {
   1458    (void)back;
   1459 
   1460    if (in->r == in->g && in->g == in->b)
   1461       out->r = out->g = out->b = ilinear(in->g);
   1462 
   1463    else
   1464       out->r = out->g = out->b = u16d(65535 *
   1465          YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
   1466 
   1467    out->a = 65535;
   1468 }
   1469 
   1470 /* gpre: make sRGB components grayscale and linear and premultiply by alpha */
   1471 static void
   1472 gpc_gpre(Pixel *out, const Pixel *in, const Background *back)
   1473 {
   1474    (void)back;
   1475 
   1476    if (in->r == in->g && in->g == in->b)
   1477       out->r = out->g = out->b = ilineara(in->g, in->a);
   1478 
   1479    else
   1480       out->r = out->g = out->b = u16d(in->a * 257 *
   1481          YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
   1482 
   1483    out->a = 257 * in->a;
   1484 }
   1485 
   1486 /* gpr': as 'gpre' but alpha := 65535 */
   1487 static void
   1488 gpc_gprq(Pixel *out, const Pixel *in, const Background *back)
   1489 {
   1490    (void)back;
   1491 
   1492    if (in->r == in->g && in->g == in->b)
   1493       out->r = out->g = out->b = ilineara(in->g, in->a);
   1494 
   1495    else
   1496       out->r = out->g = out->b = u16d(in->a * 257 *
   1497          YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]));
   1498 
   1499    out->a = 65535;
   1500 }
   1501 
   1502 /* 8-bit to 16-bit conversions for gAMA 45455 encoded values */
   1503 /* Lin: make gAMA 45455 components linear, alpha := 65535 */
   1504 static void
   1505 gpc_Lin(Pixel *out, const Pixel *in, const Background *back)
   1506 {
   1507    (void)back;
   1508 
   1509    out->r = ilinear_g22(in->r);
   1510 
   1511    if (in->g == in->r)
   1512    {
   1513       out->g = out->r;
   1514 
   1515       if (in->b == in->r)
   1516          out->b = out->r;
   1517 
   1518       else
   1519          out->b = ilinear_g22(in->b);
   1520    }
   1521 
   1522    else
   1523    {
   1524       out->g = ilinear_g22(in->g);
   1525 
   1526       if (in->b == in->r)
   1527          out->b = out->r;
   1528 
   1529       else if (in->b == in->g)
   1530          out->b = out->g;
   1531 
   1532       else
   1533          out->b = ilinear_g22(in->b);
   1534    }
   1535 
   1536    out->a = 65535;
   1537 }
   1538 
   1539 #if ALLOW_UNUSED_GPC
   1540 /* Pre: make gAMA 45455 components linear and premultiply by alpha (scale alpha)
   1541  */
   1542 static void
   1543 gpc_Pre(Pixel *out, const Pixel *in, const Background *back)
   1544 {
   1545    (void)back;
   1546 
   1547    out->r = ilineara_g22(in->r, in->a);
   1548 
   1549    if (in->g == in->r)
   1550    {
   1551       out->g = out->r;
   1552 
   1553       if (in->b == in->r)
   1554          out->b = out->r;
   1555 
   1556       else
   1557          out->b = ilineara_g22(in->b, in->a);
   1558    }
   1559 
   1560    else
   1561    {
   1562       out->g = ilineara_g22(in->g, in->a);
   1563 
   1564       if (in->b == in->r)
   1565          out->b = out->r;
   1566 
   1567       else if (in->b == in->g)
   1568          out->b = out->g;
   1569 
   1570       else
   1571          out->b = ilineara_g22(in->b, in->a);
   1572    }
   1573 
   1574    out->a = in->a * 257;
   1575 }
   1576 #endif
   1577 
   1578 #if ALLOW_UNUSED_GPC
   1579 /* Pre': as 'Pre' but alpha := 65535 */
   1580 static void
   1581 gpc_Preq(Pixel *out, const Pixel *in, const Background *back)
   1582 {
   1583    (void)back;
   1584 
   1585    out->r = ilineara_g22(in->r, in->a);
   1586 
   1587    if (in->g == in->r)
   1588    {
   1589       out->g = out->r;
   1590 
   1591       if (in->b == in->r)
   1592          out->b = out->r;
   1593 
   1594       else
   1595          out->b = ilineara_g22(in->b, in->a);
   1596    }
   1597 
   1598    else
   1599    {
   1600       out->g = ilineara_g22(in->g, in->a);
   1601 
   1602       if (in->b == in->r)
   1603          out->b = out->r;
   1604 
   1605       else if (in->b == in->g)
   1606          out->b = out->g;
   1607 
   1608       else
   1609          out->b = ilineara_g22(in->b, in->a);
   1610    }
   1611 
   1612    out->a = 65535;
   1613 }
   1614 #endif
   1615 
   1616 #if ALLOW_UNUSED_GPC
   1617 /* Glin: make gAMA 45455 components linear, convert to grayscale, alpha := 65535
   1618  */
   1619 static void
   1620 gpc_Glin(Pixel *out, const Pixel *in, const Background *back)
   1621 {
   1622    (void)back;
   1623 
   1624    if (in->r == in->g && in->g == in->b)
   1625       out->r = out->g = out->b = ilinear_g22(in->g);
   1626 
   1627    else
   1628       out->r = out->g = out->b = u16d(65535 *
   1629          YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
   1630 
   1631    out->a = 65535;
   1632 }
   1633 #endif
   1634 
   1635 #if ALLOW_UNUSED_GPC
   1636 /* Gpre: make gAMA 45455 components grayscale and linear and premultiply by
   1637  * alpha.
   1638  */
   1639 static void
   1640 gpc_Gpre(Pixel *out, const Pixel *in, const Background *back)
   1641 {
   1642    (void)back;
   1643 
   1644    if (in->r == in->g && in->g == in->b)
   1645       out->r = out->g = out->b = ilineara_g22(in->g, in->a);
   1646 
   1647    else
   1648       out->r = out->g = out->b = u16d(in->a * 257 *
   1649          YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
   1650 
   1651    out->a = 257 * in->a;
   1652 }
   1653 #endif
   1654 
   1655 #if ALLOW_UNUSED_GPC
   1656 /* Gpr': as 'Gpre' but alpha := 65535 */
   1657 static void
   1658 gpc_Gprq(Pixel *out, const Pixel *in, const Background *back)
   1659 {
   1660    (void)back;
   1661 
   1662    if (in->r == in->g && in->g == in->b)
   1663       out->r = out->g = out->b = ilineara_g22(in->g, in->a);
   1664 
   1665    else
   1666       out->r = out->g = out->b = u16d(in->a * 257 *
   1667          YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b]));
   1668 
   1669    out->a = 65535;
   1670 }
   1671 #endif
   1672 
   1673 /* 16-bit to 8-bit conversions */
   1674 /* sRGB: convert linear components to sRGB, alpha := 255 */
   1675 static void
   1676 gpc_sRGB(Pixel *out, const Pixel *in, const Background *back)
   1677 {
   1678    (void)back;
   1679 
   1680    out->r = isRGB(in->r);
   1681 
   1682    if (in->g == in->r)
   1683    {
   1684       out->g = out->r;
   1685 
   1686       if (in->b == in->r)
   1687          out->b = out->r;
   1688 
   1689       else
   1690          out->b = isRGB(in->b);
   1691    }
   1692 
   1693    else
   1694    {
   1695       out->g = isRGB(in->g);
   1696 
   1697       if (in->b == in->r)
   1698          out->b = out->r;
   1699 
   1700       else if (in->b == in->g)
   1701          out->b = out->g;
   1702 
   1703       else
   1704          out->b = isRGB(in->b);
   1705    }
   1706 
   1707    out->a = 255;
   1708 }
   1709 
   1710 /* unpg: unpremultiply gray component and convert to sRGB (scale alpha) */
   1711 static void
   1712 gpc_unpg(Pixel *out, const Pixel *in, const Background *back)
   1713 {
   1714    (void)back;
   1715 
   1716    if (in->a <= 128)
   1717    {
   1718       out->r = out->g = out->b = 255;
   1719       out->a = 0;
   1720    }
   1721 
   1722    else
   1723    {
   1724       out->r = out->g = out->b = sRGB((double)in->g / in->a);
   1725       out->a = u8d(in->a / 257.);
   1726    }
   1727 }
   1728 
   1729 /* unpc: unpremultiply color components and convert to sRGB (scale alpha) */
   1730 static void
   1731 gpc_unpc(Pixel *out, const Pixel *in, const Background *back)
   1732 {
   1733    (void)back;
   1734 
   1735    if (in->a <= 128)
   1736    {
   1737       out->r = out->g = out->b = 255;
   1738       out->a = 0;
   1739    }
   1740 
   1741    else
   1742    {
   1743       out->r = sRGB((double)in->r / in->a);
   1744       out->g = sRGB((double)in->g / in->a);
   1745       out->b = sRGB((double)in->b / in->a);
   1746       out->a = u8d(in->a / 257.);
   1747    }
   1748 }
   1749 
   1750 /* b16g: composite linear onto gray background and convert the result to sRGB */
   1751 static void
   1752 gpc_b16g(Pixel *out, const Pixel *in, const Background *back)
   1753 {
   1754    if (in->a <= 0)
   1755       out->r = out->g = out->b = back->ig;
   1756 
   1757    else
   1758    {
   1759       double a = in->a/65535.;
   1760       double a1 = 1-a;
   1761 
   1762       a /= 65535;
   1763       out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);
   1764    }
   1765 
   1766    out->a = 255;
   1767 }
   1768 
   1769 /* b16c: composite linear onto color background and convert the result to sRGB*/
   1770 static void
   1771 gpc_b16c(Pixel *out, const Pixel *in, const Background *back)
   1772 {
   1773    if (in->a <= 0)
   1774    {
   1775       out->r = back->ir;
   1776       out->g = back->ig;
   1777       out->b = back->ib;
   1778    }
   1779 
   1780    else
   1781    {
   1782       double a = in->a/65535.;
   1783       double a1 = 1-a;
   1784 
   1785       a /= 65535;
   1786       out->r = sRGB(in->r * a + back->dr * a1);
   1787       out->g = sRGB(in->g * a + back->dg * a1);
   1788       out->b = sRGB(in->b * a + back->db * a1);
   1789    }
   1790 
   1791    out->a = 255;
   1792 }
   1793 
   1794 /* sG: convert linear RGB to sRGB grayscale */
   1795 static void
   1796 gpc_sG(Pixel *out, const Pixel *in, const Background *back)
   1797 {
   1798    (void)back;
   1799 
   1800    out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/65535);
   1801    out->a = 255;
   1802 }
   1803 
   1804 /* sGp: unpremultiply RGB then convert to sRGB grayscale */
   1805 static void
   1806 gpc_sGp(Pixel *out, const Pixel *in, const Background *back)
   1807 {
   1808    (void)back;
   1809 
   1810    if (in->a <= 128)
   1811    {
   1812       out->r = out->g = out->b = 255;
   1813       out->a = 0;
   1814    }
   1815 
   1816    else
   1817    {
   1818       out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/in->a);
   1819       out->a = u8d(in->a / 257.);
   1820    }
   1821 }
   1822 
   1823 /* sCp: unpremultiply RGB then convert to sRGB */
   1824 static void
   1825 gpc_sCp(Pixel *out, const Pixel *in, const Background *back)
   1826 {
   1827    (void)back;
   1828 
   1829    if (in->a <= 128)
   1830    {
   1831       out->r = out->g = out->b = 255;
   1832       out->a = 0;
   1833    }
   1834 
   1835    else
   1836    {
   1837       out->r = sRGB((double)in->r / in->a);
   1838       out->g = sRGB((double)in->g / in->a);
   1839       out->b = sRGB((double)in->b / in->a);
   1840       out->a = u8d(in->a / 257.);
   1841    }
   1842 }
   1843 
   1844 /* gb16: composite linear onto background and convert to sRGB grayscale */
   1845 /*  (order doesn't matter, the composite and grayscale operations permute) */
   1846 static void
   1847 gpc_gb16(Pixel *out, const Pixel *in, const Background *back)
   1848 {
   1849    if (in->a <= 0)
   1850       out->r = out->g = out->b = back->ig;
   1851 
   1852    else if (in->a >= 65535)
   1853       out->r = out->g = out->b = isRGB(in->g);
   1854 
   1855    else
   1856    {
   1857       double a = in->a / 65535.;
   1858       double a1 = 1-a;
   1859 
   1860       a /= 65535;
   1861       out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1);
   1862    }
   1863 
   1864    out->a = 255;
   1865 }
   1866 
   1867 /* cb16: composite linear onto background and convert to sRGB */
   1868 static void
   1869 gpc_cb16(Pixel *out, const Pixel *in, const Background *back)
   1870 {
   1871    if (in->a <= 0)
   1872    {
   1873       out->r = back->ir;
   1874       out->g = back->ig;
   1875       out->b = back->ib;
   1876    }
   1877 
   1878    else if (in->a >= 65535)
   1879    {
   1880       out->r = isRGB(in->r);
   1881       out->g = isRGB(in->g);
   1882       out->b = isRGB(in->b);
   1883    }
   1884 
   1885    else
   1886    {
   1887       double a = in->a / 65535.;
   1888       double a1 = 1-a;
   1889 
   1890       a /= 65535;
   1891       out->r = sRGB(in->r * a + back->dr * a1);
   1892       out->g = sRGB(in->g * a + back->dg * a1);
   1893       out->b = sRGB(in->b * a + back->db * a1);
   1894    }
   1895 
   1896    out->a = 255;
   1897 }
   1898 
   1899 /* 16-bit to 16-bit conversions */
   1900 /* A:    set alpha to 65535 */
   1901 static void
   1902 gpc_A(Pixel *out, const Pixel *in, const Background *back)
   1903 {
   1904    (void)back;
   1905    out->r = in->r;
   1906    out->g = in->g;
   1907    out->b = in->b;
   1908    out->a = 65535;
   1909 }
   1910 
   1911 /* g16:  convert linear RGB to linear grayscale (alpha := 65535) */
   1912 static void
   1913 gpc_g16(Pixel *out, const Pixel *in, const Background *back)
   1914 {
   1915    (void)back;
   1916    out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));
   1917    out->a = 65535;
   1918 }
   1919 
   1920 /* g16': as 'g16' but alpha is unchanged */
   1921 static void
   1922 gpc_g16q(Pixel *out, const Pixel *in, const Background *back)
   1923 {
   1924    (void)back;
   1925    out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b));
   1926    out->a = in->a;
   1927 }
   1928 
   1929 #if ALLOW_UNUSED_GPC
   1930 /* Unused functions (to hide them from GCC unused function warnings) */
   1931 void (* const gpc_unused[])
   1932    (Pixel *out, const Pixel *in, const Background *back) =
   1933 {
   1934    gpc_Pre, gpc_Preq, gpc_Glin, gpc_Gpre, gpc_Gprq, gpc_nop8, gpc_nop6
   1935 };
   1936 #endif
   1937 
   1938 /*   OUT:    ----- 8-bit -----    ----- 16-bit -----
   1939  *   IN     G    GA   RGB  RGBA  G    GA   RGB  RGBA
   1940  *  8 G     .    .    .    .     lin  lin  lin  lin
   1941  *  8 GA    bckg .    bckc .     pre' pre  pre' pre
   1942  *  8 RGB   g8   g8   .    .     glin glin lin  lin
   1943  *  8 RGBA  g8b  g8   bckc .     gpr' gpre pre' pre
   1944  * 16 G     sRGB sRGB sRGB sRGB  .    .    .    .
   1945  * 16 GA    b16g unpg b16c unpc  A    .    A    .
   1946  * 16 RGB   sG   sG   sRGB sRGB  g16  g16  .    .
   1947  * 16 RGBA  gb16 sGp  cb16 sCp   g16  g16' A    .
   1948  *
   1949  * The matrix is held in an array indexed thus:
   1950  *
   1951  *   gpc_fn[out_format & BASE_FORMATS][in_format & BASE_FORMATS];
   1952  */
   1953 /* This will produce a compile time error if the FORMAT_FLAG values don't
   1954  * match the above matrix!
   1955  */
   1956 #if PNG_FORMAT_FLAG_ALPHA == 1 && PNG_FORMAT_FLAG_COLOR == 2 &&\
   1957    PNG_FORMAT_FLAG_LINEAR == 4
   1958 static void (* const gpc_fn[8/*in*/][8/*out*/])
   1959    (Pixel *out, const Pixel *in, const Background *back) =
   1960 {
   1961 /*out: G-8     GA-8     RGB-8    RGBA-8    G-16     GA-16   RGB-16  RGBA-16 */
   1962    {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_Lin, gpc_Lin, gpc_Lin, gpc_Lin },
   1963    {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },
   1964    {gpc_g8,  gpc_g8,  gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },
   1965    {gpc_g8b, gpc_g8,  gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },
   1966    {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},
   1967    {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A,   gpc_noop,gpc_A,   gpc_noop},
   1968    {gpc_sG,  gpc_sG,  gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},
   1969    {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp,  gpc_g16, gpc_g16q,gpc_A,   gpc_noop}
   1970 };
   1971 
   1972 /* The array is repeated for the cases where both the input and output are color
   1973  * mapped because then different algorithms are used.
   1974  */
   1975 static void (* const gpc_fn_colormapped[8/*in*/][8/*out*/])
   1976    (Pixel *out, const Pixel *in, const Background *back) =
   1977 {
   1978 /*out: G-8     GA-8     RGB-8    RGBA-8    G-16     GA-16   RGB-16  RGBA-16 */
   1979    {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_lin, gpc_lin, gpc_lin, gpc_lin },
   1980    {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre },
   1981    {gpc_g8,  gpc_g8,  gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin },
   1982    {gpc_g8b, gpc_g8,  gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre },
   1983    {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop},
   1984    {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A,   gpc_noop,gpc_A,   gpc_noop},
   1985    {gpc_sG,  gpc_sG,  gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop},
   1986    {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp,  gpc_g16, gpc_g16q,gpc_A,   gpc_noop}
   1987 };
   1988 
   1989 /* The error arrays record the error in the same matrix; 64 entries, however
   1990  * the different algorithms used in libpng for colormap and direct conversions
   1991  * mean that four separate matrices are used (for each combination of
   1992  * colormapped and direct.)
   1993  *
   1994  * In some cases the conversion between sRGB formats goes via a linear
   1995  * intermediate; an sRGB to linear conversion (as above) is followed by a simple
   1996  * linear to sRGB step with no other conversions.  This is done by a separate
   1997  * error array from an arbitrary 'in' format to one of the four basic outputs
   1998  * (since final output is always sRGB not colormapped).
   1999  *
   2000  * These arrays may be modified if the --accumulate flag is set during the run;
   2001  * then instead of logging errors they are simply added in.
   2002  *
   2003  * The three entries are currently for transparent, partially transparent and
   2004  * opaque input pixel values.  Notice that alpha should be exact in each case.
   2005  *
   2006  * Errors in alpha should only occur when converting from a direct format
   2007  * to a colormapped format, when alpha is effectively smashed (so large
   2008  * errors can occur.)  There should be no error in the '0' and 'opaque'
   2009  * values.  The fourth entry in the array is used for the alpha error (and it
   2010  * should always be zero for the 'via linear' case since this is never color
   2011  * mapped.)
   2012  *
   2013  * Mapping to a colormap smashes the colors, it is necessary to have separate
   2014  * values for these cases because they are much larger; it is very much
   2015  * impossible to obtain a reasonable result, these are held in
   2016  * gpc_error_to_colormap.
   2017  */
   2018 #if PNG_FORMAT_FLAG_COLORMAP == 8 /* extra check also required */
   2019 #  include "pngstest-errors.h" /* machine generated */
   2020 #endif /* COLORMAP flag check */
   2021 #endif /* flag checks */
   2022 
   2023 typedef struct
   2024 {
   2025    /* Basic pixel information: */
   2026    Image*       in_image;   /* Input image */
   2027    const Image* out_image;  /* Output image */
   2028 
   2029    /* 'background' is the value passed to the gpc_ routines, it may be NULL if
   2030     * it should not be used (*this* program has an error if it crashes as a
   2031     * result!)
   2032     */
   2033    Background        background_color;
   2034    const Background* background;
   2035 
   2036    /* Precalculated values: */
   2037    int          in_opaque;   /* Value of input alpha that is opaque */
   2038    int          is_palette;  /* Sample values come from the palette */
   2039    int          accumulate;  /* Accumlate component errors (don't log) */
   2040    int          output_8bit; /* Output is 8-bit (else 16-bit) */
   2041 
   2042    void (*in_gp)(Pixel*, png_const_voidp);
   2043    void (*out_gp)(Pixel*, png_const_voidp);
   2044 
   2045    void (*transform)(Pixel *out, const Pixel *in, const Background *back);
   2046       /* A function to perform the required transform */
   2047 
   2048    void (*from_linear)(Pixel *out, const Pixel *in, const Background *back);
   2049       /* For 'via_linear' transforms the final, from linear, step, else NULL */
   2050 
   2051    png_uint_16 error[4];
   2052       /* Three error values for transparent, partially transparent and opaque
   2053        * input pixels (in turn).
   2054        */
   2055 
   2056    png_uint_16 *error_ptr;
   2057       /* Where these are stored in the static array (for 'accumulate') */
   2058 }
   2059 Transform;
   2060 
   2061 /* Return a 'transform' as above for the given format conversion. */
   2062 static void
   2063 transform_from_formats(Transform *result, Image *in_image,
   2064    const Image *out_image, png_const_colorp background, int via_linear)
   2065 {
   2066    png_uint_32 in_format, out_format;
   2067    png_uint_32 in_base, out_base;
   2068 
   2069    memset(result, 0, sizeof *result);
   2070 
   2071    /* Store the original images for error messages */
   2072    result->in_image = in_image;
   2073    result->out_image = out_image;
   2074 
   2075    in_format = in_image->image.format;
   2076    out_format = out_image->image.format;
   2077 
   2078    if (in_format & PNG_FORMAT_FLAG_LINEAR)
   2079       result->in_opaque = 65535;
   2080    else
   2081       result->in_opaque = 255;
   2082 
   2083    result->output_8bit = (out_format & PNG_FORMAT_FLAG_LINEAR) == 0;
   2084 
   2085    result->is_palette = 0; /* set by caller if required */
   2086    result->accumulate = (in_image->opts & ACCUMULATE) != 0;
   2087 
   2088    /* The loaders (which need the ordering information) */
   2089    result->in_gp = get_pixel(in_format);
   2090    result->out_gp = get_pixel(out_format);
   2091 
   2092    /* Remove the ordering information: */
   2093    in_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;
   2094    in_base = in_format & BASE_FORMATS;
   2095    out_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP;
   2096    out_base = out_format & BASE_FORMATS;
   2097 
   2098    if (via_linear)
   2099    {
   2100       /* Check for an error in this program: */
   2101       if (out_format & (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLORMAP))
   2102       {
   2103          fprintf(stderr, "internal transform via linear error 0x%x->0x%x\n",
   2104             in_format, out_format);
   2105          exit(1);
   2106       }
   2107 
   2108       result->transform = gpc_fn[in_base][out_base | PNG_FORMAT_FLAG_LINEAR];
   2109       result->from_linear = gpc_fn[out_base | PNG_FORMAT_FLAG_LINEAR][out_base];
   2110       result->error_ptr = gpc_error_via_linear[in_format][out_format];
   2111    }
   2112 
   2113    else if (~in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)
   2114    {
   2115       /* The input is not colormapped but the output is, the errors will
   2116        * typically be large (only the grayscale-no-alpha case permits preserving
   2117        * even 8-bit values.)
   2118        */
   2119       result->transform = gpc_fn[in_base][out_base];
   2120       result->from_linear = NULL;
   2121       result->error_ptr = gpc_error_to_colormap[in_base][out_base];
   2122    }
   2123 
   2124    else
   2125    {
   2126       /* The caller handles the colormap->pixel value conversion, so the
   2127        * transform function just gets a pixel value, however because libpng
   2128        * currently contains a different implementation for mapping a colormap if
   2129        * both input and output are colormapped we need different conversion
   2130        * functions to deal with errors in the libpng implementation.
   2131        */
   2132       if (in_format & out_format & PNG_FORMAT_FLAG_COLORMAP)
   2133          result->transform = gpc_fn_colormapped[in_base][out_base];
   2134       else
   2135          result->transform = gpc_fn[in_base][out_base];
   2136       result->from_linear = NULL;
   2137       result->error_ptr = gpc_error[in_format][out_format];
   2138    }
   2139 
   2140    /* Follow the libpng simplified API rules to work out what to pass to the gpc
   2141     * routines as a background value, if one is not required pass NULL so that
   2142     * this program crashes in the even of a programming error.
   2143     */
   2144    result->background = NULL; /* default: not required */
   2145 
   2146    /* Rule 1: background only need be supplied if alpha is to be removed */
   2147    if (in_format & ~out_format & PNG_FORMAT_FLAG_ALPHA)
   2148    {
   2149       /* The input value is 'NULL' to use the background and (otherwise) an sRGB
   2150        * background color (to use a solid color).  The code above uses a fixed
   2151        * byte value, BUFFER_INIT8, for buffer even for 16-bit output.  For
   2152        * linear (16-bit) output the sRGB background color is ignored; the
   2153        * composition is always on the background (so BUFFER_INIT8 * 257), except
   2154        * that for the colormap (i.e. linear colormapped output) black is used.
   2155        */
   2156       result->background = &result->background_color;
   2157 
   2158       if (out_format & PNG_FORMAT_FLAG_LINEAR || via_linear)
   2159       {
   2160          if (out_format & PNG_FORMAT_FLAG_COLORMAP)
   2161          {
   2162             result->background_color.ir =
   2163                result->background_color.ig =
   2164                result->background_color.ib = 0;
   2165             result->background_color.dr =
   2166                result->background_color.dg =
   2167                result->background_color.db = 0;
   2168          }
   2169 
   2170          else
   2171          {
   2172             result->background_color.ir =
   2173                result->background_color.ig =
   2174                result->background_color.ib = BUFFER_INIT8 * 257;
   2175             result->background_color.dr =
   2176                result->background_color.dg =
   2177                result->background_color.db = 0;
   2178          }
   2179       }
   2180 
   2181       else /* sRGB output */
   2182       {
   2183          if (background != NULL)
   2184          {
   2185             if (out_format & PNG_FORMAT_FLAG_COLOR)
   2186             {
   2187                result->background_color.ir = background->red;
   2188                result->background_color.ig = background->green;
   2189                result->background_color.ib = background->blue;
   2190                /* TODO: sometimes libpng uses the power law conversion here, how
   2191                 * to handle this?
   2192                 */
   2193                result->background_color.dr = sRGB_to_d[background->red];
   2194                result->background_color.dg = sRGB_to_d[background->green];
   2195                result->background_color.db = sRGB_to_d[background->blue];
   2196             }
   2197 
   2198             else /* grayscale: libpng only looks at 'g' */
   2199             {
   2200                result->background_color.ir =
   2201                   result->background_color.ig =
   2202                   result->background_color.ib = background->green;
   2203                /* TODO: sometimes libpng uses the power law conversion here, how
   2204                 * to handle this?
   2205                 */
   2206                result->background_color.dr =
   2207                   result->background_color.dg =
   2208                   result->background_color.db = sRGB_to_d[background->green];
   2209             }
   2210          }
   2211 
   2212          else if ((out_format & PNG_FORMAT_FLAG_COLORMAP) == 0)
   2213          {
   2214             result->background_color.ir =
   2215                result->background_color.ig =
   2216                result->background_color.ib = BUFFER_INIT8;
   2217             /* TODO: sometimes libpng uses the power law conversion here, how
   2218              * to handle this?
   2219              */
   2220             result->background_color.dr =
   2221                result->background_color.dg =
   2222                result->background_color.db = sRGB_to_d[BUFFER_INIT8];
   2223          }
   2224 
   2225          /* Else the output is colormapped and a background color must be
   2226           * provided; if pngstest crashes then that is a bug in this program
   2227           * (though libpng should png_error as well.)
   2228           */
   2229          else
   2230             result->background = NULL;
   2231       }
   2232    }
   2233 
   2234    if (result->background == NULL)
   2235    {
   2236       result->background_color.ir =
   2237          result->background_color.ig =
   2238          result->background_color.ib = -1; /* not used */
   2239       result->background_color.dr =
   2240          result->background_color.dg =
   2241          result->background_color.db = 1E30; /* not used */
   2242    }
   2243 
   2244 
   2245    /* Copy the error values into the Transform: */
   2246    result->error[0] = result->error_ptr[0];
   2247    result->error[1] = result->error_ptr[1];
   2248    result->error[2] = result->error_ptr[2];
   2249    result->error[3] = result->error_ptr[3];
   2250 }
   2251 
   2252 
   2253 /* Compare two pixels.
   2254  *
   2255  * OLD error values:
   2256 static int error_to_linear = 811; * by experiment *
   2257 static int error_to_linear_grayscale = 424; * by experiment *
   2258 static int error_to_sRGB = 6; * by experiment *
   2259 static int error_to_sRGB_grayscale = 17; * libpng error by calculation +
   2260                                             2 by experiment *
   2261 static int error_in_compose = 2; * by experiment *
   2262 static int error_in_premultiply = 1;
   2263  *
   2264  * The following is *just* the result of a round trip from 8-bit sRGB to linear
   2265  * then back to 8-bit sRGB when it is done by libpng.  There are two problems:
   2266  *
   2267  * 1) libpng currently uses a 2.2 power law with no linear segment, this results
   2268  * in instability in the low values and even with 16-bit precision sRGB(1) ends
   2269  * up mapping to sRGB(0) as a result of rounding in the 16-bit representation.
   2270  * This gives an error of 1 in the handling of value 1 only.
   2271  *
   2272  * 2) libpng currently uses an intermediate 8-bit linear value in gamma
   2273  * correction of 8-bit values.  This results in many more errors, the worse of
   2274  * which is mapping sRGB(14) to sRGB(0).
   2275  *
   2276  * The general 'error_via_linear' is more complex because of pre-multiplication,
   2277  * this compounds the 8-bit errors according to the alpha value of the pixel.
   2278  * As a result 256 values are pre-calculated for error_via_linear.
   2279  */
   2280 #if 0
   2281 static int error_in_libpng_gamma;
   2282 static int error_via_linear[256]; /* Indexed by 8-bit alpha */
   2283 
   2284 static void
   2285 init_error_via_linear(void)
   2286 {
   2287    int alpha;
   2288 
   2289    error_via_linear[0] = 255; /* transparent pixel */
   2290 
   2291    for (alpha=1; alpha<=255; ++alpha)
   2292    {
   2293       /* 16-bit values less than 128.5 get rounded to 8-bit 0 and so the worst
   2294        * case error arises with 16-bit 128.5, work out what sRGB
   2295        * (non-associated) value generates 128.5; any value less than this is
   2296        * going to map to 0, so the worst error is floor(value).
   2297        *
   2298        * Note that errors are considerably higher (more than a factor of 2)
   2299        * because libpng uses a simple power law for sRGB data at present.
   2300        *
   2301        * Add .1 for arithmetic errors inside libpng.
   2302        */
   2303       double v = floor(255*pow(.5/*(128.5 * 255 / 65535)*/ / alpha, 1/2.2)+.1);
   2304 
   2305       error_via_linear[alpha] = (int)v;
   2306    }
   2307 
   2308    /* This is actually 14.99, but, despite the closeness to 15, 14 seems to work
   2309     * ok in this case.
   2310     */
   2311    error_in_libpng_gamma = 14;
   2312 }
   2313 #endif
   2314 
   2315 static void
   2316 print_pixel(char string[64], const Pixel *pixel, png_uint_32 format)
   2317 {
   2318    switch (format & (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR))
   2319    {
   2320       case 0:
   2321          sprintf(string, "%s(%d)", format_names[format], pixel->g);
   2322          break;
   2323 
   2324       case PNG_FORMAT_FLAG_ALPHA:
   2325          sprintf(string, "%s(%d,%d)", format_names[format], pixel->g,
   2326             pixel->a);
   2327          break;
   2328 
   2329       case PNG_FORMAT_FLAG_COLOR:
   2330          sprintf(string, "%s(%d,%d,%d)", format_names[format],
   2331             pixel->r, pixel->g, pixel->b);
   2332          break;
   2333 
   2334       case PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA:
   2335          sprintf(string, "%s(%d,%d,%d,%d)", format_names[format],
   2336             pixel->r, pixel->g, pixel->b, pixel->a);
   2337          break;
   2338 
   2339       default:
   2340          sprintf(string, "invalid-format");
   2341          break;
   2342    }
   2343 }
   2344 
   2345 static int
   2346 logpixel(const Transform *transform, png_uint_32 x, png_uint_32 y,
   2347    const Pixel *in, const Pixel *calc, const Pixel *out, const char *reason)
   2348 {
   2349    const png_uint_32 in_format = transform->in_image->image.format;
   2350    const png_uint_32 out_format = transform->out_image->image.format;
   2351 
   2352    png_uint_32 back_format = out_format & ~PNG_FORMAT_FLAG_ALPHA;
   2353    const char *via_linear = "";
   2354 
   2355    char pixel_in[64], pixel_calc[64], pixel_out[64], pixel_loc[64];
   2356    char background_info[100];
   2357 
   2358    print_pixel(pixel_in, in, in_format);
   2359    print_pixel(pixel_calc, calc, out_format);
   2360    print_pixel(pixel_out, out, out_format);
   2361 
   2362    if (transform->is_palette)
   2363       sprintf(pixel_loc, "palette: %lu", (unsigned long)y);
   2364    else
   2365       sprintf(pixel_loc, "%lu,%lu", (unsigned long)x, (unsigned long)y);
   2366 
   2367    if (transform->from_linear != NULL)
   2368    {
   2369       via_linear = " (via linear)";
   2370       /* And as a result the *read* format which did any background processing
   2371        * was itself linear, so the background color information is also
   2372        * linear.
   2373        */
   2374       back_format |= PNG_FORMAT_FLAG_LINEAR;
   2375    }
   2376 
   2377    if (transform->background != NULL)
   2378    {
   2379       Pixel back;
   2380       char pixel_back[64];
   2381 
   2382       back.r = transform->background->ir;
   2383       back.g = transform->background->ig;
   2384       back.b = transform->background->ib;
   2385       back.a = -1; /* not used */
   2386 
   2387       print_pixel(pixel_back, &back, back_format);
   2388       sprintf(background_info, " on background %s", pixel_back);
   2389    }
   2390 
   2391    else
   2392       background_info[0] = 0;
   2393 
   2394    if (transform->in_image->file_name != transform->out_image->file_name)
   2395    {
   2396       char error_buffer[512];
   2397       sprintf(error_buffer,
   2398          "(%s) %s error%s:\n %s%s ->\n       %s\n  not: %s.\n"
   2399          "Use --preserve and examine: ", pixel_loc, reason, via_linear,
   2400          pixel_in, background_info, pixel_out, pixel_calc);
   2401       return logerror(transform->in_image, transform->in_image->file_name,
   2402          error_buffer, transform->out_image->file_name);
   2403    }
   2404 
   2405    else
   2406    {
   2407       char error_buffer[512];
   2408       sprintf(error_buffer,
   2409          "(%s) %s error%s:\n %s%s ->\n       %s\n  not: %s.\n"
   2410          " The error happened when reading the original file with this format.",
   2411          pixel_loc, reason, via_linear, pixel_in, background_info, pixel_out,
   2412          pixel_calc);
   2413       return logerror(transform->in_image, transform->in_image->file_name,
   2414          error_buffer, "");
   2415    }
   2416 }
   2417 
   2418 static int
   2419 cmppixel(Transform *transform, png_const_voidp in, png_const_voidp out,
   2420    png_uint_32 x, png_uint_32 y/*or palette index*/)
   2421 {
   2422    int maxerr;
   2423    png_const_charp errmsg;
   2424    Pixel pixel_in, pixel_calc, pixel_out;
   2425 
   2426    transform->in_gp(&pixel_in, in);
   2427 
   2428    if (transform->from_linear == NULL)
   2429       transform->transform(&pixel_calc, &pixel_in, transform->background);
   2430 
   2431    else
   2432    {
   2433       transform->transform(&pixel_out, &pixel_in, transform->background);
   2434       transform->from_linear(&pixel_calc, &pixel_out, NULL);
   2435    }
   2436 
   2437    transform->out_gp(&pixel_out, out);
   2438 
   2439    /* Eliminate the case where the input and output values match exactly. */
   2440    if (pixel_calc.a == pixel_out.a && pixel_calc.r == pixel_out.r &&
   2441       pixel_calc.g == pixel_out.g && pixel_calc.b == pixel_out.b)
   2442       return 1;
   2443 
   2444    /* Eliminate the case where the output pixel is transparent and the output
   2445     * is 8-bit - any component values are valid.  Don't check the input alpha
   2446     * here to also skip the 16-bit small alpha cases.
   2447     */
   2448    if (transform->output_8bit && pixel_calc.a == 0 && pixel_out.a == 0)
   2449       return 1;
   2450 
   2451    /* Check for alpha errors first; an alpha error can damage the components too
   2452     * so avoid spurious checks on components if one is found.
   2453     */
   2454    errmsg = NULL;
   2455    {
   2456       int err_a = abs(pixel_calc.a-pixel_out.a);
   2457 
   2458       if (err_a > transform->error[3])
   2459       {
   2460          /* If accumulating check the components too */
   2461          if (transform->accumulate)
   2462             transform->error[3] = (png_uint_16)err_a;
   2463 
   2464          else
   2465             errmsg = "alpha";
   2466       }
   2467    }
   2468 
   2469    /* Now if *either* of the output alphas are 0 but alpha is within tolerance
   2470     * eliminate the 8-bit component comparison.
   2471     */
   2472    if (errmsg == NULL && transform->output_8bit &&
   2473       (pixel_calc.a == 0 || pixel_out.a == 0))
   2474       return 1;
   2475 
   2476    if (errmsg == NULL) /* else just signal an alpha error */
   2477    {
   2478       int err_r = abs(pixel_calc.r - pixel_out.r);
   2479       int err_g = abs(pixel_calc.g - pixel_out.g);
   2480       int err_b = abs(pixel_calc.b - pixel_out.b);
   2481       int limit;
   2482 
   2483       if ((err_r | err_g | err_b) == 0)
   2484          return 1; /* exact match */
   2485 
   2486       /* Mismatch on a component, check the input alpha */
   2487       if (pixel_in.a >= transform->in_opaque)
   2488       {
   2489          errmsg = "opaque component";
   2490          limit = 2; /* opaque */
   2491       }
   2492 
   2493       else if (pixel_in.a > 0)
   2494       {
   2495          errmsg = "alpha component";
   2496          limit = 1; /* partially transparent */
   2497       }
   2498 
   2499       else
   2500       {
   2501          errmsg = "transparent component (background)";
   2502          limit = 0; /* transparent */
   2503       }
   2504 
   2505       maxerr = err_r;
   2506       if (maxerr < err_g) maxerr = err_g;
   2507       if (maxerr < err_b) maxerr = err_b;
   2508 
   2509       if (maxerr <= transform->error[limit])
   2510          return 1; /* within the error limits */
   2511 
   2512       /* Handle a component mis-match; log it, just return an error code, or
   2513        * accumulate it.
   2514        */
   2515       if (transform->accumulate)
   2516       {
   2517          transform->error[limit] = (png_uint_16)maxerr;
   2518          return 1; /* to cause the caller to keep going */
   2519       }
   2520    }
   2521 
   2522    /* Failure to match and not accumulating, so the error must be logged. */
   2523    return logpixel(transform, x, y, &pixel_in, &pixel_calc, &pixel_out, errmsg);
   2524 }
   2525 
   2526 static png_byte
   2527 component_loc(png_byte loc[4], png_uint_32 format)
   2528 {
   2529    /* Given a format return the number of channels and the location of
   2530     * each channel.
   2531     *
   2532     * The mask 'loc' contains the component offset of the channels in the
   2533     * following order.  Note that if 'format' is grayscale the entries 1-3 must
   2534     * all contain the location of the gray channel.
   2535     *
   2536     * 0: alpha
   2537     * 1: red or gray
   2538     * 2: green or gray
   2539     * 3: blue or gray
   2540     */
   2541    png_byte channels;
   2542 
   2543    if (format & PNG_FORMAT_FLAG_COLOR)
   2544    {
   2545       channels = 3;
   2546 
   2547       loc[2] = 1;
   2548 
   2549 #     ifdef PNG_FORMAT_BGR_SUPPORTED
   2550          if (format & PNG_FORMAT_FLAG_BGR)
   2551          {
   2552             loc[1] = 2;
   2553             loc[3] = 0;
   2554          }
   2555 
   2556          else
   2557 #     endif
   2558       {
   2559          loc[1] = 0;
   2560          loc[3] = 2;
   2561       }
   2562    }
   2563 
   2564    else
   2565    {
   2566       channels = 1;
   2567       loc[1] = loc[2] = loc[3] = 0;
   2568    }
   2569 
   2570    if (format & PNG_FORMAT_FLAG_ALPHA)
   2571    {
   2572 #     ifdef PNG_FORMAT_AFIRST_SUPPORTED
   2573          if (format & PNG_FORMAT_FLAG_AFIRST)
   2574          {
   2575             loc[0] = 0;
   2576             ++loc[1];
   2577             ++loc[2];
   2578             ++loc[3];
   2579          }
   2580 
   2581          else
   2582 #     endif
   2583          loc[0] = channels;
   2584 
   2585       ++channels;
   2586    }
   2587 
   2588    else
   2589       loc[0] = 4; /* not present */
   2590 
   2591    return channels;
   2592 }
   2593 
   2594 /* Compare two images, the original 'a', which was written out then read back in
   2595  * to * give image 'b'.  The formats may have been changed.
   2596  */
   2597 static int
   2598 compare_two_images(Image *a, Image *b, int via_linear,
   2599    png_const_colorp background)
   2600 {
   2601    ptrdiff_t stridea = a->stride;
   2602    ptrdiff_t strideb = b->stride;
   2603    png_const_bytep rowa = a->buffer+16;
   2604    png_const_bytep rowb = b->buffer+16;
   2605    const png_uint_32 width = a->image.width;
   2606    const png_uint_32 height = a->image.height;
   2607    const png_uint_32 formata = a->image.format;
   2608    const png_uint_32 formatb = b->image.format;
   2609    const unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata);
   2610    const unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb);
   2611    int alpha_added, alpha_removed;
   2612    int bchannels;
   2613    png_uint_32 y;
   2614    Transform tr;
   2615    int btoa[4]={0,0,0,0};
   2616 
   2617    /* This should never happen: */
   2618    if (width != b->image.width || height != b->image.height)
   2619       return logerror(a, a->file_name, ": width x height changed: ",
   2620          b->file_name);
   2621 
   2622    /* Set up the background and the transform */
   2623    transform_from_formats(&tr, a, b, background, via_linear);
   2624 
   2625    /* Find the first row and inter-row space. */
   2626    if (!(formata & PNG_FORMAT_FLAG_COLORMAP) &&
   2627       (formata & PNG_FORMAT_FLAG_LINEAR))
   2628       stridea *= 2;
   2629 
   2630    if (!(formatb & PNG_FORMAT_FLAG_COLORMAP) &&
   2631       (formatb & PNG_FORMAT_FLAG_LINEAR))
   2632       strideb *= 2;
   2633 
   2634    if (stridea < 0) rowa += (height-1) * (-stridea);
   2635    if (strideb < 0) rowb += (height-1) * (-strideb);
   2636 
   2637    /* First shortcut the two colormap case by comparing the image data; if it
   2638     * matches then we expect the colormaps to match, although this is not
   2639     * absolutely necessary for an image match.  If the colormaps fail to match
   2640     * then there is a problem in libpng.
   2641     */
   2642    if (formata & formatb & PNG_FORMAT_FLAG_COLORMAP)
   2643    {
   2644       /* Only check colormap entries that actually exist; */
   2645       png_const_bytep ppa, ppb;
   2646       int match;
   2647       png_byte in_use[256], amax = 0, bmax = 0;
   2648 
   2649       memset(in_use, 0, sizeof in_use);
   2650 
   2651       ppa = rowa;
   2652       ppb = rowb;
   2653 
   2654       /* Do this the slow way to accumulate the 'in_use' flags, don't break out
   2655        * of the loop until the end; this validates the color-mapped data to
   2656        * ensure all pixels are valid color-map indexes.
   2657        */
   2658       for (y=0, match=1; y<height && match; ++y, ppa += stridea, ppb += strideb)
   2659       {
   2660          png_uint_32 x;
   2661 
   2662          for (x=0; x<width; ++x)
   2663          {
   2664             png_byte bval = ppb[x];
   2665             png_byte aval = ppa[x];
   2666 
   2667             if (bval > bmax)
   2668                bmax = bval;
   2669 
   2670             if (bval != aval)
   2671                match = 0;
   2672 
   2673             in_use[aval] = 1;
   2674             if (aval > amax)
   2675                amax = aval;
   2676          }
   2677       }
   2678 
   2679       /* If the buffers match then the colormaps must too. */
   2680       if (match)
   2681       {
   2682          /* Do the color-maps match, entry by entry?  Only check the 'in_use'
   2683           * entries.  An error here should be logged as a color-map error.
   2684           */
   2685          png_const_bytep a_cmap = (png_const_bytep)a->colormap;
   2686          png_const_bytep b_cmap = (png_const_bytep)b->colormap;
   2687          int result = 1; /* match by default */
   2688 
   2689          /* This is used in logpixel to get the error message correct. */
   2690          tr.is_palette = 1;
   2691 
   2692          for (y=0; y<256; ++y, a_cmap += a_sample, b_cmap += b_sample)
   2693             if (in_use[y])
   2694          {
   2695             /* The colormap entries should be valid, but because libpng doesn't
   2696              * do any checking at present the original image may contain invalid
   2697              * pixel values.  These cause an error here (at present) unless
   2698              * accumulating errors in which case the program just ignores them.
   2699              */
   2700             if (y >= a->image.colormap_entries)
   2701             {
   2702                if ((a->opts & ACCUMULATE) == 0)
   2703                {
   2704                   char pindex[9];
   2705                   sprintf(pindex, "%lu[%lu]", (unsigned long)y,
   2706                      (unsigned long)a->image.colormap_entries);
   2707                   logerror(a, a->file_name, ": bad pixel index: ", pindex);
   2708                }
   2709                result = 0;
   2710             }
   2711 
   2712             else if (y >= b->image.colormap_entries)
   2713             {
   2714                if ((b->opts & ACCUMULATE) == 0)
   2715                   {
   2716                   char pindex[9];
   2717                   sprintf(pindex, "%lu[%lu]", (unsigned long)y,
   2718                      (unsigned long)b->image.colormap_entries);
   2719                   logerror(b, b->file_name, ": bad pixel index: ", pindex);
   2720                   }
   2721                result = 0;
   2722             }
   2723 
   2724             /* All the mismatches are logged here; there can only be 256! */
   2725             else if (!cmppixel(&tr, a_cmap, b_cmap, 0, y))
   2726                result = 0;
   2727          }
   2728 
   2729          /* If reqested copy the error values back from the Transform. */
   2730          if (a->opts & ACCUMULATE)
   2731          {
   2732             tr.error_ptr[0] = tr.error[0];
   2733             tr.error_ptr[1] = tr.error[1];
   2734             tr.error_ptr[2] = tr.error[2];
   2735             tr.error_ptr[3] = tr.error[3];
   2736             result = 1; /* force a continue */
   2737          }
   2738 
   2739          return result;
   2740       }
   2741 
   2742       /* else the image buffers don't match pixel-wise so compare sample values
   2743        * instead, but first validate that the pixel indexes are in range (but
   2744        * only if not accumulating, when the error is ignored.)
   2745        */
   2746       else if ((a->opts & ACCUMULATE) == 0)
   2747       {
   2748 #        ifdef __GNUC__
   2749 #           define BYTE_CHARS 20 /* 2^32: GCC sprintf warning */
   2750 #        else
   2751 #           define BYTE_CHARS 3 /* 2^8: real maximum value */
   2752 #        endif
   2753          /* Check the original image first,
   2754           * TODO: deal with input images with bad pixel values?
   2755           */
   2756          if (amax >= a->image.colormap_entries)
   2757          {
   2758             char pindex[3+2*BYTE_CHARS];
   2759             sprintf(pindex, "%d[%u]", amax,
   2760                (png_byte)/*SAFE*/a->image.colormap_entries);
   2761             return logerror(a, a->file_name, ": bad pixel index: ", pindex);
   2762          }
   2763 
   2764          else if (bmax >= b->image.colormap_entries)
   2765          {
   2766             char pindex[3+2*BYTE_CHARS];
   2767             sprintf(pindex, "%d[%u]", bmax,
   2768                (png_byte)/*SAFE*/b->image.colormap_entries);
   2769             return logerror(b, b->file_name, ": bad pixel index: ", pindex);
   2770          }
   2771       }
   2772    }
   2773 
   2774    /* We can directly compare pixel values without the need to use the read
   2775     * or transform support (i.e. a memory compare) if:
   2776     *
   2777     * 1) The bit depth has not changed.
   2778     * 2) RGB to grayscale has not been done (the reverse is ok; we just compare
   2779     *    the three RGB values to the original grayscale.)
   2780     * 3) An alpha channel has not been removed from an 8-bit format, or the
   2781     *    8-bit alpha value of the pixel was 255 (opaque).
   2782     *
   2783     * If an alpha channel has been *added* then it must have the relevant opaque
   2784     * value (255 or 65535).
   2785     *
   2786     * The fist two the tests (in the order given above) (using the boolean
   2787     * equivalence !a && !b == !(a || b))
   2788     */
   2789    if (!(((formata ^ formatb) & PNG_FORMAT_FLAG_LINEAR) |
   2790       (formata & (formatb ^ PNG_FORMAT_FLAG_COLOR) & PNG_FORMAT_FLAG_COLOR)))
   2791    {
   2792       /* Was an alpha channel changed? */
   2793       const png_uint_32 alpha_changed = (formata ^ formatb) &
   2794          PNG_FORMAT_FLAG_ALPHA;
   2795 
   2796       /* Was an alpha channel removed?  (The third test.)  If so the direct
   2797        * comparison is only possible if the input alpha is opaque.
   2798        */
   2799       alpha_removed = (formata & alpha_changed) != 0;
   2800 
   2801       /* Was an alpha channel added? */
   2802       alpha_added = (formatb & alpha_changed) != 0;
   2803 
   2804       /* The channels may have been moved between input and output, this finds
   2805        * out how, recording the result in the btoa array, which says where in
   2806        * 'a' to find each channel of 'b'.  If alpha was added then btoa[alpha]
   2807        * ends up as 4 (and is not used.)
   2808        */
   2809       {
   2810          int i;
   2811          png_byte aloc[4];
   2812          png_byte bloc[4];
   2813 
   2814          /* The following are used only if the formats match, except that
   2815           * 'bchannels' is a flag for matching formats.  btoa[x] says, for each
   2816           * channel in b, where to find the corresponding value in a, for the
   2817           * bchannels.  achannels may be different for a gray to rgb transform
   2818           * (a will be 1 or 2, b will be 3 or 4 channels.)
   2819           */
   2820          (void)component_loc(aloc, formata);
   2821          bchannels = component_loc(bloc, formatb);
   2822 
   2823          /* Hence the btoa array. */
   2824          for (i=0; i<4; ++i) if (bloc[i] < 4)
   2825             btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */
   2826 
   2827          if (alpha_added)
   2828             alpha_added = bloc[0]; /* location of alpha channel in image b */
   2829 
   2830          else
   2831             alpha_added = 4; /* Won't match an image b channel */
   2832 
   2833          if (alpha_removed)
   2834             alpha_removed = aloc[0]; /* location of alpha channel in image a */
   2835 
   2836          else
   2837             alpha_removed = 4;
   2838       }
   2839    }
   2840 
   2841    else
   2842    {
   2843       /* Direct compare is not possible, cancel out all the corresponding local
   2844        * variables.
   2845        */
   2846       bchannels = 0;
   2847       alpha_removed = alpha_added = 4;
   2848       btoa[3] = btoa[2] = btoa[1] = btoa[0] = 4; /* 4 == not present */
   2849    }
   2850 
   2851    for (y=0; y<height; ++y, rowa += stridea, rowb += strideb)
   2852    {
   2853       png_const_bytep ppa, ppb;
   2854       png_uint_32 x;
   2855 
   2856       for (x=0, ppa=rowa, ppb=rowb; x<width; ++x)
   2857       {
   2858          png_const_bytep psa, psb;
   2859 
   2860          if (formata & PNG_FORMAT_FLAG_COLORMAP)
   2861             psa = (png_const_bytep)a->colormap + a_sample * *ppa++;
   2862          else
   2863             psa = ppa, ppa += a_sample;
   2864 
   2865          if (formatb & PNG_FORMAT_FLAG_COLORMAP)
   2866             psb = (png_const_bytep)b->colormap + b_sample * *ppb++;
   2867          else
   2868             psb = ppb, ppb += b_sample;
   2869 
   2870          /* Do the fast test if possible. */
   2871          if (bchannels)
   2872          {
   2873             /* Check each 'b' channel against either the corresponding 'a'
   2874              * channel or the opaque alpha value, as appropriate.  If
   2875              * alpha_removed value is set (not 4) then also do this only if the
   2876              * 'a' alpha channel (alpha_removed) is opaque; only relevant for
   2877              * the 8-bit case.
   2878              */
   2879             if (formatb & PNG_FORMAT_FLAG_LINEAR) /* 16-bit checks */
   2880             {
   2881                png_const_uint_16p pua = aligncastconst(png_const_uint_16p, psa);
   2882                png_const_uint_16p pub = aligncastconst(png_const_uint_16p, psb);
   2883 
   2884                switch (bchannels)
   2885                {
   2886                   case 4:
   2887                      if (pua[btoa[3]] != pub[3]) break;
   2888                      /* FALLTHROUGH */
   2889                   case 3:
   2890                      if (pua[btoa[2]] != pub[2]) break;
   2891                      /* FALLTHROUGH */
   2892                   case 2:
   2893                      if (pua[btoa[1]] != pub[1]) break;
   2894                      /* FALLTHROUGH */
   2895                   case 1:
   2896                      if (pua[btoa[0]] != pub[0]) break;
   2897                      if (alpha_added != 4 && pub[alpha_added] != 65535) break;
   2898                      continue; /* x loop */
   2899                   default:
   2900                      break; /* impossible */
   2901                }
   2902             }
   2903 
   2904             else if (alpha_removed == 4 || psa[alpha_removed] == 255)
   2905             {
   2906                switch (bchannels)
   2907                {
   2908                   case 4:
   2909                      if (psa[btoa[3]] != psb[3]) break;
   2910                      /* FALLTHROUGH */
   2911                   case 3:
   2912                      if (psa[btoa[2]] != psb[2]) break;
   2913                      /* FALLTHROUGH */
   2914                   case 2:
   2915                      if (psa[btoa[1]] != psb[1]) break;
   2916                      /* FALLTHROUGH */
   2917                   case 1:
   2918                      if (psa[btoa[0]] != psb[0]) break;
   2919                      if (alpha_added != 4 && psb[alpha_added] != 255) break;
   2920                      continue; /* x loop */
   2921                   default:
   2922                      break; /* impossible */
   2923                }
   2924             }
   2925          }
   2926 
   2927          /* If we get to here the fast match failed; do the slow match for this
   2928           * pixel.
   2929           */
   2930          if (!cmppixel(&tr, psa, psb, x, y) && (a->opts & KEEP_GOING) == 0)
   2931             return 0; /* error case */
   2932       }
   2933    }
   2934 
   2935    /* If reqested copy the error values back from the Transform. */
   2936    if (a->opts & ACCUMULATE)
   2937    {
   2938       tr.error_ptr[0] = tr.error[0];
   2939       tr.error_ptr[1] = tr.error[1];
   2940       tr.error_ptr[2] = tr.error[2];
   2941       tr.error_ptr[3] = tr.error[3];
   2942    }
   2943 
   2944    return 1;
   2945 }
   2946 
   2947 /* Read the file; how the read gets done depends on which of input_file and
   2948  * input_memory have been set.
   2949  */
   2950 static int
   2951 read_file(Image *image, png_uint_32 format, png_const_colorp background)
   2952 {
   2953    memset(&image->image, 0, sizeof image->image);
   2954    image->image.version = PNG_IMAGE_VERSION;
   2955 
   2956    if (image->input_memory != NULL)
   2957    {
   2958       if (!png_image_begin_read_from_memory(&image->image, image->input_memory,
   2959          image->input_memory_size))
   2960          return logerror(image, "memory init: ", image->file_name, "");
   2961    }
   2962 
   2963 #  ifdef PNG_STDIO_SUPPORTED
   2964       else if (image->input_file != NULL)
   2965       {
   2966          if (!png_image_begin_read_from_stdio(&image->image, image->input_file))
   2967             return logerror(image, "stdio init: ", image->file_name, "");
   2968       }
   2969 
   2970       else
   2971       {
   2972          if (!png_image_begin_read_from_file(&image->image, image->file_name))
   2973             return logerror(image, "file init: ", image->file_name, "");
   2974       }
   2975 #  else
   2976       else
   2977       {
   2978          return logerror(image, "unsupported file/stdio init: ",
   2979             image->file_name, "");
   2980       }
   2981 #  endif
   2982 
   2983    /* This must be set after the begin_read call: */
   2984    if (image->opts & sRGB_16BIT)
   2985       image->image.flags |= PNG_IMAGE_FLAG_16BIT_sRGB;
   2986 
   2987    /* Have an initialized image with all the data we need plus, maybe, an
   2988     * allocated file (myfile) or buffer (mybuffer) that need to be freed.
   2989     */
   2990    {
   2991       int result;
   2992       png_uint_32 image_format;
   2993 
   2994       /* Print both original and output formats. */
   2995       image_format = image->image.format;
   2996 
   2997       if (image->opts & VERBOSE)
   2998       {
   2999          printf("%s %lu x %lu %s -> %s", image->file_name,
   3000             (unsigned long)image->image.width,
   3001             (unsigned long)image->image.height,
   3002             format_names[image_format & FORMAT_MASK],
   3003             (format & FORMAT_NO_CHANGE) != 0 || image->image.format == format
   3004             ? "no change" : format_names[format & FORMAT_MASK]);
   3005 
   3006          if (background != NULL)
   3007             printf(" background(%d,%d,%d)\n", background->red,
   3008                background->green, background->blue);
   3009          else
   3010             printf("\n");
   3011 
   3012          fflush(stdout);
   3013       }
   3014 
   3015       /* 'NO_CHANGE' combined with the color-map flag forces the base format
   3016        * flags to be set on read to ensure that the original representation is
   3017        * not lost in the pass through a colormap format.
   3018        */
   3019       if ((format & FORMAT_NO_CHANGE) != 0)
   3020       {
   3021          if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
   3022             (image_format & PNG_FORMAT_FLAG_COLORMAP) != 0)
   3023             format = (image_format & ~BASE_FORMATS) | (format & BASE_FORMATS);
   3024 
   3025          else
   3026             format = image_format;
   3027       }
   3028 
   3029       image->image.format = format;
   3030 
   3031       image->stride = PNG_IMAGE_ROW_STRIDE(image->image) + image->stride_extra;
   3032       allocbuffer(image);
   3033 
   3034       result = png_image_finish_read(&image->image, background,
   3035          image->buffer+16, (png_int_32)image->stride, image->colormap);
   3036 
   3037       checkbuffer(image, image->file_name);
   3038 
   3039       if (result)
   3040          return checkopaque(image);
   3041 
   3042       else
   3043          return logerror(image, image->file_name, ": image read failed", "");
   3044    }
   3045 }
   3046 
   3047 /* Reads from a filename, which must be in image->file_name, but uses
   3048  * image->opts to choose the method.  The file is always read in its native
   3049  * format (the one the simplified API suggests).
   3050  */
   3051 static int
   3052 read_one_file(Image *image)
   3053 {
   3054    if (!(image->opts & USE_FILE) || (image->opts & USE_STDIO))
   3055    {
   3056       /* memory or stdio. */
   3057       FILE *f = fopen(image->file_name, "rb");
   3058 
   3059       if (f != NULL)
   3060       {
   3061          if (image->opts & USE_FILE)
   3062             image->input_file = f;
   3063 
   3064          else /* memory */
   3065          {
   3066             if (fseek(f, 0, SEEK_END) == 0)
   3067             {
   3068                long int cb = ftell(f);
   3069 
   3070                if (cb > 0)
   3071                {
   3072 #ifndef __COVERITY__
   3073                   if ((unsigned long int)cb <= (size_t)~(size_t)0)
   3074 #endif
   3075                   {
   3076                      png_bytep b = voidcast(png_bytep, malloc((size_t)cb));
   3077 
   3078                      if (b != NULL)
   3079                      {
   3080                         rewind(f);
   3081 
   3082                         if (fread(b, (size_t)cb, 1, f) == 1)
   3083                         {
   3084                            fclose(f);
   3085                            image->input_memory_size = cb;
   3086                            image->input_memory = b;
   3087                         }
   3088 
   3089                         else
   3090                         {
   3091                            free(b);
   3092                            return logclose(image, f, image->file_name,
   3093                               ": read failed: ");
   3094                         }
   3095                      }
   3096 
   3097                      else
   3098                         return logclose(image, f, image->file_name,
   3099                            ": out of memory: ");
   3100                   }
   3101 
   3102                   else
   3103                      return logclose(image, f, image->file_name,
   3104                         ": file too big for this architecture: ");
   3105                      /* cb is the length of the file as a (long) and
   3106                       * this is greater than the maximum amount of
   3107                       * memory that can be requested from malloc.
   3108                       */
   3109                }
   3110 
   3111                else if (cb == 0)
   3112                   return logclose(image, f, image->file_name,
   3113                      ": zero length: ");
   3114 
   3115                else
   3116                   return logclose(image, f, image->file_name,
   3117                      ": tell failed: ");
   3118             }
   3119 
   3120             else
   3121                return logclose(image, f, image->file_name, ": seek failed: ");
   3122          }
   3123       }
   3124 
   3125       else
   3126          return logerror(image, image->file_name, ": open failed: ",
   3127             strerror(errno));
   3128    }
   3129 
   3130    return read_file(image, FORMAT_NO_CHANGE, NULL);
   3131 }
   3132 
   3133 #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
   3134 static int
   3135 write_one_file(Image *output, Image *image, int convert_to_8bit)
   3136 {
   3137    if (image->opts & FAST_WRITE)
   3138       image->image.flags |= PNG_IMAGE_FLAG_FAST;
   3139 
   3140    if (image->opts & USE_STDIO)
   3141    {
   3142 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
   3143 #ifndef __COVERITY__
   3144       FILE *f = tmpfile();
   3145 #else
   3146       /* Experimental. Coverity says tmpfile() is insecure because it
   3147        * generates predictable names.
   3148        *
   3149        * It is possible to satisfy Coverity by using mkstemp(); however,
   3150        * any platform supporting mkstemp() undoubtedly has a secure tmpfile()
   3151        * implementation as well, and doesn't need the fix.  Note that
   3152        * the fix won't work on platforms that don't support mkstemp().
   3153        *
   3154        * https://www.securecoding.cert.org/confluence/display/c/
   3155        * FIO21-C.+Do+not+create+temporary+files+in+shared+directories
   3156        * says that most historic implementations of tmpfile() provide
   3157        * only a limited number of possible temporary file names
   3158        * (usually 26) before file names are recycled. That article also
   3159        * provides a secure solution that unfortunately depends upon mkstemp().
   3160        */
   3161       char tmpfile[] = "pngstest-XXXXXX";
   3162       int filedes;
   3163       FILE *f;
   3164       umask(0177);
   3165       filedes = mkstemp(tmpfile);
   3166       if (filedes < 0)
   3167         f = NULL;
   3168       else
   3169       {
   3170         f = fdopen(filedes,"w+");
   3171         /* Hide the filename immediately and ensure that the file does
   3172          * not exist after the program ends
   3173          */
   3174         (void) unlink(tmpfile);
   3175       }
   3176 #endif
   3177 
   3178       if (f != NULL)
   3179       {
   3180          if (png_image_write_to_stdio(&image->image, f, convert_to_8bit,
   3181             image->buffer+16, (png_int_32)image->stride, image->colormap))
   3182          {
   3183             if (fflush(f) == 0)
   3184             {
   3185                rewind(f);
   3186                initimage(output, image->opts, "tmpfile", image->stride_extra);
   3187                output->input_file = f;
   3188                if (!checkopaque(image))
   3189                   return 0;
   3190             }
   3191 
   3192             else
   3193                return logclose(image, f, "tmpfile", ": flush: ");
   3194          }
   3195 
   3196          else
   3197          {
   3198             fclose(f);
   3199             return logerror(image, "tmpfile", ": write failed", "");
   3200          }
   3201       }
   3202 
   3203       else
   3204          return logerror(image, "tmpfile", ": open: ", strerror(errno));
   3205 #else /* SIMPLIFIED_WRITE_STDIO */
   3206       return logerror(image, "tmpfile", ": open: unsupported", "");
   3207 #endif /* SIMPLIFIED_WRITE_STDIO */
   3208    }
   3209 
   3210    else if (image->opts & USE_FILE)
   3211    {
   3212 #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
   3213       static int counter = 0;
   3214       char name[32];
   3215 
   3216       sprintf(name, "%s%d.png", tmpf, ++counter);
   3217 
   3218       if (png_image_write_to_file(&image->image, name, convert_to_8bit,
   3219          image->buffer+16, (png_int_32)image->stride, image->colormap))
   3220       {
   3221          initimage(output, image->opts, output->tmpfile_name,
   3222             image->stride_extra);
   3223          /* Afterwards, or freeimage will delete it! */
   3224          strcpy(output->tmpfile_name, name);
   3225 
   3226          if (!checkopaque(image))
   3227             return 0;
   3228       }
   3229 
   3230       else
   3231          return logerror(image, name, ": write failed", "");
   3232 #else /* SIMPLIFIED_WRITE_STDIO */
   3233       return logerror(image, "stdio", ": open: unsupported", "");
   3234 #endif /* SIMPLIFIED_WRITE_STDIO */
   3235    }
   3236 
   3237    else /* use memory */
   3238    {
   3239       png_alloc_size_t size;
   3240 
   3241       if (png_image_write_get_memory_size(image->image, size, convert_to_8bit,
   3242                image->buffer+16, (png_int_32)image->stride, image->colormap))
   3243       {
   3244          /* This is non-fatal but ignoring it was causing serious problems in
   3245           * the macro to be ignored:
   3246           */
   3247          if (size > PNG_IMAGE_PNG_SIZE_MAX(image->image))
   3248             return logerror(image, "memory", ": PNG_IMAGE_SIZE_MAX wrong", "");
   3249 
   3250          initimage(output, image->opts, "memory", image->stride_extra);
   3251          output->input_memory = malloc(size);
   3252 
   3253          if (output->input_memory != NULL)
   3254          {
   3255             output->input_memory_size = size;
   3256 
   3257             if (png_image_write_to_memory(&image->image, output->input_memory,
   3258                   &output->input_memory_size, convert_to_8bit, image->buffer+16,
   3259                   (png_int_32)image->stride, image->colormap))
   3260             {
   3261                /* This is also non-fatal but it safes safer to error out anyway:
   3262                 */
   3263                if (size != output->input_memory_size)
   3264                   return logerror(image, "memory", ": memory size wrong", "");
   3265             }
   3266 
   3267             else
   3268                return logerror(image, "memory", ": write failed", "");
   3269          }
   3270 
   3271          else
   3272             return logerror(image, "memory", ": out of memory", "");
   3273       }
   3274 
   3275       else
   3276          return logerror(image, "memory", ": get size:", "");
   3277    }
   3278 
   3279    /* 'output' has an initialized temporary image, read this back in and compare
   3280     * this against the original: there should be no change since the original
   3281     * format was written unmodified unless 'convert_to_8bit' was specified.
   3282     * However, if the original image was color-mapped, a simple read will zap
   3283     * the linear, color and maybe alpha flags, this will cause spurious failures
   3284     * under some circumstances.
   3285     */
   3286    if (read_file(output, image->image.format | FORMAT_NO_CHANGE, NULL))
   3287    {
   3288       png_uint_32 original_format = image->image.format;
   3289 
   3290       if (convert_to_8bit)
   3291          original_format &= ~PNG_FORMAT_FLAG_LINEAR;
   3292 
   3293       if ((output->image.format & BASE_FORMATS) !=
   3294          (original_format & BASE_FORMATS))
   3295          return logerror(image, image->file_name, ": format changed on read: ",
   3296             output->file_name);
   3297 
   3298       return compare_two_images(image, output, 0/*via linear*/, NULL);
   3299    }
   3300 
   3301    else
   3302       return logerror(output, output->tmpfile_name,
   3303          ": read of new file failed", "");
   3304 }
   3305 #endif
   3306 
   3307 static int
   3308 testimage(Image *image, png_uint_32 opts, format_list *pf)
   3309 {
   3310    int result;
   3311    Image copy;
   3312 
   3313    /* Copy the original data, stealing it from 'image' */
   3314    checkopaque(image);
   3315    copy = *image;
   3316 
   3317    copy.opts = opts;
   3318    copy.buffer = NULL;
   3319    copy.bufsize = 0;
   3320    copy.allocsize = 0;
   3321 
   3322    image->input_file = NULL;
   3323    image->input_memory = NULL;
   3324    image->input_memory_size = 0;
   3325    image->tmpfile_name[0] = 0;
   3326 
   3327    {
   3328       png_uint_32 counter;
   3329       Image output;
   3330 
   3331       newimage(&output);
   3332 
   3333       result = 1;
   3334 
   3335       /* Use the low bit of 'counter' to indicate whether or not to do alpha
   3336        * removal with a background color or by composting onto the image; this
   3337        * step gets skipped if it isn't relevant
   3338        */
   3339       for (counter=0; counter<2*FORMAT_COUNT; ++counter)
   3340          if (format_isset(pf, counter >> 1))
   3341       {
   3342          png_uint_32 format = counter >> 1;
   3343 
   3344          png_color background_color;
   3345          png_colorp background = NULL;
   3346 
   3347          /* If there is a format change that removes the alpha channel then
   3348           * the background is relevant.  If the output is 8-bit color-mapped
   3349           * then a background color *must* be provided, otherwise there are
   3350           * two tests to do - one with a color, the other with NULL.  The
   3351           * NULL test happens second.
   3352           */
   3353          if ((counter & 1) == 0)
   3354          {
   3355             if ((format & PNG_FORMAT_FLAG_ALPHA) == 0 &&
   3356                (image->image.format & PNG_FORMAT_FLAG_ALPHA) != 0)
   3357             {
   3358                /* Alpha/transparency will be removed, the background is
   3359                 * relevant: make it a color the first time
   3360                 */
   3361                random_color(&background_color);
   3362                background = &background_color;
   3363 
   3364                /* BUT if the output is to a color-mapped 8-bit format then
   3365                 * the background must always be a color, so increment 'counter'
   3366                 * to skip the NULL test.
   3367                 */
   3368                if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 &&
   3369                   (format & PNG_FORMAT_FLAG_LINEAR) == 0)
   3370                   ++counter;
   3371             }
   3372 
   3373             /* Otherwise an alpha channel is not being eliminated, just leave
   3374              * background NULL and skip the (counter & 1) NULL test.
   3375              */
   3376             else
   3377                ++counter;
   3378          }
   3379          /* else just use NULL for background */
   3380 
   3381          resetimage(&copy);
   3382          copy.opts = opts; /* in case read_file needs to change it */
   3383 
   3384          result = read_file(&copy, format, background);
   3385          if (!result)
   3386             break;
   3387 
   3388          /* Make sure the file just read matches the original file. */
   3389          result = compare_two_images(image, &copy, 0/*via linear*/, background);
   3390          if (!result)
   3391             break;
   3392 
   3393 #        ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
   3394             /* Write the *copy* just made to a new file to make sure the write
   3395              * side works ok.  Check the conversion to sRGB if the copy is
   3396              * linear.
   3397              */
   3398             output.opts = opts;
   3399             result = write_one_file(&output, &copy, 0/*convert to 8bit*/);
   3400             if (!result)
   3401                break;
   3402 
   3403             /* Validate against the original too; the background is needed here
   3404              * as well so that compare_two_images knows what color was used.
   3405              */
   3406             result = compare_two_images(image, &output, 0, background);
   3407             if (!result)
   3408                break;
   3409 
   3410             if ((format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
   3411                (format & PNG_FORMAT_FLAG_COLORMAP) == 0)
   3412             {
   3413                /* 'output' is linear, convert to the corresponding sRGB format.
   3414                 */
   3415                output.opts = opts;
   3416                result = write_one_file(&output, &copy, 1/*convert to 8bit*/);
   3417                if (!result)
   3418                   break;
   3419 
   3420                /* This may involve a conversion via linear; in the ideal world
   3421                 * this would round-trip correctly, but libpng 1.5.7 is not the
   3422                 * ideal world so allow a drift (error_via_linear).
   3423                 *
   3424                 * 'image' has an alpha channel but 'output' does not then there
   3425                 * will a strip-alpha-channel operation (because 'output' is
   3426                 * linear), handle this by composing on black when doing the
   3427                 * comparison.
   3428                 */
   3429                result = compare_two_images(image, &output, 1/*via_linear*/,
   3430                   background);
   3431                if (!result)
   3432                   break;
   3433             }
   3434 #        endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */
   3435       }
   3436 
   3437       freeimage(&output);
   3438    }
   3439 
   3440    freeimage(&copy);
   3441 
   3442    return result;
   3443 }
   3444 
   3445 static int
   3446 test_one_file(const char *file_name, format_list *formats, png_uint_32 opts,
   3447    int stride_extra, int log_pass)
   3448 {
   3449    int result;
   3450    Image image;
   3451 
   3452    if (!(opts & NO_RESEED))
   3453       reseed(); /* ensure that the random numbers don't depend on file order */
   3454    newimage(&image);
   3455    initimage(&image, opts, file_name, stride_extra);
   3456    result = read_one_file(&image);
   3457    if (result)
   3458       result = testimage(&image, opts, formats);
   3459    freeimage(&image);
   3460 
   3461    /* Ensure that stderr is flushed into any log file */
   3462    fflush(stderr);
   3463 
   3464    if (log_pass)
   3465    {
   3466       if (result)
   3467          printf("PASS:");
   3468 
   3469       else
   3470          printf("FAIL:");
   3471 
   3472 #     ifndef PNG_SIMPLIFIED_WRITE_SUPPORTED
   3473          printf(" (no write)");
   3474 #     endif
   3475 
   3476       print_opts(opts);
   3477       printf(" %s\n", file_name);
   3478       /* stdout may not be line-buffered if it is piped to a file, so: */
   3479       fflush(stdout);
   3480    }
   3481 
   3482    else if (!result)
   3483       exit(1);
   3484 
   3485    return result;
   3486 }
   3487 
   3488 int
   3489 main(int argc, char **argv)
   3490 {
   3491    png_uint_32 opts = FAST_WRITE | STRICT;
   3492    format_list formats;
   3493    const char *touch = NULL;
   3494    int log_pass = 0;
   3495    int redundant = 0;
   3496    int stride_extra = 0;
   3497    int retval = 0;
   3498    int c;
   3499 
   3500 #if PNG_LIBPNG_VER >= 10700
   3501       /* This error should not exist in 1.7 or later: */
   3502       opts |= GBG_ERROR;
   3503 #endif
   3504 
   3505    init_sRGB_to_d();
   3506 #if 0
   3507    init_error_via_linear();
   3508 #endif
   3509    format_init(&formats);
   3510    reseed(); /* initialize random number seeds */
   3511 
   3512    for (c=1; c<argc; ++c)
   3513    {
   3514       const char *arg = argv[c];
   3515 
   3516       if (strcmp(arg, "--log") == 0)
   3517          log_pass = 1;
   3518       else if (strcmp(arg, "--fresh") == 0)
   3519       {
   3520          memset(gpc_error, 0, sizeof gpc_error);
   3521          memset(gpc_error_via_linear, 0, sizeof gpc_error_via_linear);
   3522       }
   3523       else if (strcmp(arg, "--file") == 0)
   3524 #        ifdef PNG_STDIO_SUPPORTED
   3525             opts |= USE_FILE;
   3526 #        else
   3527             return SKIP; /* skipped: no support */
   3528 #        endif
   3529       else if (strcmp(arg, "--memory") == 0)
   3530          opts &= ~USE_FILE;
   3531       else if (strcmp(arg, "--stdio") == 0)
   3532 #        ifdef PNG_STDIO_SUPPORTED
   3533             opts |= USE_STDIO;
   3534 #        else
   3535             return SKIP; /* skipped: no support */
   3536 #        endif
   3537       else if (strcmp(arg, "--name") == 0)
   3538          opts &= ~USE_STDIO;
   3539       else if (strcmp(arg, "--verbose") == 0)
   3540          opts |= VERBOSE;
   3541       else if (strcmp(arg, "--quiet") == 0)
   3542          opts &= ~VERBOSE;
   3543       else if (strcmp(arg, "--preserve") == 0)
   3544          opts |= KEEP_TMPFILES;
   3545       else if (strcmp(arg, "--nopreserve") == 0)
   3546          opts &= ~KEEP_TMPFILES;
   3547       else if (strcmp(arg, "--keep-going") == 0)
   3548          opts |= KEEP_GOING;
   3549       else if (strcmp(arg, "--fast") == 0)
   3550          opts |= FAST_WRITE;
   3551       else if (strcmp(arg, "--slow") == 0)
   3552          opts &= ~FAST_WRITE;
   3553       else if (strcmp(arg, "--accumulate") == 0)
   3554          opts |= ACCUMULATE;
   3555       else if (strcmp(arg, "--redundant") == 0)
   3556          redundant = 1;
   3557       else if (strcmp(arg, "--stop") == 0)
   3558          opts &= ~KEEP_GOING;
   3559       else if (strcmp(arg, "--strict") == 0)
   3560          opts |= STRICT;
   3561       else if (strcmp(arg, "--nostrict") == 0)
   3562          opts &= ~STRICT;
   3563       else if (strcmp(arg, "--sRGB-16bit") == 0)
   3564          opts |= sRGB_16BIT;
   3565       else if (strcmp(arg, "--linear-16bit") == 0)
   3566          opts &= ~sRGB_16BIT;
   3567       else if (strcmp(arg, "--noreseed") == 0)
   3568          opts |= NO_RESEED;
   3569       else if (strcmp(arg, "--fault-gbg-warning") == 0)
   3570          opts |= GBG_ERROR;
   3571       else if (strcmp(arg, "--tmpfile") == 0)
   3572       {
   3573          if (c+1 < argc)
   3574          {
   3575             if (strlen(argv[++c]) >= sizeof tmpf)
   3576             {
   3577                fflush(stdout);
   3578                fprintf(stderr, "%s: %s is too long for a temp file prefix\n",
   3579                   argv[0], argv[c]);
   3580                exit(99);
   3581             }
   3582 
   3583             /* Safe: checked above */
   3584             strncpy(tmpf, argv[c], sizeof (tmpf)-1);
   3585          }
   3586 
   3587          else
   3588          {
   3589             fflush(stdout);
   3590             fprintf(stderr, "%s: %s requires a temporary file prefix\n",
   3591                argv[0], arg);
   3592             exit(99);
   3593          }
   3594       }
   3595       else if (strcmp(arg, "--touch") == 0)
   3596       {
   3597          if (c+1 < argc)
   3598             touch = argv[++c];
   3599 
   3600          else
   3601          {
   3602             fflush(stdout);
   3603             fprintf(stderr, "%s: %s requires a file name argument\n",
   3604                argv[0], arg);
   3605             exit(99);
   3606          }
   3607       }
   3608       else if (arg[0] == '+')
   3609       {
   3610          png_uint_32 format = formatof(arg+1);
   3611 
   3612          if (format > FORMAT_COUNT)
   3613             exit(99);
   3614 
   3615          format_set(&formats, format);
   3616       }
   3617       else if (arg[0] == '-' && arg[1] != 0 && (arg[1] != '0' || arg[2] != 0))
   3618       {
   3619          fflush(stdout);
   3620          fprintf(stderr, "%s: unknown option: %s\n", argv[0], arg);
   3621          exit(99);
   3622       }
   3623       else
   3624       {
   3625          if (format_is_initial(&formats))
   3626             format_default(&formats, redundant);
   3627 
   3628          if (arg[0] == '-')
   3629          {
   3630             const int term = (arg[1] == '0' ? 0 : '\n');
   3631             unsigned int ich = 0;
   3632 
   3633             /* Loop reading files, use a static buffer to simplify this and just
   3634              * stop if the name gets to long.
   3635              */
   3636             static char buffer[4096];
   3637 
   3638             do
   3639             {
   3640                int ch = getchar();
   3641 
   3642                /* Don't allow '\0' in file names, and terminate with '\n' or,
   3643                 * for -0, just '\0' (use -print0 to find to make this work!)
   3644                 */
   3645                if (ch == EOF || ch == term || ch == 0)
   3646                {
   3647                   buffer[ich] = 0;
   3648 
   3649                   if (ich > 0 && !test_one_file(buffer, &formats, opts,
   3650                      stride_extra, log_pass))
   3651                      retval = 1;
   3652 
   3653                   if (ch == EOF)
   3654                      break;
   3655 
   3656                   ich = 0;
   3657                   --ich; /* so that the increment below sets it to 0 again */
   3658                }
   3659 
   3660                else
   3661                   buffer[ich] = (char)ch;
   3662             } while (++ich < sizeof buffer);
   3663 
   3664             if (ich)
   3665             {
   3666                buffer[32] = 0;
   3667                buffer[4095] = 0;
   3668                fprintf(stderr, "%s...%s: file name too long\n", buffer,
   3669                   buffer+(4096-32));
   3670                exit(99);
   3671             }
   3672          }
   3673 
   3674          else if (!test_one_file(arg, &formats, opts, stride_extra, log_pass))
   3675             retval = 1;
   3676       }
   3677    }
   3678 
   3679    if (opts & ACCUMULATE)
   3680    {
   3681       unsigned int in;
   3682 
   3683       printf("/* contrib/libtests/pngstest-errors.h\n");
   3684       printf(" *\n");
   3685       printf(" * BUILT USING:" PNG_HEADER_VERSION_STRING);
   3686       printf(" *\n");
   3687       printf(" * This code is released under the libpng license.\n");
   3688       printf(" * For conditions of distribution and use, see the disclaimer\n");
   3689       printf(" * and license in png.h\n");
   3690       printf(" *\n");
   3691       printf(" * THIS IS A MACHINE GENERATED FILE: do not edit it directly!\n");
   3692       printf(" * Instead run:\n");
   3693       printf(" *\n");
   3694       printf(" *    pngstest --accumulate\n");
   3695       printf(" *\n");
   3696       printf(" * on as many PNG files as possible; at least PNGSuite and\n");
   3697       printf(" * contrib/libtests/testpngs.\n");
   3698       printf(" */\n");
   3699 
   3700       printf("static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =\n");
   3701       printf("{\n");
   3702       for (in=0; in<16; ++in)
   3703       {
   3704          unsigned int out;
   3705          printf(" { /* input: %s */\n ", format_names[in]);
   3706          for (out=0; out<16; ++out)
   3707          {
   3708             unsigned int alpha;
   3709             printf(" {");
   3710             for (alpha=0; alpha<4; ++alpha)
   3711             {
   3712                printf(" %d", gpc_error[in][out][alpha]);
   3713                if (alpha < 3) putchar(',');
   3714             }
   3715             printf(" }");
   3716             if (out < 15)
   3717             {
   3718                putchar(',');
   3719                if (out % 4 == 3) printf("\n ");
   3720             }
   3721          }
   3722          printf("\n }");
   3723 
   3724          if (in < 15)
   3725             putchar(',');
   3726          else
   3727             putchar('\n');
   3728       }
   3729       printf("};\n");
   3730 
   3731       printf("static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =\n");
   3732       printf("{\n");
   3733       for (in=0; in<16; ++in)
   3734       {
   3735          unsigned int out;
   3736          printf(" { /* input: %s */\n ", format_names[in]);
   3737          for (out=0; out<4; ++out)
   3738          {
   3739             unsigned int alpha;
   3740             printf(" {");
   3741             for (alpha=0; alpha<4; ++alpha)
   3742             {
   3743                printf(" %d", gpc_error_via_linear[in][out][alpha]);
   3744                if (alpha < 3) putchar(',');
   3745             }
   3746             printf(" }");
   3747             if (out < 3)
   3748                putchar(',');
   3749          }
   3750          printf("\n }");
   3751 
   3752          if (in < 15)
   3753             putchar(',');
   3754          else
   3755             putchar('\n');
   3756       }
   3757       printf("};\n");
   3758 
   3759       printf("static png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =\n");
   3760       printf("{\n");
   3761       for (in=0; in<8; ++in)
   3762       {
   3763          unsigned int out;
   3764          printf(" { /* input: %s */\n ", format_names[in]);
   3765          for (out=0; out<8; ++out)
   3766          {
   3767             unsigned int alpha;
   3768             printf(" {");
   3769             for (alpha=0; alpha<4; ++alpha)
   3770             {
   3771                printf(" %d", gpc_error_to_colormap[in][out][alpha]);
   3772                if (alpha < 3) putchar(',');
   3773             }
   3774             printf(" }");
   3775             if (out < 7)
   3776             {
   3777                putchar(',');
   3778                if (out % 4 == 3) printf("\n ");
   3779             }
   3780          }
   3781          printf("\n }");
   3782 
   3783          if (in < 7)
   3784             putchar(',');
   3785          else
   3786             putchar('\n');
   3787       }
   3788       printf("};\n");
   3789       printf("/* END MACHINE GENERATED */\n");
   3790    }
   3791 
   3792    if (retval == 0 && touch != NULL)
   3793    {
   3794       FILE *fsuccess = fopen(touch, "wt");
   3795 
   3796       if (fsuccess != NULL)
   3797       {
   3798          int error = 0;
   3799          fprintf(fsuccess, "PNG simple API tests succeeded\n");
   3800          fflush(fsuccess);
   3801          error = ferror(fsuccess);
   3802 
   3803          if (fclose(fsuccess) || error)
   3804          {
   3805             fflush(stdout);
   3806             fprintf(stderr, "%s: write failed\n", touch);
   3807             exit(99);
   3808          }
   3809       }
   3810 
   3811       else
   3812       {
   3813          fflush(stdout);
   3814          fprintf(stderr, "%s: open failed\n", touch);
   3815          exit(99);
   3816       }
   3817    }
   3818 
   3819    return retval;
   3820 }
   3821 
   3822 #else /* !PNG_SIMPLIFIED_READ_SUPPORTED */
   3823 int main(void)
   3824 {
   3825    fprintf(stderr, "pngstest: no read support in libpng, test skipped\n");
   3826    /* So the test is skipped: */
   3827    return SKIP;
   3828 }
   3829 #endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
   3830