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