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