Home | History | Annotate | Download | only in libpng
      1 
      2 /* pngrutil.c - utilities to read a PNG file
      3  *
      4  * Last changed in libpng 1.2.44 [June 26, 2010]
      5  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
      6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      8  *
      9  * This code is released under the libpng license.
     10  * For conditions of distribution and use, see the disclaimer
     11  * and license in png.h
     12  *
     13  * This file contains routines that are only called from within
     14  * libpng itself during the course of reading an image.
     15  */
     16 
     17 #define PNG_INTERNAL
     18 #define PNG_NO_PEDANTIC_WARNINGS
     19 #include "png.h"
     20 #ifdef PNG_READ_SUPPORTED
     21 
     22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
     23 #  define WIN32_WCE_OLD
     24 #endif
     25 
     26 #ifdef PNG_FLOATING_POINT_SUPPORTED
     27 #  ifdef WIN32_WCE_OLD
     28 /* The strtod() function is not supported on WindowsCE */
     29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
     30     char **endptr)
     31 {
     32    double result = 0;
     33    int len;
     34    wchar_t *str, *end;
     35 
     36    len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
     37    str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
     38    if ( NULL != str )
     39    {
     40       MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
     41       result = wcstod(str, &end);
     42       len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
     43       *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
     44       png_free(png_ptr, str);
     45    }
     46    return result;
     47 }
     48 #  else
     49 #    define png_strtod(p,a,b) strtod(a,b)
     50 #  endif
     51 #endif
     52 
     53 png_uint_32 PNGAPI
     54 png_get_uint_31(png_structp png_ptr, png_bytep buf)
     55 {
     56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
     57    png_uint_32 i = png_get_uint_32(buf);
     58 #else
     59    /* Avoid an extra function call by inlining the result. */
     60    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
     61       ((png_uint_32)(*(buf + 1)) << 16) +
     62       ((png_uint_32)(*(buf + 2)) << 8) +
     63       (png_uint_32)(*(buf + 3));
     64 #endif
     65    if (i > PNG_UINT_31_MAX)
     66      png_error(png_ptr, "PNG unsigned integer out of range.");
     67    return (i);
     68 }
     69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
     70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
     71 png_uint_32 PNGAPI
     72 png_get_uint_32(png_bytep buf)
     73 {
     74    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
     75       ((png_uint_32)(*(buf + 1)) << 16) +
     76       ((png_uint_32)(*(buf + 2)) << 8) +
     77       (png_uint_32)(*(buf + 3));
     78 
     79    return (i);
     80 }
     81 
     82 /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
     83  * data is stored in the PNG file in two's complement format, and it is
     84  * assumed that the machine format for signed integers is the same.
     85  */
     86 png_int_32 PNGAPI
     87 png_get_int_32(png_bytep buf)
     88 {
     89    png_int_32 i = ((png_int_32)(*buf) << 24) +
     90       ((png_int_32)(*(buf + 1)) << 16) +
     91       ((png_int_32)(*(buf + 2)) << 8) +
     92       (png_int_32)(*(buf + 3));
     93 
     94    return (i);
     95 }
     96 
     97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
     98 png_uint_16 PNGAPI
     99 png_get_uint_16(png_bytep buf)
    100 {
    101    png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
    102       (png_uint_16)(*(buf + 1)));
    103 
    104    return (i);
    105 }
    106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
    107 
    108 /* Read the chunk header (length + type name).
    109  * Put the type name into png_ptr->chunk_name, and return the length.
    110  */
    111 png_uint_32 /* PRIVATE */
    112 png_read_chunk_header(png_structp png_ptr)
    113 {
    114    png_byte buf[8];
    115    png_uint_32 length;
    116 
    117    /* Read the length and the chunk name */
    118    png_read_data(png_ptr, buf, 8);
    119    length = png_get_uint_31(png_ptr, buf);
    120 
    121    /* Put the chunk name into png_ptr->chunk_name */
    122    png_memcpy(png_ptr->chunk_name, buf + 4, 4);
    123 
    124    png_debug2(0, "Reading %s chunk, length = %lu",
    125       png_ptr->chunk_name, length);
    126 
    127    /* Reset the crc and run it over the chunk name */
    128    png_reset_crc(png_ptr);
    129    png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
    130 
    131    /* Check to see if chunk name is valid */
    132    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    133 
    134    return length;
    135 }
    136 
    137 /* Read data, and (optionally) run it through the CRC. */
    138 void /* PRIVATE */
    139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
    140 {
    141    if (png_ptr == NULL)
    142       return;
    143    png_read_data(png_ptr, buf, length);
    144    png_calculate_crc(png_ptr, buf, length);
    145 }
    146 
    147 /* Optionally skip data and then check the CRC.  Depending on whether we
    148  * are reading a ancillary or critical chunk, and how the program has set
    149  * things up, we may calculate the CRC on the data and print a message.
    150  * Returns '1' if there was a CRC error, '0' otherwise.
    151  */
    152 int /* PRIVATE */
    153 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
    154 {
    155    png_size_t i;
    156    png_size_t istop = png_ptr->zbuf_size;
    157 
    158    for (i = (png_size_t)skip; i > istop; i -= istop)
    159    {
    160       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
    161    }
    162    if (i)
    163    {
    164       png_crc_read(png_ptr, png_ptr->zbuf, i);
    165    }
    166 
    167    if (png_crc_error(png_ptr))
    168    {
    169       if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
    170           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
    171           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
    172           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
    173       {
    174          png_chunk_warning(png_ptr, "CRC error");
    175       }
    176       else
    177       {
    178          png_chunk_error(png_ptr, "CRC error");
    179       }
    180       return (1);
    181    }
    182 
    183    return (0);
    184 }
    185 
    186 /* Compare the CRC stored in the PNG file with that calculated by libpng from
    187  * the data it has read thus far.
    188  */
    189 int /* PRIVATE */
    190 png_crc_error(png_structp png_ptr)
    191 {
    192    png_byte crc_bytes[4];
    193    png_uint_32 crc;
    194    int need_crc = 1;
    195 
    196    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
    197    {
    198       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
    199           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
    200          need_crc = 0;
    201    }
    202    else                                                    /* critical */
    203    {
    204       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
    205          need_crc = 0;
    206    }
    207 
    208    png_read_data(png_ptr, crc_bytes, 4);
    209 
    210    if (need_crc)
    211    {
    212       crc = png_get_uint_32(crc_bytes);
    213       return ((int)(crc != png_ptr->crc));
    214    }
    215    else
    216       return (0);
    217 }
    218 
    219 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
    220     defined(PNG_READ_iCCP_SUPPORTED)
    221 static png_size_t
    222 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
    223         png_bytep output, png_size_t output_size)
    224 {
    225    png_size_t count = 0;
    226 
    227    png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
    228    png_ptr->zstream.avail_in = size;
    229 
    230    while (1)
    231    {
    232       int ret, avail;
    233 
    234       /* Reset the output buffer each time round - we empty it
    235        * after every inflate call.
    236        */
    237       png_ptr->zstream.next_out = png_ptr->zbuf;
    238       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
    239 
    240       ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
    241       avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
    242 
    243       /* First copy/count any new output - but only if we didn't
    244        * get an error code.
    245        */
    246       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
    247       {
    248          if (output != 0 && output_size > count)
    249          {
    250             int copy = output_size - count;
    251             if (avail < copy) copy = avail;
    252             png_memcpy(output + count, png_ptr->zbuf, copy);
    253          }
    254          count += avail;
    255       }
    256 
    257       if (ret == Z_OK)
    258          continue;
    259 
    260       /* Termination conditions - always reset the zstream, it
    261        * must be left in inflateInit state.
    262        */
    263       png_ptr->zstream.avail_in = 0;
    264       inflateReset(&png_ptr->zstream);
    265 
    266       if (ret == Z_STREAM_END)
    267          return count; /* NOTE: may be zero. */
    268 
    269       /* Now handle the error codes - the API always returns 0
    270        * and the error message is dumped into the uncompressed
    271        * buffer if available.
    272        */
    273       {
    274          PNG_CONST char *msg;
    275          if (png_ptr->zstream.msg != 0)
    276             msg = png_ptr->zstream.msg;
    277          else
    278          {
    279 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
    280             char umsg[52];
    281 
    282             switch (ret)
    283             {
    284                case Z_BUF_ERROR:
    285                   msg = "Buffer error in compressed datastream in %s chunk";
    286                   break;
    287                case Z_DATA_ERROR:
    288                   msg = "Data error in compressed datastream in %s chunk";
    289                   break;
    290                default:
    291                   msg = "Incomplete compressed datastream in %s chunk";
    292                   break;
    293             }
    294 
    295             png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
    296             msg = umsg;
    297 #else
    298             msg = "Damaged compressed datastream in chunk other than IDAT";
    299 #endif
    300          }
    301 
    302          png_warning(png_ptr, msg);
    303       }
    304 
    305       /* 0 means an error - notice that this code simple ignores
    306        * zero length compressed chunks as a result.
    307        */
    308       return 0;
    309    }
    310 }
    311 
    312 /*
    313  * Decompress trailing data in a chunk.  The assumption is that chunkdata
    314  * points at an allocated area holding the contents of a chunk with a
    315  * trailing compressed part.  What we get back is an allocated area
    316  * holding the original prefix part and an uncompressed version of the
    317  * trailing part (the malloc area passed in is freed).
    318  */
    319 void /* PRIVATE */
    320 png_decompress_chunk(png_structp png_ptr, int comp_type,
    321     png_size_t chunklength,
    322     png_size_t prefix_size, png_size_t *newlength)
    323 {
    324    /* The caller should guarantee this */
    325    if (prefix_size > chunklength)
    326    {
    327       /* The recovery is to delete the chunk. */
    328       png_warning(png_ptr, "invalid chunklength");
    329       prefix_size = 0; /* To delete everything */
    330    }
    331 
    332    else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
    333    {
    334       png_size_t expanded_size = png_inflate(png_ptr,
    335                 (png_bytep)(png_ptr->chunkdata + prefix_size),
    336                 chunklength - prefix_size,
    337                 0/*output*/, 0/*output size*/);
    338 
    339       /* Now check the limits on this chunk - if the limit fails the
    340        * compressed data will be removed, the prefix will remain.
    341        */
    342 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
    343       if (png_ptr->user_chunk_malloc_max &&
    344           (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
    345 #else
    346 #  ifdef PNG_USER_CHUNK_MALLOC_MAX
    347       if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
    348           prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
    349 #  endif
    350 #endif
    351          png_warning(png_ptr, "Exceeded size limit while expanding chunk");
    352 
    353       /* If the size is zero either there was an error and a message
    354        * has already been output (warning) or the size really is zero
    355        * and we have nothing to do - the code will exit through the
    356        * error case below.
    357        */
    358 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
    359     defined(PNG_USER_CHUNK_MALLOC_MAX)
    360       else
    361 #endif
    362       if (expanded_size > 0)
    363       {
    364          /* Success (maybe) - really uncompress the chunk. */
    365          png_size_t new_size = 0;
    366          png_charp text = png_malloc_warn(png_ptr,
    367                         prefix_size + expanded_size + 1);
    368 
    369          if (text != NULL)
    370          {
    371             png_memcpy(text, png_ptr->chunkdata, prefix_size);
    372             new_size = png_inflate(png_ptr,
    373                 (png_bytep)(png_ptr->chunkdata + prefix_size),
    374                 chunklength - prefix_size,
    375                 (png_bytep)(text + prefix_size), expanded_size);
    376             text[prefix_size + expanded_size] = 0; /* just in case */
    377 
    378             if (new_size == expanded_size)
    379             {
    380                png_free(png_ptr, png_ptr->chunkdata);
    381                png_ptr->chunkdata = text;
    382                *newlength = prefix_size + expanded_size;
    383                return; /* The success return! */
    384             }
    385 
    386             png_warning(png_ptr, "png_inflate logic error");
    387             png_free(png_ptr, text);
    388          }
    389          else
    390           png_warning(png_ptr, "Not enough memory to decompress chunk.");
    391       }
    392    }
    393 
    394    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
    395    {
    396 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
    397       char umsg[50];
    398 
    399       png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
    400           comp_type);
    401       png_warning(png_ptr, umsg);
    402 #else
    403       png_warning(png_ptr, "Unknown zTXt compression type");
    404 #endif
    405 
    406       /* The recovery is to simply drop the data. */
    407    }
    408 
    409    /* Generic error return - leave the prefix, delete the compressed
    410     * data, reallocate the chunkdata to remove the potentially large
    411     * amount of compressed data.
    412     */
    413    {
    414       png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
    415       if (text != NULL)
    416       {
    417          if (prefix_size > 0)
    418             png_memcpy(text, png_ptr->chunkdata, prefix_size);
    419          png_free(png_ptr, png_ptr->chunkdata);
    420          png_ptr->chunkdata = text;
    421 
    422          /* This is an extra zero in the 'uncompressed' part. */
    423          *(png_ptr->chunkdata + prefix_size) = 0x00;
    424       }
    425       /* Ignore a malloc error here - it is safe. */
    426    }
    427 
    428    *newlength = prefix_size;
    429 }
    430 #endif
    431 
    432 /* Read and check the IDHR chunk */
    433 void /* PRIVATE */
    434 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    435 {
    436    png_byte buf[13];
    437    png_uint_32 width, height;
    438    int bit_depth, color_type, compression_type, filter_type;
    439    int interlace_type;
    440 
    441    png_debug(1, "in png_handle_IHDR");
    442 
    443    if (png_ptr->mode & PNG_HAVE_IHDR)
    444       png_error(png_ptr, "Out of place IHDR");
    445 
    446    /* Check the length */
    447    if (length != 13)
    448       png_error(png_ptr, "Invalid IHDR chunk");
    449 
    450    png_ptr->mode |= PNG_HAVE_IHDR;
    451 
    452    png_crc_read(png_ptr, buf, 13);
    453    png_crc_finish(png_ptr, 0);
    454 
    455    width = png_get_uint_31(png_ptr, buf);
    456    height = png_get_uint_31(png_ptr, buf + 4);
    457    bit_depth = buf[8];
    458    color_type = buf[9];
    459    compression_type = buf[10];
    460    filter_type = buf[11];
    461    interlace_type = buf[12];
    462 
    463    /* Set internal variables */
    464    png_ptr->width = width;
    465    png_ptr->height = height;
    466    png_ptr->bit_depth = (png_byte)bit_depth;
    467    png_ptr->interlaced = (png_byte)interlace_type;
    468    png_ptr->color_type = (png_byte)color_type;
    469 #ifdef PNG_MNG_FEATURES_SUPPORTED
    470    png_ptr->filter_type = (png_byte)filter_type;
    471 #endif
    472    png_ptr->compression_type = (png_byte)compression_type;
    473 
    474    /* Find number of channels */
    475    switch (png_ptr->color_type)
    476    {
    477       case PNG_COLOR_TYPE_GRAY:
    478       case PNG_COLOR_TYPE_PALETTE:
    479          png_ptr->channels = 1;
    480          break;
    481 
    482       case PNG_COLOR_TYPE_RGB:
    483          png_ptr->channels = 3;
    484          break;
    485 
    486       case PNG_COLOR_TYPE_GRAY_ALPHA:
    487          png_ptr->channels = 2;
    488          break;
    489 
    490       case PNG_COLOR_TYPE_RGB_ALPHA:
    491          png_ptr->channels = 4;
    492          break;
    493    }
    494 
    495    /* Set up other useful info */
    496    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
    497    png_ptr->channels);
    498    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
    499    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
    500    png_debug1(3, "channels = %d", png_ptr->channels);
    501    png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
    502    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
    503       color_type, interlace_type, compression_type, filter_type);
    504 }
    505 
    506 /* Read and check the palette */
    507 void /* PRIVATE */
    508 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    509 {
    510    png_color palette[PNG_MAX_PALETTE_LENGTH];
    511    int num, i;
    512 #ifdef PNG_POINTER_INDEXING_SUPPORTED
    513    png_colorp pal_ptr;
    514 #endif
    515 
    516    png_debug(1, "in png_handle_PLTE");
    517 
    518    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    519       png_error(png_ptr, "Missing IHDR before PLTE");
    520 
    521    else if (png_ptr->mode & PNG_HAVE_IDAT)
    522    {
    523       png_warning(png_ptr, "Invalid PLTE after IDAT");
    524       png_crc_finish(png_ptr, length);
    525       return;
    526    }
    527 
    528    else if (png_ptr->mode & PNG_HAVE_PLTE)
    529       png_error(png_ptr, "Duplicate PLTE chunk");
    530 
    531    png_ptr->mode |= PNG_HAVE_PLTE;
    532 
    533    if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
    534    {
    535       png_warning(png_ptr,
    536         "Ignoring PLTE chunk in grayscale PNG");
    537       png_crc_finish(png_ptr, length);
    538       return;
    539    }
    540 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
    541    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
    542    {
    543       png_crc_finish(png_ptr, length);
    544       return;
    545    }
    546 #endif
    547 
    548    if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
    549    {
    550       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
    551       {
    552          png_warning(png_ptr, "Invalid palette chunk");
    553          png_crc_finish(png_ptr, length);
    554          return;
    555       }
    556 
    557       else
    558       {
    559          png_error(png_ptr, "Invalid palette chunk");
    560       }
    561    }
    562 
    563    num = (int)length / 3;
    564 
    565 #ifdef PNG_POINTER_INDEXING_SUPPORTED
    566    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
    567    {
    568       png_byte buf[3];
    569 
    570       png_crc_read(png_ptr, buf, 3);
    571       pal_ptr->red = buf[0];
    572       pal_ptr->green = buf[1];
    573       pal_ptr->blue = buf[2];
    574    }
    575 #else
    576    for (i = 0; i < num; i++)
    577    {
    578       png_byte buf[3];
    579 
    580       png_crc_read(png_ptr, buf, 3);
    581       /* Don't depend upon png_color being any order */
    582       palette[i].red = buf[0];
    583       palette[i].green = buf[1];
    584       palette[i].blue = buf[2];
    585    }
    586 #endif
    587 
    588    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
    589     * whatever the normal CRC configuration tells us.  However, if we
    590     * have an RGB image, the PLTE can be considered ancillary, so
    591     * we will act as though it is.
    592     */
    593 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
    594    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    595 #endif
    596    {
    597       png_crc_finish(png_ptr, 0);
    598    }
    599 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
    600    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
    601    {
    602       /* If we don't want to use the data from an ancillary chunk,
    603          we have two options: an error abort, or a warning and we
    604          ignore the data in this chunk (which should be OK, since
    605          it's considered ancillary for a RGB or RGBA image). */
    606       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
    607       {
    608          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
    609          {
    610             png_chunk_error(png_ptr, "CRC error");
    611          }
    612          else
    613          {
    614             png_chunk_warning(png_ptr, "CRC error");
    615             return;
    616          }
    617       }
    618       /* Otherwise, we (optionally) emit a warning and use the chunk. */
    619       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
    620       {
    621          png_chunk_warning(png_ptr, "CRC error");
    622       }
    623    }
    624 #endif
    625 
    626    png_set_PLTE(png_ptr, info_ptr, palette, num);
    627 
    628 #ifdef PNG_READ_tRNS_SUPPORTED
    629    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    630    {
    631       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
    632       {
    633          if (png_ptr->num_trans > (png_uint_16)num)
    634          {
    635             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
    636             png_ptr->num_trans = (png_uint_16)num;
    637          }
    638          if (info_ptr->num_trans > (png_uint_16)num)
    639          {
    640             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
    641             info_ptr->num_trans = (png_uint_16)num;
    642          }
    643       }
    644    }
    645 #endif
    646 
    647 }
    648 
    649 void /* PRIVATE */
    650 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    651 {
    652    png_debug(1, "in png_handle_IEND");
    653 
    654    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
    655    {
    656       png_error(png_ptr, "No image in file");
    657    }
    658 
    659    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
    660 
    661    if (length != 0)
    662    {
    663       png_warning(png_ptr, "Incorrect IEND chunk length");
    664    }
    665    png_crc_finish(png_ptr, length);
    666 
    667    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
    668 }
    669 
    670 #ifdef PNG_READ_gAMA_SUPPORTED
    671 void /* PRIVATE */
    672 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    673 {
    674    png_fixed_point igamma;
    675 #ifdef PNG_FLOATING_POINT_SUPPORTED
    676    float file_gamma;
    677 #endif
    678    png_byte buf[4];
    679 
    680    png_debug(1, "in png_handle_gAMA");
    681 
    682    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    683       png_error(png_ptr, "Missing IHDR before gAMA");
    684    else if (png_ptr->mode & PNG_HAVE_IDAT)
    685    {
    686       png_warning(png_ptr, "Invalid gAMA after IDAT");
    687       png_crc_finish(png_ptr, length);
    688       return;
    689    }
    690    else if (png_ptr->mode & PNG_HAVE_PLTE)
    691       /* Should be an error, but we can cope with it */
    692       png_warning(png_ptr, "Out of place gAMA chunk");
    693 
    694    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
    695 #ifdef PNG_READ_sRGB_SUPPORTED
    696       && !(info_ptr->valid & PNG_INFO_sRGB)
    697 #endif
    698       )
    699    {
    700       png_warning(png_ptr, "Duplicate gAMA chunk");
    701       png_crc_finish(png_ptr, length);
    702       return;
    703    }
    704 
    705    if (length != 4)
    706    {
    707       png_warning(png_ptr, "Incorrect gAMA chunk length");
    708       png_crc_finish(png_ptr, length);
    709       return;
    710    }
    711 
    712    png_crc_read(png_ptr, buf, 4);
    713    if (png_crc_finish(png_ptr, 0))
    714       return;
    715 
    716    igamma = (png_fixed_point)png_get_uint_32(buf);
    717    /* Check for zero gamma */
    718    if (igamma == 0)
    719       {
    720          png_warning(png_ptr,
    721            "Ignoring gAMA chunk with gamma=0");
    722          return;
    723       }
    724 
    725 #ifdef PNG_READ_sRGB_SUPPORTED
    726    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
    727       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
    728       {
    729          png_warning(png_ptr,
    730            "Ignoring incorrect gAMA value when sRGB is also present");
    731 #ifdef PNG_CONSOLE_IO_SUPPORTED
    732          fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
    733 #endif
    734          return;
    735       }
    736 #endif /* PNG_READ_sRGB_SUPPORTED */
    737 
    738 #ifdef PNG_FLOATING_POINT_SUPPORTED
    739    file_gamma = (float)igamma / (float)100000.0;
    740 #  ifdef PNG_READ_GAMMA_SUPPORTED
    741      png_ptr->gamma = file_gamma;
    742 #  endif
    743      png_set_gAMA(png_ptr, info_ptr, file_gamma);
    744 #endif
    745 #ifdef PNG_FIXED_POINT_SUPPORTED
    746    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
    747 #endif
    748 }
    749 #endif
    750 
    751 #ifdef PNG_READ_sBIT_SUPPORTED
    752 void /* PRIVATE */
    753 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    754 {
    755    png_size_t truelen;
    756    png_byte buf[4];
    757 
    758    png_debug(1, "in png_handle_sBIT");
    759 
    760    buf[0] = buf[1] = buf[2] = buf[3] = 0;
    761 
    762    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    763       png_error(png_ptr, "Missing IHDR before sBIT");
    764    else if (png_ptr->mode & PNG_HAVE_IDAT)
    765    {
    766       png_warning(png_ptr, "Invalid sBIT after IDAT");
    767       png_crc_finish(png_ptr, length);
    768       return;
    769    }
    770    else if (png_ptr->mode & PNG_HAVE_PLTE)
    771    {
    772       /* Should be an error, but we can cope with it */
    773       png_warning(png_ptr, "Out of place sBIT chunk");
    774    }
    775    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
    776    {
    777       png_warning(png_ptr, "Duplicate sBIT chunk");
    778       png_crc_finish(png_ptr, length);
    779       return;
    780    }
    781 
    782    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    783       truelen = 3;
    784    else
    785       truelen = (png_size_t)png_ptr->channels;
    786 
    787    if (length != truelen || length > 4)
    788    {
    789       png_warning(png_ptr, "Incorrect sBIT chunk length");
    790       png_crc_finish(png_ptr, length);
    791       return;
    792    }
    793 
    794    png_crc_read(png_ptr, buf, truelen);
    795    if (png_crc_finish(png_ptr, 0))
    796       return;
    797 
    798    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
    799    {
    800       png_ptr->sig_bit.red = buf[0];
    801       png_ptr->sig_bit.green = buf[1];
    802       png_ptr->sig_bit.blue = buf[2];
    803       png_ptr->sig_bit.alpha = buf[3];
    804    }
    805    else
    806    {
    807       png_ptr->sig_bit.gray = buf[0];
    808       png_ptr->sig_bit.red = buf[0];
    809       png_ptr->sig_bit.green = buf[0];
    810       png_ptr->sig_bit.blue = buf[0];
    811       png_ptr->sig_bit.alpha = buf[1];
    812    }
    813    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
    814 }
    815 #endif
    816 
    817 #ifdef PNG_READ_cHRM_SUPPORTED
    818 void /* PRIVATE */
    819 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    820 {
    821    png_byte buf[32];
    822 #ifdef PNG_FLOATING_POINT_SUPPORTED
    823    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
    824 #endif
    825    png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
    826       int_y_green, int_x_blue, int_y_blue;
    827 
    828    png_uint_32 uint_x, uint_y;
    829 
    830    png_debug(1, "in png_handle_cHRM");
    831 
    832    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    833       png_error(png_ptr, "Missing IHDR before cHRM");
    834    else if (png_ptr->mode & PNG_HAVE_IDAT)
    835    {
    836       png_warning(png_ptr, "Invalid cHRM after IDAT");
    837       png_crc_finish(png_ptr, length);
    838       return;
    839    }
    840    else if (png_ptr->mode & PNG_HAVE_PLTE)
    841       /* Should be an error, but we can cope with it */
    842       png_warning(png_ptr, "Missing PLTE before cHRM");
    843 
    844    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
    845 #ifdef PNG_READ_sRGB_SUPPORTED
    846       && !(info_ptr->valid & PNG_INFO_sRGB)
    847 #endif
    848       )
    849    {
    850       png_warning(png_ptr, "Duplicate cHRM chunk");
    851       png_crc_finish(png_ptr, length);
    852       return;
    853    }
    854 
    855    if (length != 32)
    856    {
    857       png_warning(png_ptr, "Incorrect cHRM chunk length");
    858       png_crc_finish(png_ptr, length);
    859       return;
    860    }
    861 
    862    png_crc_read(png_ptr, buf, 32);
    863    if (png_crc_finish(png_ptr, 0))
    864       return;
    865 
    866    uint_x = png_get_uint_32(buf);
    867    uint_y = png_get_uint_32(buf + 4);
    868    int_x_white = (png_fixed_point)uint_x;
    869    int_y_white = (png_fixed_point)uint_y;
    870 
    871    uint_x = png_get_uint_32(buf + 8);
    872    uint_y = png_get_uint_32(buf + 12);
    873    int_x_red = (png_fixed_point)uint_x;
    874    int_y_red = (png_fixed_point)uint_y;
    875 
    876    uint_x = png_get_uint_32(buf + 16);
    877    uint_y = png_get_uint_32(buf + 20);
    878    int_x_green = (png_fixed_point)uint_x;
    879    int_y_green = (png_fixed_point)uint_y;
    880 
    881    uint_x = png_get_uint_32(buf + 24);
    882    uint_y = png_get_uint_32(buf + 28);
    883    int_x_blue = (png_fixed_point)uint_x;
    884    int_y_blue = (png_fixed_point)uint_y;
    885 
    886 #ifdef PNG_FLOATING_POINT_SUPPORTED
    887    white_x = (float)int_x_white / (float)100000.0;
    888    white_y = (float)int_y_white / (float)100000.0;
    889    red_x   = (float)int_x_red   / (float)100000.0;
    890    red_y   = (float)int_y_red   / (float)100000.0;
    891    green_x = (float)int_x_green / (float)100000.0;
    892    green_y = (float)int_y_green / (float)100000.0;
    893    blue_x  = (float)int_x_blue  / (float)100000.0;
    894    blue_y  = (float)int_y_blue  / (float)100000.0;
    895 #endif
    896 
    897 #ifdef PNG_READ_sRGB_SUPPORTED
    898    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
    899       {
    900       if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
    901           PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
    902           PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
    903           PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
    904           PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
    905           PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
    906           PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
    907           PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
    908          {
    909             png_warning(png_ptr,
    910               "Ignoring incorrect cHRM value when sRGB is also present");
    911 #ifdef PNG_CONSOLE_IO_SUPPORTED
    912 #ifdef PNG_FLOATING_POINT_SUPPORTED
    913             fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
    914                white_x, white_y, red_x, red_y);
    915             fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
    916                green_x, green_y, blue_x, blue_y);
    917 #else
    918             fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
    919                (long)int_x_white, (long)int_y_white,
    920                (long)int_x_red, (long)int_y_red);
    921             fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
    922                (long)int_x_green, (long)int_y_green,
    923                (long)int_x_blue, (long)int_y_blue);
    924 #endif
    925 #endif /* PNG_CONSOLE_IO_SUPPORTED */
    926          }
    927          return;
    928       }
    929 #endif /* PNG_READ_sRGB_SUPPORTED */
    930 
    931 #ifdef PNG_FLOATING_POINT_SUPPORTED
    932    png_set_cHRM(png_ptr, info_ptr,
    933       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
    934 #endif
    935 #ifdef PNG_FIXED_POINT_SUPPORTED
    936    png_set_cHRM_fixed(png_ptr, info_ptr,
    937       int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
    938       int_y_green, int_x_blue, int_y_blue);
    939 #endif
    940 }
    941 #endif
    942 
    943 #ifdef PNG_READ_sRGB_SUPPORTED
    944 void /* PRIVATE */
    945 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    946 {
    947    int intent;
    948    png_byte buf[1];
    949 
    950    png_debug(1, "in png_handle_sRGB");
    951 
    952    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    953       png_error(png_ptr, "Missing IHDR before sRGB");
    954    else if (png_ptr->mode & PNG_HAVE_IDAT)
    955    {
    956       png_warning(png_ptr, "Invalid sRGB after IDAT");
    957       png_crc_finish(png_ptr, length);
    958       return;
    959    }
    960    else if (png_ptr->mode & PNG_HAVE_PLTE)
    961       /* Should be an error, but we can cope with it */
    962       png_warning(png_ptr, "Out of place sRGB chunk");
    963 
    964    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
    965    {
    966       png_warning(png_ptr, "Duplicate sRGB chunk");
    967       png_crc_finish(png_ptr, length);
    968       return;
    969    }
    970 
    971    if (length != 1)
    972    {
    973       png_warning(png_ptr, "Incorrect sRGB chunk length");
    974       png_crc_finish(png_ptr, length);
    975       return;
    976    }
    977 
    978    png_crc_read(png_ptr, buf, 1);
    979    if (png_crc_finish(png_ptr, 0))
    980       return;
    981 
    982    intent = buf[0];
    983    /* Check for bad intent */
    984    if (intent >= PNG_sRGB_INTENT_LAST)
    985    {
    986       png_warning(png_ptr, "Unknown sRGB intent");
    987       return;
    988    }
    989 
    990 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
    991    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
    992    {
    993    png_fixed_point igamma;
    994 #ifdef PNG_FIXED_POINT_SUPPORTED
    995       igamma=info_ptr->int_gamma;
    996 #else
    997 #  ifdef PNG_FLOATING_POINT_SUPPORTED
    998       igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
    999 #  endif
   1000 #endif
   1001       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
   1002       {
   1003          png_warning(png_ptr,
   1004            "Ignoring incorrect gAMA value when sRGB is also present");
   1005 #ifdef PNG_CONSOLE_IO_SUPPORTED
   1006 #  ifdef PNG_FIXED_POINT_SUPPORTED
   1007          fprintf(stderr, "incorrect gamma=(%d/100000)\n",
   1008             (int)png_ptr->int_gamma);
   1009 #  else
   1010 #    ifdef PNG_FLOATING_POINT_SUPPORTED
   1011          fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
   1012 #    endif
   1013 #  endif
   1014 #endif
   1015       }
   1016    }
   1017 #endif /* PNG_READ_gAMA_SUPPORTED */
   1018 
   1019 #ifdef PNG_READ_cHRM_SUPPORTED
   1020 #ifdef PNG_FIXED_POINT_SUPPORTED
   1021    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
   1022       if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
   1023           PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
   1024           PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
   1025           PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
   1026           PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
   1027           PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
   1028           PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
   1029           PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
   1030          {
   1031             png_warning(png_ptr,
   1032               "Ignoring incorrect cHRM value when sRGB is also present");
   1033          }
   1034 #endif /* PNG_FIXED_POINT_SUPPORTED */
   1035 #endif /* PNG_READ_cHRM_SUPPORTED */
   1036 
   1037    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
   1038 }
   1039 #endif /* PNG_READ_sRGB_SUPPORTED */
   1040 
   1041 #ifdef PNG_READ_iCCP_SUPPORTED
   1042 void /* PRIVATE */
   1043 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1044 /* Note: this does not properly handle chunks that are > 64K under DOS */
   1045 {
   1046    png_byte compression_type;
   1047    png_bytep pC;
   1048    png_charp profile;
   1049    png_uint_32 skip = 0;
   1050    png_uint_32 profile_size, profile_length;
   1051    png_size_t slength, prefix_length, data_length;
   1052 
   1053    png_debug(1, "in png_handle_iCCP");
   1054 
   1055    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1056       png_error(png_ptr, "Missing IHDR before iCCP");
   1057    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1058    {
   1059       png_warning(png_ptr, "Invalid iCCP after IDAT");
   1060       png_crc_finish(png_ptr, length);
   1061       return;
   1062    }
   1063    else if (png_ptr->mode & PNG_HAVE_PLTE)
   1064       /* Should be an error, but we can cope with it */
   1065       png_warning(png_ptr, "Out of place iCCP chunk");
   1066 
   1067    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
   1068    {
   1069       png_warning(png_ptr, "Duplicate iCCP chunk");
   1070       png_crc_finish(png_ptr, length);
   1071       return;
   1072    }
   1073 
   1074 #ifdef PNG_MAX_MALLOC_64K
   1075    if (length > (png_uint_32)65535L)
   1076    {
   1077       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
   1078       skip = length - (png_uint_32)65535L;
   1079       length = (png_uint_32)65535L;
   1080    }
   1081 #endif
   1082 
   1083    png_free(png_ptr, png_ptr->chunkdata);
   1084    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
   1085    slength = (png_size_t)length;
   1086    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   1087 
   1088    if (png_crc_finish(png_ptr, skip))
   1089    {
   1090       png_free(png_ptr, png_ptr->chunkdata);
   1091       png_ptr->chunkdata = NULL;
   1092       return;
   1093    }
   1094 
   1095    png_ptr->chunkdata[slength] = 0x00;
   1096 
   1097    for (profile = png_ptr->chunkdata; *profile; profile++)
   1098       /* Empty loop to find end of name */ ;
   1099 
   1100    ++profile;
   1101 
   1102    /* There should be at least one zero (the compression type byte)
   1103     * following the separator, and we should be on it
   1104     */
   1105    if ( profile >= png_ptr->chunkdata + slength - 1)
   1106    {
   1107       png_free(png_ptr, png_ptr->chunkdata);
   1108       png_ptr->chunkdata = NULL;
   1109       png_warning(png_ptr, "Malformed iCCP chunk");
   1110       return;
   1111    }
   1112 
   1113    /* Compression_type should always be zero */
   1114    compression_type = *profile++;
   1115    if (compression_type)
   1116    {
   1117       png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
   1118       compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
   1119                                  wrote nonzero) */
   1120    }
   1121 
   1122    prefix_length = profile - png_ptr->chunkdata;
   1123    png_decompress_chunk(png_ptr, compression_type,
   1124      slength, prefix_length, &data_length);
   1125 
   1126    profile_length = data_length - prefix_length;
   1127 
   1128    if ( prefix_length > data_length || profile_length < 4)
   1129    {
   1130       png_free(png_ptr, png_ptr->chunkdata);
   1131       png_ptr->chunkdata = NULL;
   1132       png_warning(png_ptr, "Profile size field missing from iCCP chunk");
   1133       return;
   1134    }
   1135 
   1136    /* Check the profile_size recorded in the first 32 bits of the ICC profile */
   1137    pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
   1138    profile_size = ((*(pC    ))<<24) |
   1139                   ((*(pC + 1))<<16) |
   1140                   ((*(pC + 2))<< 8) |
   1141                   ((*(pC + 3))    );
   1142 
   1143    if (profile_size < profile_length)
   1144       profile_length = profile_size;
   1145 
   1146    if (profile_size > profile_length)
   1147    {
   1148       png_free(png_ptr, png_ptr->chunkdata);
   1149       png_ptr->chunkdata = NULL;
   1150       png_warning(png_ptr, "Ignoring truncated iCCP profile.");
   1151       return;
   1152    }
   1153 
   1154    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
   1155      compression_type, png_ptr->chunkdata + prefix_length, profile_length);
   1156    png_free(png_ptr, png_ptr->chunkdata);
   1157    png_ptr->chunkdata = NULL;
   1158 }
   1159 #endif /* PNG_READ_iCCP_SUPPORTED */
   1160 
   1161 #ifdef PNG_READ_sPLT_SUPPORTED
   1162 void /* PRIVATE */
   1163 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1164 /* Note: this does not properly handle chunks that are > 64K under DOS */
   1165 {
   1166    png_bytep entry_start;
   1167    png_sPLT_t new_palette;
   1168 #ifdef PNG_POINTER_INDEXING_SUPPORTED
   1169    png_sPLT_entryp pp;
   1170 #endif
   1171    int data_length, entry_size, i;
   1172    png_uint_32 skip = 0;
   1173    png_size_t slength;
   1174 
   1175    png_debug(1, "in png_handle_sPLT");
   1176 
   1177 #ifdef PNG_USER_LIMITS_SUPPORTED
   1178 
   1179    if (png_ptr->user_chunk_cache_max != 0)
   1180    {
   1181       if (png_ptr->user_chunk_cache_max == 1)
   1182       {
   1183          png_crc_finish(png_ptr, length);
   1184          return;
   1185       }
   1186       if (--png_ptr->user_chunk_cache_max == 1)
   1187       {
   1188          png_warning(png_ptr, "No space in chunk cache for sPLT");
   1189          png_crc_finish(png_ptr, length);
   1190          return;
   1191       }
   1192    }
   1193 #endif
   1194 
   1195    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1196       png_error(png_ptr, "Missing IHDR before sPLT");
   1197    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1198    {
   1199       png_warning(png_ptr, "Invalid sPLT after IDAT");
   1200       png_crc_finish(png_ptr, length);
   1201       return;
   1202    }
   1203 
   1204 #ifdef PNG_MAX_MALLOC_64K
   1205    if (length > (png_uint_32)65535L)
   1206    {
   1207       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
   1208       skip = length - (png_uint_32)65535L;
   1209       length = (png_uint_32)65535L;
   1210    }
   1211 #endif
   1212 
   1213    png_free(png_ptr, png_ptr->chunkdata);
   1214    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
   1215    slength = (png_size_t)length;
   1216    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   1217 
   1218    if (png_crc_finish(png_ptr, skip))
   1219    {
   1220       png_free(png_ptr, png_ptr->chunkdata);
   1221       png_ptr->chunkdata = NULL;
   1222       return;
   1223    }
   1224 
   1225    png_ptr->chunkdata[slength] = 0x00;
   1226 
   1227    for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
   1228        entry_start++)
   1229       /* Empty loop to find end of name */ ;
   1230    ++entry_start;
   1231 
   1232    /* A sample depth should follow the separator, and we should be on it  */
   1233    if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
   1234    {
   1235       png_free(png_ptr, png_ptr->chunkdata);
   1236       png_ptr->chunkdata = NULL;
   1237       png_warning(png_ptr, "malformed sPLT chunk");
   1238       return;
   1239    }
   1240 
   1241    new_palette.depth = *entry_start++;
   1242    entry_size = (new_palette.depth == 8 ? 6 : 10);
   1243    data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
   1244 
   1245    /* Integrity-check the data length */
   1246    if (data_length % entry_size)
   1247    {
   1248       png_free(png_ptr, png_ptr->chunkdata);
   1249       png_ptr->chunkdata = NULL;
   1250       png_warning(png_ptr, "sPLT chunk has bad length");
   1251       return;
   1252    }
   1253 
   1254    new_palette.nentries = (png_int_32) ( data_length / entry_size);
   1255    if ((png_uint_32) new_palette.nentries >
   1256        (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
   1257    {
   1258        png_warning(png_ptr, "sPLT chunk too long");
   1259        return;
   1260    }
   1261    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
   1262        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
   1263    if (new_palette.entries == NULL)
   1264    {
   1265        png_warning(png_ptr, "sPLT chunk requires too much memory");
   1266        return;
   1267    }
   1268 
   1269 #ifdef PNG_POINTER_INDEXING_SUPPORTED
   1270    for (i = 0; i < new_palette.nentries; i++)
   1271    {
   1272       pp = new_palette.entries + i;
   1273 
   1274       if (new_palette.depth == 8)
   1275       {
   1276           pp->red = *entry_start++;
   1277           pp->green = *entry_start++;
   1278           pp->blue = *entry_start++;
   1279           pp->alpha = *entry_start++;
   1280       }
   1281       else
   1282       {
   1283           pp->red   = png_get_uint_16(entry_start); entry_start += 2;
   1284           pp->green = png_get_uint_16(entry_start); entry_start += 2;
   1285           pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
   1286           pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
   1287       }
   1288       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
   1289    }
   1290 #else
   1291    pp = new_palette.entries;
   1292    for (i = 0; i < new_palette.nentries; i++)
   1293    {
   1294 
   1295       if (new_palette.depth == 8)
   1296       {
   1297           pp[i].red   = *entry_start++;
   1298           pp[i].green = *entry_start++;
   1299           pp[i].blue  = *entry_start++;
   1300           pp[i].alpha = *entry_start++;
   1301       }
   1302       else
   1303       {
   1304           pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
   1305           pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
   1306           pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
   1307           pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
   1308       }
   1309       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
   1310    }
   1311 #endif
   1312 
   1313    /* Discard all chunk data except the name and stash that */
   1314    new_palette.name = png_ptr->chunkdata;
   1315 
   1316    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
   1317 
   1318    png_free(png_ptr, png_ptr->chunkdata);
   1319    png_ptr->chunkdata = NULL;
   1320    png_free(png_ptr, new_palette.entries);
   1321 }
   1322 #endif /* PNG_READ_sPLT_SUPPORTED */
   1323 
   1324 #ifdef PNG_READ_tRNS_SUPPORTED
   1325 void /* PRIVATE */
   1326 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1327 {
   1328    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
   1329 
   1330    png_debug(1, "in png_handle_tRNS");
   1331 
   1332    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1333       png_error(png_ptr, "Missing IHDR before tRNS");
   1334    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1335    {
   1336       png_warning(png_ptr, "Invalid tRNS after IDAT");
   1337       png_crc_finish(png_ptr, length);
   1338       return;
   1339    }
   1340    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
   1341    {
   1342       png_warning(png_ptr, "Duplicate tRNS chunk");
   1343       png_crc_finish(png_ptr, length);
   1344       return;
   1345    }
   1346 
   1347    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
   1348    {
   1349       png_byte buf[2];
   1350 
   1351       if (length != 2)
   1352       {
   1353          png_warning(png_ptr, "Incorrect tRNS chunk length");
   1354          png_crc_finish(png_ptr, length);
   1355          return;
   1356       }
   1357 
   1358       png_crc_read(png_ptr, buf, 2);
   1359       png_ptr->num_trans = 1;
   1360       png_ptr->trans_values.gray = png_get_uint_16(buf);
   1361    }
   1362    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   1363    {
   1364       png_byte buf[6];
   1365 
   1366       if (length != 6)
   1367       {
   1368          png_warning(png_ptr, "Incorrect tRNS chunk length");
   1369          png_crc_finish(png_ptr, length);
   1370          return;
   1371       }
   1372       png_crc_read(png_ptr, buf, (png_size_t)length);
   1373       png_ptr->num_trans = 1;
   1374       png_ptr->trans_values.red = png_get_uint_16(buf);
   1375       png_ptr->trans_values.green = png_get_uint_16(buf + 2);
   1376       png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
   1377    }
   1378    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1379    {
   1380       if (!(png_ptr->mode & PNG_HAVE_PLTE))
   1381       {
   1382          /* Should be an error, but we can cope with it. */
   1383          png_warning(png_ptr, "Missing PLTE before tRNS");
   1384       }
   1385       if (length > (png_uint_32)png_ptr->num_palette ||
   1386           length > PNG_MAX_PALETTE_LENGTH)
   1387       {
   1388          png_warning(png_ptr, "Incorrect tRNS chunk length");
   1389          png_crc_finish(png_ptr, length);
   1390          return;
   1391       }
   1392       if (length == 0)
   1393       {
   1394          png_warning(png_ptr, "Zero length tRNS chunk");
   1395          png_crc_finish(png_ptr, length);
   1396          return;
   1397       }
   1398       png_crc_read(png_ptr, readbuf, (png_size_t)length);
   1399       png_ptr->num_trans = (png_uint_16)length;
   1400    }
   1401    else
   1402    {
   1403       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
   1404       png_crc_finish(png_ptr, length);
   1405       return;
   1406    }
   1407 
   1408    if (png_crc_finish(png_ptr, 0))
   1409    {
   1410       png_ptr->num_trans = 0;
   1411       return;
   1412    }
   1413 
   1414    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
   1415       &(png_ptr->trans_values));
   1416 }
   1417 #endif
   1418 
   1419 #ifdef PNG_READ_bKGD_SUPPORTED
   1420 void /* PRIVATE */
   1421 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1422 {
   1423    png_size_t truelen;
   1424    png_byte buf[6];
   1425 
   1426    png_debug(1, "in png_handle_bKGD");
   1427 
   1428    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1429       png_error(png_ptr, "Missing IHDR before bKGD");
   1430    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1431    {
   1432       png_warning(png_ptr, "Invalid bKGD after IDAT");
   1433       png_crc_finish(png_ptr, length);
   1434       return;
   1435    }
   1436    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
   1437             !(png_ptr->mode & PNG_HAVE_PLTE))
   1438    {
   1439       png_warning(png_ptr, "Missing PLTE before bKGD");
   1440       png_crc_finish(png_ptr, length);
   1441       return;
   1442    }
   1443    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
   1444    {
   1445       png_warning(png_ptr, "Duplicate bKGD chunk");
   1446       png_crc_finish(png_ptr, length);
   1447       return;
   1448    }
   1449 
   1450    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1451       truelen = 1;
   1452    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
   1453       truelen = 6;
   1454    else
   1455       truelen = 2;
   1456 
   1457    if (length != truelen)
   1458    {
   1459       png_warning(png_ptr, "Incorrect bKGD chunk length");
   1460       png_crc_finish(png_ptr, length);
   1461       return;
   1462    }
   1463 
   1464    png_crc_read(png_ptr, buf, truelen);
   1465    if (png_crc_finish(png_ptr, 0))
   1466       return;
   1467 
   1468    /* We convert the index value into RGB components so that we can allow
   1469     * arbitrary RGB values for background when we have transparency, and
   1470     * so it is easy to determine the RGB values of the background color
   1471     * from the info_ptr struct. */
   1472    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   1473    {
   1474       png_ptr->background.index = buf[0];
   1475       if (info_ptr && info_ptr->num_palette)
   1476       {
   1477           if (buf[0] >= info_ptr->num_palette)
   1478           {
   1479              png_warning(png_ptr, "Incorrect bKGD chunk index value");
   1480              return;
   1481           }
   1482           png_ptr->background.red =
   1483              (png_uint_16)png_ptr->palette[buf[0]].red;
   1484           png_ptr->background.green =
   1485              (png_uint_16)png_ptr->palette[buf[0]].green;
   1486           png_ptr->background.blue =
   1487              (png_uint_16)png_ptr->palette[buf[0]].blue;
   1488       }
   1489    }
   1490    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
   1491    {
   1492       png_ptr->background.red =
   1493       png_ptr->background.green =
   1494       png_ptr->background.blue =
   1495       png_ptr->background.gray = png_get_uint_16(buf);
   1496    }
   1497    else
   1498    {
   1499       png_ptr->background.red = png_get_uint_16(buf);
   1500       png_ptr->background.green = png_get_uint_16(buf + 2);
   1501       png_ptr->background.blue = png_get_uint_16(buf + 4);
   1502    }
   1503 
   1504    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
   1505 }
   1506 #endif
   1507 
   1508 #ifdef PNG_READ_hIST_SUPPORTED
   1509 void /* PRIVATE */
   1510 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1511 {
   1512    unsigned int num, i;
   1513    png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
   1514 
   1515    png_debug(1, "in png_handle_hIST");
   1516 
   1517    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1518       png_error(png_ptr, "Missing IHDR before hIST");
   1519    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1520    {
   1521       png_warning(png_ptr, "Invalid hIST after IDAT");
   1522       png_crc_finish(png_ptr, length);
   1523       return;
   1524    }
   1525    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
   1526    {
   1527       png_warning(png_ptr, "Missing PLTE before hIST");
   1528       png_crc_finish(png_ptr, length);
   1529       return;
   1530    }
   1531    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
   1532    {
   1533       png_warning(png_ptr, "Duplicate hIST chunk");
   1534       png_crc_finish(png_ptr, length);
   1535       return;
   1536    }
   1537 
   1538    num = length / 2 ;
   1539    if (num != (unsigned int) png_ptr->num_palette || num >
   1540       (unsigned int) PNG_MAX_PALETTE_LENGTH)
   1541    {
   1542       png_warning(png_ptr, "Incorrect hIST chunk length");
   1543       png_crc_finish(png_ptr, length);
   1544       return;
   1545    }
   1546 
   1547    for (i = 0; i < num; i++)
   1548    {
   1549       png_byte buf[2];
   1550 
   1551       png_crc_read(png_ptr, buf, 2);
   1552       readbuf[i] = png_get_uint_16(buf);
   1553    }
   1554 
   1555    if (png_crc_finish(png_ptr, 0))
   1556       return;
   1557 
   1558    png_set_hIST(png_ptr, info_ptr, readbuf);
   1559 }
   1560 #endif
   1561 
   1562 #ifdef PNG_READ_pHYs_SUPPORTED
   1563 void /* PRIVATE */
   1564 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1565 {
   1566    png_byte buf[9];
   1567    png_uint_32 res_x, res_y;
   1568    int unit_type;
   1569 
   1570    png_debug(1, "in png_handle_pHYs");
   1571 
   1572    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1573       png_error(png_ptr, "Missing IHDR before pHYs");
   1574    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1575    {
   1576       png_warning(png_ptr, "Invalid pHYs after IDAT");
   1577       png_crc_finish(png_ptr, length);
   1578       return;
   1579    }
   1580    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
   1581    {
   1582       png_warning(png_ptr, "Duplicate pHYs chunk");
   1583       png_crc_finish(png_ptr, length);
   1584       return;
   1585    }
   1586 
   1587    if (length != 9)
   1588    {
   1589       png_warning(png_ptr, "Incorrect pHYs chunk length");
   1590       png_crc_finish(png_ptr, length);
   1591       return;
   1592    }
   1593 
   1594    png_crc_read(png_ptr, buf, 9);
   1595    if (png_crc_finish(png_ptr, 0))
   1596       return;
   1597 
   1598    res_x = png_get_uint_32(buf);
   1599    res_y = png_get_uint_32(buf + 4);
   1600    unit_type = buf[8];
   1601    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
   1602 }
   1603 #endif
   1604 
   1605 #ifdef PNG_READ_oFFs_SUPPORTED
   1606 void /* PRIVATE */
   1607 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1608 {
   1609    png_byte buf[9];
   1610    png_int_32 offset_x, offset_y;
   1611    int unit_type;
   1612 
   1613    png_debug(1, "in png_handle_oFFs");
   1614 
   1615    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1616       png_error(png_ptr, "Missing IHDR before oFFs");
   1617    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1618    {
   1619       png_warning(png_ptr, "Invalid oFFs after IDAT");
   1620       png_crc_finish(png_ptr, length);
   1621       return;
   1622    }
   1623    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
   1624    {
   1625       png_warning(png_ptr, "Duplicate oFFs chunk");
   1626       png_crc_finish(png_ptr, length);
   1627       return;
   1628    }
   1629 
   1630    if (length != 9)
   1631    {
   1632       png_warning(png_ptr, "Incorrect oFFs chunk length");
   1633       png_crc_finish(png_ptr, length);
   1634       return;
   1635    }
   1636 
   1637    png_crc_read(png_ptr, buf, 9);
   1638    if (png_crc_finish(png_ptr, 0))
   1639       return;
   1640 
   1641    offset_x = png_get_int_32(buf);
   1642    offset_y = png_get_int_32(buf + 4);
   1643    unit_type = buf[8];
   1644    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
   1645 }
   1646 #endif
   1647 
   1648 #ifdef PNG_READ_pCAL_SUPPORTED
   1649 /* Read the pCAL chunk (described in the PNG Extensions document) */
   1650 void /* PRIVATE */
   1651 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1652 {
   1653    png_int_32 X0, X1;
   1654    png_byte type, nparams;
   1655    png_charp buf, units, endptr;
   1656    png_charpp params;
   1657    png_size_t slength;
   1658    int i;
   1659 
   1660    png_debug(1, "in png_handle_pCAL");
   1661 
   1662    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1663       png_error(png_ptr, "Missing IHDR before pCAL");
   1664    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1665    {
   1666       png_warning(png_ptr, "Invalid pCAL after IDAT");
   1667       png_crc_finish(png_ptr, length);
   1668       return;
   1669    }
   1670    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
   1671    {
   1672       png_warning(png_ptr, "Duplicate pCAL chunk");
   1673       png_crc_finish(png_ptr, length);
   1674       return;
   1675    }
   1676 
   1677    png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
   1678       length + 1);
   1679    png_free(png_ptr, png_ptr->chunkdata);
   1680    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   1681    if (png_ptr->chunkdata == NULL)
   1682      {
   1683        png_warning(png_ptr, "No memory for pCAL purpose.");
   1684        return;
   1685      }
   1686    slength = (png_size_t)length;
   1687    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   1688 
   1689    if (png_crc_finish(png_ptr, 0))
   1690    {
   1691       png_free(png_ptr, png_ptr->chunkdata);
   1692       png_ptr->chunkdata = NULL;
   1693       return;
   1694    }
   1695 
   1696    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
   1697 
   1698    png_debug(3, "Finding end of pCAL purpose string");
   1699    for (buf = png_ptr->chunkdata; *buf; buf++)
   1700       /* Empty loop */ ;
   1701 
   1702    endptr = png_ptr->chunkdata + slength;
   1703 
   1704    /* We need to have at least 12 bytes after the purpose string
   1705       in order to get the parameter information. */
   1706    if (endptr <= buf + 12)
   1707    {
   1708       png_warning(png_ptr, "Invalid pCAL data");
   1709       png_free(png_ptr, png_ptr->chunkdata);
   1710       png_ptr->chunkdata = NULL;
   1711       return;
   1712    }
   1713 
   1714    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
   1715    X0 = png_get_int_32((png_bytep)buf+1);
   1716    X1 = png_get_int_32((png_bytep)buf+5);
   1717    type = buf[9];
   1718    nparams = buf[10];
   1719    units = buf + 11;
   1720 
   1721    png_debug(3, "Checking pCAL equation type and number of parameters");
   1722    /* Check that we have the right number of parameters for known
   1723       equation types. */
   1724    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
   1725        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
   1726        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
   1727        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
   1728    {
   1729       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
   1730       png_free(png_ptr, png_ptr->chunkdata);
   1731       png_ptr->chunkdata = NULL;
   1732       return;
   1733    }
   1734    else if (type >= PNG_EQUATION_LAST)
   1735    {
   1736       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
   1737    }
   1738 
   1739    for (buf = units; *buf; buf++)
   1740       /* Empty loop to move past the units string. */ ;
   1741 
   1742    png_debug(3, "Allocating pCAL parameters array");
   1743    params = (png_charpp)png_malloc_warn(png_ptr,
   1744       (png_uint_32)(nparams * png_sizeof(png_charp))) ;
   1745    if (params == NULL)
   1746      {
   1747        png_free(png_ptr, png_ptr->chunkdata);
   1748        png_ptr->chunkdata = NULL;
   1749        png_warning(png_ptr, "No memory for pCAL params.");
   1750        return;
   1751      }
   1752 
   1753    /* Get pointers to the start of each parameter string. */
   1754    for (i = 0; i < (int)nparams; i++)
   1755    {
   1756       buf++; /* Skip the null string terminator from previous parameter. */
   1757 
   1758       png_debug1(3, "Reading pCAL parameter %d", i);
   1759       for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
   1760          /* Empty loop to move past each parameter string */ ;
   1761 
   1762       /* Make sure we haven't run out of data yet */
   1763       if (buf > endptr)
   1764       {
   1765          png_warning(png_ptr, "Invalid pCAL data");
   1766          png_free(png_ptr, png_ptr->chunkdata);
   1767          png_ptr->chunkdata = NULL;
   1768          png_free(png_ptr, params);
   1769          return;
   1770       }
   1771    }
   1772 
   1773    png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
   1774       units, params);
   1775 
   1776    png_free(png_ptr, png_ptr->chunkdata);
   1777    png_ptr->chunkdata = NULL;
   1778    png_free(png_ptr, params);
   1779 }
   1780 #endif
   1781 
   1782 #ifdef PNG_READ_sCAL_SUPPORTED
   1783 /* Read the sCAL chunk */
   1784 void /* PRIVATE */
   1785 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1786 {
   1787    png_charp ep;
   1788 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1789    double width, height;
   1790    png_charp vp;
   1791 #else
   1792 #ifdef PNG_FIXED_POINT_SUPPORTED
   1793    png_charp swidth, sheight;
   1794 #endif
   1795 #endif
   1796    png_size_t slength;
   1797 
   1798    png_debug(1, "in png_handle_sCAL");
   1799 
   1800    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1801       png_error(png_ptr, "Missing IHDR before sCAL");
   1802    else if (png_ptr->mode & PNG_HAVE_IDAT)
   1803    {
   1804       png_warning(png_ptr, "Invalid sCAL after IDAT");
   1805       png_crc_finish(png_ptr, length);
   1806       return;
   1807    }
   1808    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
   1809    {
   1810       png_warning(png_ptr, "Duplicate sCAL chunk");
   1811       png_crc_finish(png_ptr, length);
   1812       return;
   1813    }
   1814 
   1815    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
   1816       length + 1);
   1817    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   1818    if (png_ptr->chunkdata == NULL)
   1819    {
   1820       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
   1821       png_crc_finish(png_ptr, length);
   1822       return;
   1823    }
   1824    slength = (png_size_t)length;
   1825    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   1826 
   1827    if (png_crc_finish(png_ptr, 0))
   1828    {
   1829       png_free(png_ptr, png_ptr->chunkdata);
   1830       png_ptr->chunkdata = NULL;
   1831       return;
   1832    }
   1833 
   1834    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
   1835 
   1836    ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
   1837 
   1838 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1839    width = png_strtod(png_ptr, ep, &vp);
   1840    if (*vp)
   1841    {
   1842       png_warning(png_ptr, "malformed width string in sCAL chunk");
   1843       png_free(png_ptr, png_ptr->chunkdata);
   1844       png_ptr->chunkdata = NULL;
   1845       return;
   1846    }
   1847 #else
   1848 #ifdef PNG_FIXED_POINT_SUPPORTED
   1849    swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
   1850    if (swidth == NULL)
   1851    {
   1852       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
   1853       png_free(png_ptr, png_ptr->chunkdata);
   1854       png_ptr->chunkdata = NULL;
   1855       return;
   1856    }
   1857    png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
   1858 #endif
   1859 #endif
   1860 
   1861    for (ep = png_ptr->chunkdata; *ep; ep++)
   1862       /* Empty loop */ ;
   1863    ep++;
   1864 
   1865    if (png_ptr->chunkdata + slength < ep)
   1866    {
   1867       png_warning(png_ptr, "Truncated sCAL chunk");
   1868 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1869       png_free(png_ptr, swidth);
   1870 #endif
   1871       png_free(png_ptr, png_ptr->chunkdata);
   1872       png_ptr->chunkdata = NULL;
   1873       return;
   1874    }
   1875 
   1876 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1877    height = png_strtod(png_ptr, ep, &vp);
   1878    if (*vp)
   1879    {
   1880       png_warning(png_ptr, "malformed height string in sCAL chunk");
   1881       png_free(png_ptr, png_ptr->chunkdata);
   1882       png_ptr->chunkdata = NULL;
   1883 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1884       png_free(png_ptr, swidth);
   1885 #endif
   1886       return;
   1887    }
   1888 #else
   1889 #ifdef PNG_FIXED_POINT_SUPPORTED
   1890    sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
   1891    if (sheight == NULL)
   1892    {
   1893       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
   1894       png_free(png_ptr, png_ptr->chunkdata);
   1895       png_ptr->chunkdata = NULL;
   1896 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1897       png_free(png_ptr, swidth);
   1898 #endif
   1899       return;
   1900    }
   1901    png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
   1902 #endif
   1903 #endif
   1904 
   1905    if (png_ptr->chunkdata + slength < ep
   1906 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1907       || width <= 0. || height <= 0.
   1908 #endif
   1909       )
   1910    {
   1911       png_warning(png_ptr, "Invalid sCAL data");
   1912       png_free(png_ptr, png_ptr->chunkdata);
   1913       png_ptr->chunkdata = NULL;
   1914 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1915       png_free(png_ptr, swidth);
   1916       png_free(png_ptr, sheight);
   1917 #endif
   1918       return;
   1919    }
   1920 
   1921 
   1922 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1923    png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
   1924 #else
   1925 #ifdef PNG_FIXED_POINT_SUPPORTED
   1926    png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
   1927 #endif
   1928 #endif
   1929 
   1930    png_free(png_ptr, png_ptr->chunkdata);
   1931    png_ptr->chunkdata = NULL;
   1932 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1933    png_free(png_ptr, swidth);
   1934    png_free(png_ptr, sheight);
   1935 #endif
   1936 }
   1937 #endif
   1938 
   1939 #ifdef PNG_READ_tIME_SUPPORTED
   1940 void /* PRIVATE */
   1941 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1942 {
   1943    png_byte buf[7];
   1944    png_time mod_time;
   1945 
   1946    png_debug(1, "in png_handle_tIME");
   1947 
   1948    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1949       png_error(png_ptr, "Out of place tIME chunk");
   1950    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
   1951    {
   1952       png_warning(png_ptr, "Duplicate tIME chunk");
   1953       png_crc_finish(png_ptr, length);
   1954       return;
   1955    }
   1956 
   1957    if (png_ptr->mode & PNG_HAVE_IDAT)
   1958       png_ptr->mode |= PNG_AFTER_IDAT;
   1959 
   1960    if (length != 7)
   1961    {
   1962       png_warning(png_ptr, "Incorrect tIME chunk length");
   1963       png_crc_finish(png_ptr, length);
   1964       return;
   1965    }
   1966 
   1967    png_crc_read(png_ptr, buf, 7);
   1968    if (png_crc_finish(png_ptr, 0))
   1969       return;
   1970 
   1971    mod_time.second = buf[6];
   1972    mod_time.minute = buf[5];
   1973    mod_time.hour = buf[4];
   1974    mod_time.day = buf[3];
   1975    mod_time.month = buf[2];
   1976    mod_time.year = png_get_uint_16(buf);
   1977 
   1978    png_set_tIME(png_ptr, info_ptr, &mod_time);
   1979 }
   1980 #endif
   1981 
   1982 #ifdef PNG_READ_tEXt_SUPPORTED
   1983 /* Note: this does not properly handle chunks that are > 64K under DOS */
   1984 void /* PRIVATE */
   1985 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1986 {
   1987    png_textp text_ptr;
   1988    png_charp key;
   1989    png_charp text;
   1990    png_uint_32 skip = 0;
   1991    png_size_t slength;
   1992    int ret;
   1993 
   1994    png_debug(1, "in png_handle_tEXt");
   1995 
   1996 #ifdef PNG_USER_LIMITS_SUPPORTED
   1997    if (png_ptr->user_chunk_cache_max != 0)
   1998    {
   1999       if (png_ptr->user_chunk_cache_max == 1)
   2000       {
   2001          png_crc_finish(png_ptr, length);
   2002          return;
   2003       }
   2004       if (--png_ptr->user_chunk_cache_max == 1)
   2005       {
   2006          png_warning(png_ptr, "No space in chunk cache for tEXt");
   2007          png_crc_finish(png_ptr, length);
   2008          return;
   2009       }
   2010    }
   2011 #endif
   2012 
   2013    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2014       png_error(png_ptr, "Missing IHDR before tEXt");
   2015 
   2016    if (png_ptr->mode & PNG_HAVE_IDAT)
   2017       png_ptr->mode |= PNG_AFTER_IDAT;
   2018 
   2019 #ifdef PNG_MAX_MALLOC_64K
   2020    if (length > (png_uint_32)65535L)
   2021    {
   2022       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
   2023       skip = length - (png_uint_32)65535L;
   2024       length = (png_uint_32)65535L;
   2025    }
   2026 #endif
   2027 
   2028    png_free(png_ptr, png_ptr->chunkdata);
   2029 
   2030    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2031    if (png_ptr->chunkdata == NULL)
   2032    {
   2033      png_warning(png_ptr, "No memory to process text chunk.");
   2034      return;
   2035    }
   2036    slength = (png_size_t)length;
   2037    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2038 
   2039    if (png_crc_finish(png_ptr, skip))
   2040    {
   2041       png_free(png_ptr, png_ptr->chunkdata);
   2042       png_ptr->chunkdata = NULL;
   2043       return;
   2044    }
   2045 
   2046    key = png_ptr->chunkdata;
   2047 
   2048    key[slength] = 0x00;
   2049 
   2050    for (text = key; *text; text++)
   2051       /* Empty loop to find end of key */ ;
   2052 
   2053    if (text != key + slength)
   2054       text++;
   2055 
   2056    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2057       (png_uint_32)png_sizeof(png_text));
   2058    if (text_ptr == NULL)
   2059    {
   2060      png_warning(png_ptr, "Not enough memory to process text chunk.");
   2061      png_free(png_ptr, png_ptr->chunkdata);
   2062      png_ptr->chunkdata = NULL;
   2063      return;
   2064    }
   2065    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
   2066    text_ptr->key = key;
   2067 #ifdef PNG_iTXt_SUPPORTED
   2068    text_ptr->lang = NULL;
   2069    text_ptr->lang_key = NULL;
   2070    text_ptr->itxt_length = 0;
   2071 #endif
   2072    text_ptr->text = text;
   2073    text_ptr->text_length = png_strlen(text);
   2074 
   2075    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2076 
   2077    png_free(png_ptr, png_ptr->chunkdata);
   2078    png_ptr->chunkdata = NULL;
   2079    png_free(png_ptr, text_ptr);
   2080    if (ret)
   2081      png_warning(png_ptr, "Insufficient memory to process text chunk.");
   2082 }
   2083 #endif
   2084 
   2085 #ifdef PNG_READ_zTXt_SUPPORTED
   2086 /* Note: this does not correctly handle chunks that are > 64K under DOS */
   2087 void /* PRIVATE */
   2088 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2089 {
   2090    png_textp text_ptr;
   2091    png_charp text;
   2092    int comp_type;
   2093    int ret;
   2094    png_size_t slength, prefix_len, data_len;
   2095 
   2096    png_debug(1, "in png_handle_zTXt");
   2097 
   2098 #ifdef PNG_USER_LIMITS_SUPPORTED
   2099    if (png_ptr->user_chunk_cache_max != 0)
   2100    {
   2101       if (png_ptr->user_chunk_cache_max == 1)
   2102       {
   2103          png_crc_finish(png_ptr, length);
   2104          return;
   2105       }
   2106       if (--png_ptr->user_chunk_cache_max == 1)
   2107       {
   2108          png_warning(png_ptr, "No space in chunk cache for zTXt");
   2109          png_crc_finish(png_ptr, length);
   2110          return;
   2111       }
   2112    }
   2113 #endif
   2114 
   2115    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2116       png_error(png_ptr, "Missing IHDR before zTXt");
   2117 
   2118    if (png_ptr->mode & PNG_HAVE_IDAT)
   2119       png_ptr->mode |= PNG_AFTER_IDAT;
   2120 
   2121 #ifdef PNG_MAX_MALLOC_64K
   2122    /* We will no doubt have problems with chunks even half this size, but
   2123       there is no hard and fast rule to tell us where to stop. */
   2124    if (length > (png_uint_32)65535L)
   2125    {
   2126      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
   2127      png_crc_finish(png_ptr, length);
   2128      return;
   2129    }
   2130 #endif
   2131 
   2132    png_free(png_ptr, png_ptr->chunkdata);
   2133    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2134    if (png_ptr->chunkdata == NULL)
   2135    {
   2136      png_warning(png_ptr, "Out of memory processing zTXt chunk.");
   2137      return;
   2138    }
   2139    slength = (png_size_t)length;
   2140    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2141    if (png_crc_finish(png_ptr, 0))
   2142    {
   2143       png_free(png_ptr, png_ptr->chunkdata);
   2144       png_ptr->chunkdata = NULL;
   2145       return;
   2146    }
   2147 
   2148    png_ptr->chunkdata[slength] = 0x00;
   2149 
   2150    for (text = png_ptr->chunkdata; *text; text++)
   2151       /* Empty loop */ ;
   2152 
   2153    /* zTXt must have some text after the chunkdataword */
   2154    if (text >= png_ptr->chunkdata + slength - 2)
   2155    {
   2156       png_warning(png_ptr, "Truncated zTXt chunk");
   2157       png_free(png_ptr, png_ptr->chunkdata);
   2158       png_ptr->chunkdata = NULL;
   2159       return;
   2160    }
   2161    else
   2162    {
   2163        comp_type = *(++text);
   2164        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
   2165        {
   2166           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
   2167           comp_type = PNG_TEXT_COMPRESSION_zTXt;
   2168        }
   2169        text++;        /* Skip the compression_method byte */
   2170    }
   2171    prefix_len = text - png_ptr->chunkdata;
   2172 
   2173    png_decompress_chunk(png_ptr, comp_type,
   2174      (png_size_t)length, prefix_len, &data_len);
   2175 
   2176    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2177       (png_uint_32)png_sizeof(png_text));
   2178    if (text_ptr == NULL)
   2179    {
   2180      png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
   2181      png_free(png_ptr, png_ptr->chunkdata);
   2182      png_ptr->chunkdata = NULL;
   2183      return;
   2184    }
   2185    text_ptr->compression = comp_type;
   2186    text_ptr->key = png_ptr->chunkdata;
   2187 #ifdef PNG_iTXt_SUPPORTED
   2188    text_ptr->lang = NULL;
   2189    text_ptr->lang_key = NULL;
   2190    text_ptr->itxt_length = 0;
   2191 #endif
   2192    text_ptr->text = png_ptr->chunkdata + prefix_len;
   2193    text_ptr->text_length = data_len;
   2194 
   2195    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2196 
   2197    png_free(png_ptr, text_ptr);
   2198    png_free(png_ptr, png_ptr->chunkdata);
   2199    png_ptr->chunkdata = NULL;
   2200    if (ret)
   2201      png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
   2202 }
   2203 #endif
   2204 
   2205 #ifdef PNG_READ_iTXt_SUPPORTED
   2206 /* Note: this does not correctly handle chunks that are > 64K under DOS */
   2207 void /* PRIVATE */
   2208 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2209 {
   2210    png_textp text_ptr;
   2211    png_charp key, lang, text, lang_key;
   2212    int comp_flag;
   2213    int comp_type = 0;
   2214    int ret;
   2215    png_size_t slength, prefix_len, data_len;
   2216 
   2217    png_debug(1, "in png_handle_iTXt");
   2218 
   2219 #ifdef PNG_USER_LIMITS_SUPPORTED
   2220    if (png_ptr->user_chunk_cache_max != 0)
   2221    {
   2222       if (png_ptr->user_chunk_cache_max == 1)
   2223       {
   2224          png_crc_finish(png_ptr, length);
   2225          return;
   2226       }
   2227       if (--png_ptr->user_chunk_cache_max == 1)
   2228       {
   2229          png_warning(png_ptr, "No space in chunk cache for iTXt");
   2230          png_crc_finish(png_ptr, length);
   2231          return;
   2232       }
   2233    }
   2234 #endif
   2235 
   2236    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2237       png_error(png_ptr, "Missing IHDR before iTXt");
   2238 
   2239    if (png_ptr->mode & PNG_HAVE_IDAT)
   2240       png_ptr->mode |= PNG_AFTER_IDAT;
   2241 
   2242 #ifdef PNG_MAX_MALLOC_64K
   2243    /* We will no doubt have problems with chunks even half this size, but
   2244       there is no hard and fast rule to tell us where to stop. */
   2245    if (length > (png_uint_32)65535L)
   2246    {
   2247      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
   2248      png_crc_finish(png_ptr, length);
   2249      return;
   2250    }
   2251 #endif
   2252 
   2253    png_free(png_ptr, png_ptr->chunkdata);
   2254    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2255    if (png_ptr->chunkdata == NULL)
   2256    {
   2257      png_warning(png_ptr, "No memory to process iTXt chunk.");
   2258      return;
   2259    }
   2260    slength = (png_size_t)length;
   2261    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2262    if (png_crc_finish(png_ptr, 0))
   2263    {
   2264       png_free(png_ptr, png_ptr->chunkdata);
   2265       png_ptr->chunkdata = NULL;
   2266       return;
   2267    }
   2268 
   2269    png_ptr->chunkdata[slength] = 0x00;
   2270 
   2271    for (lang = png_ptr->chunkdata; *lang; lang++)
   2272       /* Empty loop */ ;
   2273    lang++;        /* Skip NUL separator */
   2274 
   2275    /* iTXt must have a language tag (possibly empty), two compression bytes,
   2276     * translated keyword (possibly empty), and possibly some text after the
   2277     * keyword
   2278     */
   2279 
   2280    if (lang >= png_ptr->chunkdata + slength - 3)
   2281    {
   2282       png_warning(png_ptr, "Truncated iTXt chunk");
   2283       png_free(png_ptr, png_ptr->chunkdata);
   2284       png_ptr->chunkdata = NULL;
   2285       return;
   2286    }
   2287    else
   2288    {
   2289        comp_flag = *lang++;
   2290        comp_type = *lang++;
   2291    }
   2292 
   2293    for (lang_key = lang; *lang_key; lang_key++)
   2294       /* Empty loop */ ;
   2295    lang_key++;        /* Skip NUL separator */
   2296 
   2297    if (lang_key >= png_ptr->chunkdata + slength)
   2298    {
   2299       png_warning(png_ptr, "Truncated iTXt chunk");
   2300       png_free(png_ptr, png_ptr->chunkdata);
   2301       png_ptr->chunkdata = NULL;
   2302       return;
   2303    }
   2304 
   2305    for (text = lang_key; *text; text++)
   2306       /* Empty loop */ ;
   2307    text++;        /* Skip NUL separator */
   2308    if (text >= png_ptr->chunkdata + slength)
   2309    {
   2310       png_warning(png_ptr, "Malformed iTXt chunk");
   2311       png_free(png_ptr, png_ptr->chunkdata);
   2312       png_ptr->chunkdata = NULL;
   2313       return;
   2314    }
   2315 
   2316    prefix_len = text - png_ptr->chunkdata;
   2317 
   2318    key=png_ptr->chunkdata;
   2319    if (comp_flag)
   2320        png_decompress_chunk(png_ptr, comp_type,
   2321          (size_t)length, prefix_len, &data_len);
   2322    else
   2323        data_len = png_strlen(png_ptr->chunkdata + prefix_len);
   2324    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2325       (png_uint_32)png_sizeof(png_text));
   2326    if (text_ptr == NULL)
   2327    {
   2328      png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
   2329      png_free(png_ptr, png_ptr->chunkdata);
   2330      png_ptr->chunkdata = NULL;
   2331      return;
   2332    }
   2333    text_ptr->compression = (int)comp_flag + 1;
   2334    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
   2335    text_ptr->lang = png_ptr->chunkdata + (lang - key);
   2336    text_ptr->itxt_length = data_len;
   2337    text_ptr->text_length = 0;
   2338    text_ptr->key = png_ptr->chunkdata;
   2339    text_ptr->text = png_ptr->chunkdata + prefix_len;
   2340 
   2341    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2342 
   2343    png_free(png_ptr, text_ptr);
   2344    png_free(png_ptr, png_ptr->chunkdata);
   2345    png_ptr->chunkdata = NULL;
   2346    if (ret)
   2347      png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
   2348 }
   2349 #endif
   2350 
   2351 /* This function is called when we haven't found a handler for a
   2352    chunk.  If there isn't a problem with the chunk itself (ie bad
   2353    chunk name, CRC, or a critical chunk), the chunk is silently ignored
   2354    -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
   2355    case it will be saved away to be written out later. */
   2356 void /* PRIVATE */
   2357 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2358 {
   2359    png_uint_32 skip = 0;
   2360 
   2361    png_debug(1, "in png_handle_unknown");
   2362 
   2363 #ifdef PNG_USER_LIMITS_SUPPORTED
   2364    if (png_ptr->user_chunk_cache_max != 0)
   2365    {
   2366       if (png_ptr->user_chunk_cache_max == 1)
   2367       {
   2368          png_crc_finish(png_ptr, length);
   2369          return;
   2370       }
   2371       if (--png_ptr->user_chunk_cache_max == 1)
   2372       {
   2373          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
   2374          png_crc_finish(png_ptr, length);
   2375          return;
   2376       }
   2377    }
   2378 #endif
   2379 
   2380    if (png_ptr->mode & PNG_HAVE_IDAT)
   2381    {
   2382 #ifdef PNG_USE_LOCAL_ARRAYS
   2383       PNG_CONST PNG_IDAT;
   2384 #endif
   2385       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
   2386          png_ptr->mode |= PNG_AFTER_IDAT;
   2387    }
   2388 
   2389    if (!(png_ptr->chunk_name[0] & 0x20))
   2390    {
   2391 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   2392       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   2393            PNG_HANDLE_CHUNK_ALWAYS
   2394 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2395            && png_ptr->read_user_chunk_fn == NULL
   2396 #endif
   2397         )
   2398 #endif
   2399           png_chunk_error(png_ptr, "unknown critical chunk");
   2400    }
   2401 
   2402 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   2403    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   2404 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2405        || (png_ptr->read_user_chunk_fn != NULL)
   2406 #endif
   2407         )
   2408    {
   2409 #ifdef PNG_MAX_MALLOC_64K
   2410        if (length > (png_uint_32)65535L)
   2411        {
   2412            png_warning(png_ptr, "unknown chunk too large to fit in memory");
   2413            skip = length - (png_uint_32)65535L;
   2414            length = (png_uint_32)65535L;
   2415        }
   2416 #endif
   2417        png_memcpy((png_charp)png_ptr->unknown_chunk.name,
   2418                   (png_charp)png_ptr->chunk_name,
   2419                   png_sizeof(png_ptr->unknown_chunk.name));
   2420        png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
   2421            = '\0';
   2422        png_ptr->unknown_chunk.size = (png_size_t)length;
   2423        if (length == 0)
   2424          png_ptr->unknown_chunk.data = NULL;
   2425        else
   2426        {
   2427          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
   2428          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
   2429        }
   2430 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2431        if (png_ptr->read_user_chunk_fn != NULL)
   2432        {
   2433           /* Callback to user unknown chunk handler */
   2434           int ret;
   2435           ret = (*(png_ptr->read_user_chunk_fn))
   2436             (png_ptr, &png_ptr->unknown_chunk);
   2437           if (ret < 0)
   2438              png_chunk_error(png_ptr, "error in user chunk");
   2439           if (ret == 0)
   2440           {
   2441              if (!(png_ptr->chunk_name[0] & 0x20))
   2442 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   2443                 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   2444                      PNG_HANDLE_CHUNK_ALWAYS)
   2445 #endif
   2446                    png_chunk_error(png_ptr, "unknown critical chunk");
   2447              png_set_unknown_chunks(png_ptr, info_ptr,
   2448                &png_ptr->unknown_chunk, 1);
   2449           }
   2450        }
   2451        else
   2452 #endif
   2453        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
   2454        png_free(png_ptr, png_ptr->unknown_chunk.data);
   2455        png_ptr->unknown_chunk.data = NULL;
   2456    }
   2457    else
   2458 #endif
   2459       skip = length;
   2460 
   2461    png_crc_finish(png_ptr, skip);
   2462 
   2463 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
   2464    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
   2465 #endif
   2466 }
   2467 
   2468 /* This function is called to verify that a chunk name is valid.
   2469    This function can't have the "critical chunk check" incorporated
   2470    into it, since in the future we will need to be able to call user
   2471    functions to handle unknown critical chunks after we check that
   2472    the chunk name itself is valid. */
   2473 
   2474 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
   2475 
   2476 void /* PRIVATE */
   2477 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
   2478 {
   2479    png_debug(1, "in png_check_chunk_name");
   2480    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
   2481        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
   2482    {
   2483       png_chunk_error(png_ptr, "invalid chunk type");
   2484    }
   2485 }
   2486 
   2487 /* Combines the row recently read in with the existing pixels in the
   2488    row.  This routine takes care of alpha and transparency if requested.
   2489    This routine also handles the two methods of progressive display
   2490    of interlaced images, depending on the mask value.
   2491    The mask value describes which pixels are to be combined with
   2492    the row.  The pattern always repeats every 8 pixels, so just 8
   2493    bits are needed.  A one indicates the pixel is to be combined,
   2494    a zero indicates the pixel is to be skipped.  This is in addition
   2495    to any alpha or transparency value associated with the pixel.  If
   2496    you want all pixels to be combined, pass 0xff (255) in mask.  */
   2497 
   2498 void /* PRIVATE */
   2499 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
   2500 {
   2501    png_debug(1, "in png_combine_row");
   2502    if (mask == 0xff)
   2503    {
   2504       png_memcpy(row, png_ptr->row_buf + 1,
   2505          PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
   2506    }
   2507    else
   2508    {
   2509       switch (png_ptr->row_info.pixel_depth)
   2510       {
   2511          case 1:
   2512          {
   2513             png_bytep sp = png_ptr->row_buf + 1;
   2514             png_bytep dp = row;
   2515             int s_inc, s_start, s_end;
   2516             int m = 0x80;
   2517             int shift;
   2518             png_uint_32 i;
   2519             png_uint_32 row_width = png_ptr->width;
   2520 
   2521 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2522             if (png_ptr->transformations & PNG_PACKSWAP)
   2523             {
   2524                 s_start = 0;
   2525                 s_end = 7;
   2526                 s_inc = 1;
   2527             }
   2528             else
   2529 #endif
   2530             {
   2531                 s_start = 7;
   2532                 s_end = 0;
   2533                 s_inc = -1;
   2534             }
   2535 
   2536             shift = s_start;
   2537 
   2538             for (i = 0; i < row_width; i++)
   2539             {
   2540                if (m & mask)
   2541                {
   2542                   int value;
   2543 
   2544                   value = (*sp >> shift) & 0x01;
   2545                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
   2546                   *dp |= (png_byte)(value << shift);
   2547                }
   2548 
   2549                if (shift == s_end)
   2550                {
   2551                   shift = s_start;
   2552                   sp++;
   2553                   dp++;
   2554                }
   2555                else
   2556                   shift += s_inc;
   2557 
   2558                if (m == 1)
   2559                   m = 0x80;
   2560                else
   2561                   m >>= 1;
   2562             }
   2563             break;
   2564          }
   2565          case 2:
   2566          {
   2567             png_bytep sp = png_ptr->row_buf + 1;
   2568             png_bytep dp = row;
   2569             int s_start, s_end, s_inc;
   2570             int m = 0x80;
   2571             int shift;
   2572             png_uint_32 i;
   2573             png_uint_32 row_width = png_ptr->width;
   2574             int value;
   2575 
   2576 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2577             if (png_ptr->transformations & PNG_PACKSWAP)
   2578             {
   2579                s_start = 0;
   2580                s_end = 6;
   2581                s_inc = 2;
   2582             }
   2583             else
   2584 #endif
   2585             {
   2586                s_start = 6;
   2587                s_end = 0;
   2588                s_inc = -2;
   2589             }
   2590 
   2591             shift = s_start;
   2592 
   2593             for (i = 0; i < row_width; i++)
   2594             {
   2595                if (m & mask)
   2596                {
   2597                   value = (*sp >> shift) & 0x03;
   2598                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2599                   *dp |= (png_byte)(value << shift);
   2600                }
   2601 
   2602                if (shift == s_end)
   2603                {
   2604                   shift = s_start;
   2605                   sp++;
   2606                   dp++;
   2607                }
   2608                else
   2609                   shift += s_inc;
   2610                if (m == 1)
   2611                   m = 0x80;
   2612                else
   2613                   m >>= 1;
   2614             }
   2615             break;
   2616          }
   2617          case 4:
   2618          {
   2619             png_bytep sp = png_ptr->row_buf + 1;
   2620             png_bytep dp = row;
   2621             int s_start, s_end, s_inc;
   2622             int m = 0x80;
   2623             int shift;
   2624             png_uint_32 i;
   2625             png_uint_32 row_width = png_ptr->width;
   2626             int value;
   2627 
   2628 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2629             if (png_ptr->transformations & PNG_PACKSWAP)
   2630             {
   2631                s_start = 0;
   2632                s_end = 4;
   2633                s_inc = 4;
   2634             }
   2635             else
   2636 #endif
   2637             {
   2638                s_start = 4;
   2639                s_end = 0;
   2640                s_inc = -4;
   2641             }
   2642             shift = s_start;
   2643 
   2644             for (i = 0; i < row_width; i++)
   2645             {
   2646                if (m & mask)
   2647                {
   2648                   value = (*sp >> shift) & 0xf;
   2649                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2650                   *dp |= (png_byte)(value << shift);
   2651                }
   2652 
   2653                if (shift == s_end)
   2654                {
   2655                   shift = s_start;
   2656                   sp++;
   2657                   dp++;
   2658                }
   2659                else
   2660                   shift += s_inc;
   2661                if (m == 1)
   2662                   m = 0x80;
   2663                else
   2664                   m >>= 1;
   2665             }
   2666             break;
   2667          }
   2668          default:
   2669          {
   2670             png_bytep sp = png_ptr->row_buf + 1;
   2671             png_bytep dp = row;
   2672             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
   2673             png_uint_32 i;
   2674             png_uint_32 row_width = png_ptr->width;
   2675             png_byte m = 0x80;
   2676 
   2677 
   2678             for (i = 0; i < row_width; i++)
   2679             {
   2680                if (m & mask)
   2681                {
   2682                   png_memcpy(dp, sp, pixel_bytes);
   2683                }
   2684 
   2685                sp += pixel_bytes;
   2686                dp += pixel_bytes;
   2687 
   2688                if (m == 1)
   2689                   m = 0x80;
   2690                else
   2691                   m >>= 1;
   2692             }
   2693             break;
   2694          }
   2695       }
   2696    }
   2697 }
   2698 
   2699 #ifdef PNG_READ_INTERLACING_SUPPORTED
   2700 /* OLD pre-1.0.9 interface:
   2701 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
   2702    png_uint_32 transformations)
   2703  */
   2704 void /* PRIVATE */
   2705 png_do_read_interlace(png_structp png_ptr)
   2706 {
   2707    png_row_infop row_info = &(png_ptr->row_info);
   2708    png_bytep row = png_ptr->row_buf + 1;
   2709    int pass = png_ptr->pass;
   2710    png_uint_32 transformations = png_ptr->transformations;
   2711    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   2712    /* Offset to next interlace block */
   2713    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   2714 
   2715    png_debug(1, "in png_do_read_interlace");
   2716    if (row != NULL && row_info != NULL)
   2717    {
   2718       png_uint_32 final_width;
   2719 
   2720       final_width = row_info->width * png_pass_inc[pass];
   2721 
   2722       switch (row_info->pixel_depth)
   2723       {
   2724          case 1:
   2725          {
   2726             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
   2727             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
   2728             int sshift, dshift;
   2729             int s_start, s_end, s_inc;
   2730             int jstop = png_pass_inc[pass];
   2731             png_byte v;
   2732             png_uint_32 i;
   2733             int j;
   2734 
   2735 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2736             if (transformations & PNG_PACKSWAP)
   2737             {
   2738                 sshift = (int)((row_info->width + 7) & 0x07);
   2739                 dshift = (int)((final_width + 7) & 0x07);
   2740                 s_start = 7;
   2741                 s_end = 0;
   2742                 s_inc = -1;
   2743             }
   2744             else
   2745 #endif
   2746             {
   2747                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
   2748                 dshift = 7 - (int)((final_width + 7) & 0x07);
   2749                 s_start = 0;
   2750                 s_end = 7;
   2751                 s_inc = 1;
   2752             }
   2753 
   2754             for (i = 0; i < row_info->width; i++)
   2755             {
   2756                v = (png_byte)((*sp >> sshift) & 0x01);
   2757                for (j = 0; j < jstop; j++)
   2758                {
   2759                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
   2760                   *dp |= (png_byte)(v << dshift);
   2761                   if (dshift == s_end)
   2762                   {
   2763                      dshift = s_start;
   2764                      dp--;
   2765                   }
   2766                   else
   2767                      dshift += s_inc;
   2768                }
   2769                if (sshift == s_end)
   2770                {
   2771                   sshift = s_start;
   2772                   sp--;
   2773                }
   2774                else
   2775                   sshift += s_inc;
   2776             }
   2777             break;
   2778          }
   2779          case 2:
   2780          {
   2781             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
   2782             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
   2783             int sshift, dshift;
   2784             int s_start, s_end, s_inc;
   2785             int jstop = png_pass_inc[pass];
   2786             png_uint_32 i;
   2787 
   2788 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2789             if (transformations & PNG_PACKSWAP)
   2790             {
   2791                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
   2792                dshift = (int)(((final_width + 3) & 0x03) << 1);
   2793                s_start = 6;
   2794                s_end = 0;
   2795                s_inc = -2;
   2796             }
   2797             else
   2798 #endif
   2799             {
   2800                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
   2801                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
   2802                s_start = 0;
   2803                s_end = 6;
   2804                s_inc = 2;
   2805             }
   2806 
   2807             for (i = 0; i < row_info->width; i++)
   2808             {
   2809                png_byte v;
   2810                int j;
   2811 
   2812                v = (png_byte)((*sp >> sshift) & 0x03);
   2813                for (j = 0; j < jstop; j++)
   2814                {
   2815                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
   2816                   *dp |= (png_byte)(v << dshift);
   2817                   if (dshift == s_end)
   2818                   {
   2819                      dshift = s_start;
   2820                      dp--;
   2821                   }
   2822                   else
   2823                      dshift += s_inc;
   2824                }
   2825                if (sshift == s_end)
   2826                {
   2827                   sshift = s_start;
   2828                   sp--;
   2829                }
   2830                else
   2831                   sshift += s_inc;
   2832             }
   2833             break;
   2834          }
   2835          case 4:
   2836          {
   2837             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
   2838             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
   2839             int sshift, dshift;
   2840             int s_start, s_end, s_inc;
   2841             png_uint_32 i;
   2842             int jstop = png_pass_inc[pass];
   2843 
   2844 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2845             if (transformations & PNG_PACKSWAP)
   2846             {
   2847                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
   2848                dshift = (int)(((final_width + 1) & 0x01) << 2);
   2849                s_start = 4;
   2850                s_end = 0;
   2851                s_inc = -4;
   2852             }
   2853             else
   2854 #endif
   2855             {
   2856                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
   2857                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
   2858                s_start = 0;
   2859                s_end = 4;
   2860                s_inc = 4;
   2861             }
   2862 
   2863             for (i = 0; i < row_info->width; i++)
   2864             {
   2865                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
   2866                int j;
   2867 
   2868                for (j = 0; j < jstop; j++)
   2869                {
   2870                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
   2871                   *dp |= (png_byte)(v << dshift);
   2872                   if (dshift == s_end)
   2873                   {
   2874                      dshift = s_start;
   2875                      dp--;
   2876                   }
   2877                   else
   2878                      dshift += s_inc;
   2879                }
   2880                if (sshift == s_end)
   2881                {
   2882                   sshift = s_start;
   2883                   sp--;
   2884                }
   2885                else
   2886                   sshift += s_inc;
   2887             }
   2888             break;
   2889          }
   2890          default:
   2891          {
   2892             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
   2893             png_bytep sp = row + (png_size_t)(row_info->width - 1)
   2894                 * pixel_bytes;
   2895             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
   2896 
   2897             int jstop = png_pass_inc[pass];
   2898             png_uint_32 i;
   2899 
   2900             for (i = 0; i < row_info->width; i++)
   2901             {
   2902                png_byte v[8];
   2903                int j;
   2904 
   2905                png_memcpy(v, sp, pixel_bytes);
   2906                for (j = 0; j < jstop; j++)
   2907                {
   2908                   png_memcpy(dp, v, pixel_bytes);
   2909                   dp -= pixel_bytes;
   2910                }
   2911                sp -= pixel_bytes;
   2912             }
   2913             break;
   2914          }
   2915       }
   2916       row_info->width = final_width;
   2917       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
   2918    }
   2919 #ifndef PNG_READ_PACKSWAP_SUPPORTED
   2920    transformations = transformations; /* Silence compiler warning */
   2921 #endif
   2922 }
   2923 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   2924 
   2925 void /* PRIVATE */
   2926 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
   2927    png_bytep prev_row, int filter)
   2928 {
   2929    png_debug(1, "in png_read_filter_row");
   2930    png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
   2931    switch (filter)
   2932    {
   2933       case PNG_FILTER_VALUE_NONE:
   2934          break;
   2935       case PNG_FILTER_VALUE_SUB:
   2936       {
   2937          png_uint_32 i;
   2938          png_uint_32 istop = row_info->rowbytes;
   2939          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   2940          png_bytep rp = row + bpp;
   2941          png_bytep lp = row;
   2942 
   2943          for (i = bpp; i < istop; i++)
   2944          {
   2945             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
   2946             rp++;
   2947          }
   2948          break;
   2949       }
   2950       case PNG_FILTER_VALUE_UP:
   2951       {
   2952          png_uint_32 i;
   2953          png_uint_32 istop = row_info->rowbytes;
   2954          png_bytep rp = row;
   2955          png_bytep pp = prev_row;
   2956 
   2957          for (i = 0; i < istop; i++)
   2958          {
   2959             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
   2960             rp++;
   2961          }
   2962          break;
   2963       }
   2964       case PNG_FILTER_VALUE_AVG:
   2965       {
   2966          png_uint_32 i;
   2967          png_bytep rp = row;
   2968          png_bytep pp = prev_row;
   2969          png_bytep lp = row;
   2970          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   2971          png_uint_32 istop = row_info->rowbytes - bpp;
   2972 
   2973          for (i = 0; i < bpp; i++)
   2974          {
   2975             *rp = (png_byte)(((int)(*rp) +
   2976                ((int)(*pp++) / 2 )) & 0xff);
   2977             rp++;
   2978          }
   2979 
   2980          for (i = 0; i < istop; i++)
   2981          {
   2982             *rp = (png_byte)(((int)(*rp) +
   2983                (int)(*pp++ + *lp++) / 2 ) & 0xff);
   2984             rp++;
   2985          }
   2986          break;
   2987       }
   2988       case PNG_FILTER_VALUE_PAETH:
   2989       {
   2990          png_uint_32 i;
   2991          png_bytep rp = row;
   2992          png_bytep pp = prev_row;
   2993          png_bytep lp = row;
   2994          png_bytep cp = prev_row;
   2995          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   2996          png_uint_32 istop=row_info->rowbytes - bpp;
   2997 
   2998          for (i = 0; i < bpp; i++)
   2999          {
   3000             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
   3001             rp++;
   3002          }
   3003 
   3004          for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
   3005          {
   3006             int a, b, c, pa, pb, pc, p;
   3007 
   3008             a = *lp++;
   3009             b = *pp++;
   3010             c = *cp++;
   3011 
   3012             p = b - c;
   3013             pc = a - c;
   3014 
   3015 #ifdef PNG_USE_ABS
   3016             pa = abs(p);
   3017             pb = abs(pc);
   3018             pc = abs(p + pc);
   3019 #else
   3020             pa = p < 0 ? -p : p;
   3021             pb = pc < 0 ? -pc : pc;
   3022             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
   3023 #endif
   3024 
   3025             /*
   3026                if (pa <= pb && pa <= pc)
   3027                   p = a;
   3028                else if (pb <= pc)
   3029                   p = b;
   3030                else
   3031                   p = c;
   3032              */
   3033 
   3034             p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
   3035 
   3036             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
   3037             rp++;
   3038          }
   3039          break;
   3040       }
   3041       default:
   3042          png_warning(png_ptr, "Ignoring bad adaptive filter type");
   3043          *row = 0;
   3044          break;
   3045    }
   3046 }
   3047 
   3048 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
   3049 void /* PRIVATE */
   3050 png_read_finish_row(png_structp png_ptr)
   3051 {
   3052 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3053    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   3054 
   3055    /* Start of interlace block */
   3056    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
   3057 
   3058    /* Offset to next interlace block */
   3059    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   3060 
   3061    /* Start of interlace block in the y direction */
   3062    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
   3063 
   3064    /* Offset to next interlace block in the y direction */
   3065    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
   3066 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3067 
   3068    png_debug(1, "in png_read_finish_row");
   3069    png_ptr->row_number++;
   3070    if (png_ptr->row_number < png_ptr->num_rows)
   3071       return;
   3072 
   3073 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3074    if (png_ptr->interlaced)
   3075    {
   3076       png_ptr->row_number = 0;
   3077       png_memset_check(png_ptr, png_ptr->prev_row, 0,
   3078          png_ptr->rowbytes + 1);
   3079       do
   3080       {
   3081          png_ptr->pass++;
   3082          if (png_ptr->pass >= 7)
   3083             break;
   3084          png_ptr->iwidth = (png_ptr->width +
   3085             png_pass_inc[png_ptr->pass] - 1 -
   3086             png_pass_start[png_ptr->pass]) /
   3087             png_pass_inc[png_ptr->pass];
   3088 
   3089          if (!(png_ptr->transformations & PNG_INTERLACE))
   3090          {
   3091             png_ptr->num_rows = (png_ptr->height +
   3092                png_pass_yinc[png_ptr->pass] - 1 -
   3093                png_pass_ystart[png_ptr->pass]) /
   3094                png_pass_yinc[png_ptr->pass];
   3095             if (!(png_ptr->num_rows))
   3096                continue;
   3097          }
   3098          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
   3099             break;
   3100       } while (png_ptr->iwidth == 0);
   3101 
   3102       if (png_ptr->pass < 7)
   3103          return;
   3104    }
   3105 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3106 
   3107    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   3108    {
   3109 #ifdef PNG_USE_LOCAL_ARRAYS
   3110       PNG_CONST PNG_IDAT;
   3111 #endif
   3112       char extra;
   3113       int ret;
   3114 
   3115       png_ptr->zstream.next_out = (Byte *)&extra;
   3116       png_ptr->zstream.avail_out = (uInt)1;
   3117       for (;;)
   3118       {
   3119          if (!(png_ptr->zstream.avail_in))
   3120          {
   3121             while (!png_ptr->idat_size)
   3122             {
   3123                png_byte chunk_length[4];
   3124 
   3125                png_crc_finish(png_ptr, 0);
   3126 
   3127                png_read_data(png_ptr, chunk_length, 4);
   3128                png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
   3129                png_reset_crc(png_ptr);
   3130                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
   3131                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   3132                   png_error(png_ptr, "Not enough image data");
   3133 
   3134             }
   3135             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
   3136             png_ptr->zstream.next_in = png_ptr->zbuf;
   3137             if (png_ptr->zbuf_size > png_ptr->idat_size)
   3138                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
   3139             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
   3140             png_ptr->idat_size -= png_ptr->zstream.avail_in;
   3141          }
   3142          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
   3143          if (ret == Z_STREAM_END)
   3144          {
   3145             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
   3146                png_ptr->idat_size)
   3147                png_warning(png_ptr, "Extra compressed data.");
   3148             png_ptr->mode |= PNG_AFTER_IDAT;
   3149             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   3150             break;
   3151          }
   3152          if (ret != Z_OK)
   3153             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
   3154                       "Decompression Error");
   3155 
   3156          if (!(png_ptr->zstream.avail_out))
   3157          {
   3158             png_warning(png_ptr, "Extra compressed data.");
   3159             png_ptr->mode |= PNG_AFTER_IDAT;
   3160             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   3161             break;
   3162          }
   3163 
   3164       }
   3165       png_ptr->zstream.avail_out = 0;
   3166    }
   3167 
   3168    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
   3169       png_warning(png_ptr, "Extra compression data.");
   3170 
   3171    inflateReset(&png_ptr->zstream);
   3172 
   3173    png_ptr->mode |= PNG_AFTER_IDAT;
   3174 }
   3175 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
   3176 
   3177 void /* PRIVATE */
   3178 png_read_start_row(png_structp png_ptr)
   3179 {
   3180 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3181    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   3182 
   3183    /* Start of interlace block */
   3184    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
   3185 
   3186    /* Offset to next interlace block */
   3187    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   3188 
   3189    /* Start of interlace block in the y direction */
   3190    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
   3191 
   3192    /* Offset to next interlace block in the y direction */
   3193    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
   3194 #endif
   3195 
   3196    int max_pixel_depth;
   3197    png_size_t row_bytes;
   3198 
   3199    png_debug(1, "in png_read_start_row");
   3200    png_ptr->zstream.avail_in = 0;
   3201    png_init_read_transformations(png_ptr);
   3202 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3203    if (png_ptr->interlaced)
   3204    {
   3205       if (!(png_ptr->transformations & PNG_INTERLACE))
   3206          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
   3207             png_pass_ystart[0]) / png_pass_yinc[0];
   3208       else
   3209          png_ptr->num_rows = png_ptr->height;
   3210 
   3211       png_ptr->iwidth = (png_ptr->width +
   3212          png_pass_inc[png_ptr->pass] - 1 -
   3213          png_pass_start[png_ptr->pass]) /
   3214          png_pass_inc[png_ptr->pass];
   3215    }
   3216    else
   3217 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3218    {
   3219       png_ptr->num_rows = png_ptr->height;
   3220       png_ptr->iwidth = png_ptr->width;
   3221    }
   3222    max_pixel_depth = png_ptr->pixel_depth;
   3223 
   3224 #ifdef PNG_READ_PACK_SUPPORTED
   3225    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
   3226       max_pixel_depth = 8;
   3227 #endif
   3228 
   3229 #ifdef PNG_READ_EXPAND_SUPPORTED
   3230    if (png_ptr->transformations & PNG_EXPAND)
   3231    {
   3232       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   3233       {
   3234          if (png_ptr->num_trans)
   3235             max_pixel_depth = 32;
   3236          else
   3237             max_pixel_depth = 24;
   3238       }
   3239       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
   3240       {
   3241          if (max_pixel_depth < 8)
   3242             max_pixel_depth = 8;
   3243          if (png_ptr->num_trans)
   3244             max_pixel_depth *= 2;
   3245       }
   3246       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   3247       {
   3248          if (png_ptr->num_trans)
   3249          {
   3250             max_pixel_depth *= 4;
   3251             max_pixel_depth /= 3;
   3252          }
   3253       }
   3254    }
   3255 #endif
   3256 
   3257 #ifdef PNG_READ_FILLER_SUPPORTED
   3258    if (png_ptr->transformations & (PNG_FILLER))
   3259    {
   3260       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   3261          max_pixel_depth = 32;
   3262       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
   3263       {
   3264          if (max_pixel_depth <= 8)
   3265             max_pixel_depth = 16;
   3266          else
   3267             max_pixel_depth = 32;
   3268       }
   3269       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   3270       {
   3271          if (max_pixel_depth <= 32)
   3272             max_pixel_depth = 32;
   3273          else
   3274             max_pixel_depth = 64;
   3275       }
   3276    }
   3277 #endif
   3278 
   3279 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   3280    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   3281    {
   3282       if (
   3283 #ifdef PNG_READ_EXPAND_SUPPORTED
   3284         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
   3285 #endif
   3286 #ifdef PNG_READ_FILLER_SUPPORTED
   3287         (png_ptr->transformations & (PNG_FILLER)) ||
   3288 #endif
   3289         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   3290       {
   3291          if (max_pixel_depth <= 16)
   3292             max_pixel_depth = 32;
   3293          else
   3294             max_pixel_depth = 64;
   3295       }
   3296       else
   3297       {
   3298          if (max_pixel_depth <= 8)
   3299            {
   3300              if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   3301                max_pixel_depth = 32;
   3302              else
   3303                max_pixel_depth = 24;
   3304            }
   3305          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   3306             max_pixel_depth = 64;
   3307          else
   3308             max_pixel_depth = 48;
   3309       }
   3310    }
   3311 #endif
   3312 
   3313 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
   3314 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
   3315    if (png_ptr->transformations & PNG_USER_TRANSFORM)
   3316      {
   3317        int user_pixel_depth = png_ptr->user_transform_depth*
   3318          png_ptr->user_transform_channels;
   3319        if (user_pixel_depth > max_pixel_depth)
   3320          max_pixel_depth=user_pixel_depth;
   3321      }
   3322 #endif
   3323 
   3324    /* Align the width on the next larger 8 pixels.  Mainly used
   3325     * for interlacing
   3326     */
   3327    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
   3328    /* Calculate the maximum bytes needed, adding a byte and a pixel
   3329     * for safety's sake
   3330     */
   3331    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
   3332       1 + ((max_pixel_depth + 7) >> 3);
   3333 #ifdef PNG_MAX_MALLOC_64K
   3334    if (row_bytes > (png_uint_32)65536L)
   3335       png_error(png_ptr, "This image requires a row greater than 64KB");
   3336 #endif
   3337 
   3338    if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
   3339    {
   3340      png_free(png_ptr, png_ptr->big_row_buf);
   3341      if (png_ptr->interlaced)
   3342         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
   3343             row_bytes + 64);
   3344      else
   3345         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
   3346             row_bytes + 64);
   3347      png_ptr->old_big_row_buf_size = row_bytes + 64;
   3348 
   3349      /* Use 32 bytes of padding before and after row_buf. */
   3350      png_ptr->row_buf = png_ptr->big_row_buf + 32;
   3351      png_ptr->old_big_row_buf_size = row_bytes + 64;
   3352    }
   3353 
   3354 #ifdef PNG_MAX_MALLOC_64K
   3355    if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
   3356       png_error(png_ptr, "This image requires a row greater than 64KB");
   3357 #endif
   3358    if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
   3359       png_error(png_ptr, "Row has too many bytes to allocate in memory.");
   3360 
   3361    if (row_bytes + 1 > png_ptr->old_prev_row_size)
   3362    {
   3363       png_free(png_ptr, png_ptr->prev_row);
   3364       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
   3365         row_bytes + 1));
   3366       png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
   3367       png_ptr->old_prev_row_size = row_bytes + 1;
   3368    }
   3369 
   3370    png_ptr->rowbytes = row_bytes;
   3371 
   3372    png_debug1(3, "width = %lu,", png_ptr->width);
   3373    png_debug1(3, "height = %lu,", png_ptr->height);
   3374    png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
   3375    png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
   3376    png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
   3377    png_debug1(3, "irowbytes = %lu",
   3378        PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
   3379 
   3380    png_ptr->flags |= PNG_FLAG_ROW_INIT;
   3381 }
   3382 #endif /* PNG_READ_SUPPORTED */
   3383