Home | History | Annotate | Download | only in libpng
      1 
      2 /* pngrutil.c - utilities to read a PNG file
      3  *
      4  * Last changed in libpng 1.2.44 [June 26, 2010]
      5  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
      6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      8  *
      9  * This code is released under the libpng license.
     10  * For conditions of distribution and use, see the disclaimer
     11  * and license in png.h
     12  *
     13  * This file contains routines that are only called from within
     14  * libpng itself during the course of reading an image.
     15  */
     16 
     17 #define PNG_INTERNAL
     18 #define PNG_NO_PEDANTIC_WARNINGS
     19 #include "png.h"
     20 #ifdef PNG_READ_SUPPORTED
     21 
     22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
     23 #  define WIN32_WCE_OLD
     24 #endif
     25 
     26 #ifdef PNG_FLOATING_POINT_SUPPORTED
     27 #  ifdef WIN32_WCE_OLD
     28 /* The strtod() function is not supported on WindowsCE */
     29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
     30     char **endptr)
     31 {
     32    double result = 0;
     33    int len;
     34    wchar_t *str, *end;
     35 
     36    len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
     37    str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
     38    if ( NULL != str )
     39    {
     40       MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
     41       result = wcstod(str, &end);
     42       len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
     43       *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
     44       png_free(png_ptr, str);
     45    }
     46    return result;
     47 }
     48 #  else
     49 #    define png_strtod(p,a,b) strtod(a,b)
     50 #  endif
     51 #endif
     52 
     53 png_uint_32 PNGAPI
     54 png_get_uint_31(png_structp png_ptr, png_bytep buf)
     55 {
     56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
     57    png_uint_32 i = png_get_uint_32(buf);
     58 #else
     59    /* Avoid an extra function call by inlining the result. */
     60    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
     61       ((png_uint_32)(*(buf + 1)) << 16) +
     62       ((png_uint_32)(*(buf + 2)) << 8) +
     63       (png_uint_32)(*(buf + 3));
     64 #endif
     65    if (i > PNG_UINT_31_MAX)
     66      png_error(png_ptr, "PNG unsigned integer out of range.");
     67    return (i);
     68 }
     69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
     70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
     71 png_uint_32 PNGAPI
     72 png_get_uint_32(png_bytep buf)
     73 {
     74    png_uint_32 i = ((png_uint_32)(*buf) << 24) +
     75       ((png_uint_32)(*(buf + 1)) << 16) +
     76       ((png_uint_32)(*(buf + 2)) << 8) +
     77       (png_uint_32)(*(buf + 3));
     78 
     79    return (i);
     80 }
     81 
     82 /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
     83  * data is stored in the PNG file in two's complement format, and it is
     84  * assumed that the machine format for signed integers is the same.
     85  */
     86 png_int_32 PNGAPI
     87 png_get_int_32(png_bytep buf)
     88 {
     89    png_int_32 i = ((png_int_32)(*buf) << 24) +
     90       ((png_int_32)(*(buf + 1)) << 16) +
     91       ((png_int_32)(*(buf + 2)) << 8) +
     92       (png_int_32)(*(buf + 3));
     93 
     94    return (i);
     95 }
     96 
     97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
     98 png_uint_16 PNGAPI
     99 png_get_uint_16(png_bytep buf)
    100 {
    101    png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
    102       (png_uint_16)(*(buf + 1)));
    103 
    104    return (i);
    105 }
    106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
    107 
    108 /* Read the chunk header (length + type name).
    109  * Put the type name into png_ptr->chunk_name, and return the length.
    110  */
    111 png_uint_32 /* PRIVATE */
    112 png_read_chunk_header(png_structp png_ptr)
    113 {
    114    png_byte buf[8];
    115    png_uint_32 length;
    116 
    117    /* Read the length and the chunk name */
    118    png_read_data(png_ptr, buf, 8);
    119    length = png_get_uint_31(png_ptr, buf);
    120 
    121    /* Put the chunk name into png_ptr->chunk_name */
    122    png_memcpy(png_ptr->chunk_name, buf + 4, 4);
    123 
    124    png_debug2(0, "Reading %s chunk, length = %lu",
    125       png_ptr->chunk_name, length);
    126 
    127    /* Reset the crc and run it over the chunk name */
    128    png_reset_crc(png_ptr);
    129    png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
    130 
    131    /* Check to see if chunk name is valid */
    132    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    133 
    134    return length;
    135 }
    136 
    137 /* Read data, and (optionally) run it through the CRC. */
    138 void /* PRIVATE */
    139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
    140 {
    141    if (png_ptr == NULL)
    142       return;
    143    png_read_data(png_ptr, buf, length);
    144    png_calculate_crc(png_ptr, buf, length);
    145 }
    146 
    147 #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    png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
   1833       length + 1);
   1834    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   1835    if (png_ptr->chunkdata == NULL)
   1836    {
   1837       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
   1838       png_crc_finish(png_ptr, length);
   1839       return;
   1840    }
   1841    slength = (png_size_t)length;
   1842    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   1843 
   1844    if (png_crc_finish(png_ptr, 0))
   1845    {
   1846       png_free(png_ptr, png_ptr->chunkdata);
   1847       png_ptr->chunkdata = NULL;
   1848       return;
   1849    }
   1850 
   1851    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
   1852 
   1853    ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
   1854 
   1855 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1856    width = png_strtod(png_ptr, ep, &vp);
   1857    if (*vp)
   1858    {
   1859       png_warning(png_ptr, "malformed width string in sCAL chunk");
   1860       png_free(png_ptr, png_ptr->chunkdata);
   1861       png_ptr->chunkdata = NULL;
   1862       return;
   1863    }
   1864 #else
   1865 #ifdef PNG_FIXED_POINT_SUPPORTED
   1866    swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
   1867    if (swidth == NULL)
   1868    {
   1869       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
   1870       png_free(png_ptr, png_ptr->chunkdata);
   1871       png_ptr->chunkdata = NULL;
   1872       return;
   1873    }
   1874    png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
   1875 #endif
   1876 #endif
   1877 
   1878    for (ep = png_ptr->chunkdata; *ep; ep++)
   1879       /* Empty loop */ ;
   1880    ep++;
   1881 
   1882    if (png_ptr->chunkdata + slength < ep)
   1883    {
   1884       png_warning(png_ptr, "Truncated sCAL chunk");
   1885 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1886       png_free(png_ptr, swidth);
   1887 #endif
   1888       png_free(png_ptr, png_ptr->chunkdata);
   1889       png_ptr->chunkdata = NULL;
   1890       return;
   1891    }
   1892 
   1893 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1894    height = png_strtod(png_ptr, ep, &vp);
   1895    if (*vp)
   1896    {
   1897       png_warning(png_ptr, "malformed height string in sCAL chunk");
   1898       png_free(png_ptr, png_ptr->chunkdata);
   1899       png_ptr->chunkdata = NULL;
   1900 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1901       png_free(png_ptr, swidth);
   1902 #endif
   1903       return;
   1904    }
   1905 #else
   1906 #ifdef PNG_FIXED_POINT_SUPPORTED
   1907    sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
   1908    if (sheight == NULL)
   1909    {
   1910       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
   1911       png_free(png_ptr, png_ptr->chunkdata);
   1912       png_ptr->chunkdata = NULL;
   1913 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1914       png_free(png_ptr, swidth);
   1915 #endif
   1916       return;
   1917    }
   1918    png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
   1919 #endif
   1920 #endif
   1921 
   1922    if (png_ptr->chunkdata + slength < ep
   1923 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1924       || width <= 0. || height <= 0.
   1925 #endif
   1926       )
   1927    {
   1928       png_warning(png_ptr, "Invalid sCAL data");
   1929       png_free(png_ptr, png_ptr->chunkdata);
   1930       png_ptr->chunkdata = NULL;
   1931 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1932       png_free(png_ptr, swidth);
   1933       png_free(png_ptr, sheight);
   1934 #endif
   1935       return;
   1936    }
   1937 
   1938 
   1939 #ifdef PNG_FLOATING_POINT_SUPPORTED
   1940    png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
   1941 #else
   1942 #ifdef PNG_FIXED_POINT_SUPPORTED
   1943    png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
   1944 #endif
   1945 #endif
   1946 
   1947    png_free(png_ptr, png_ptr->chunkdata);
   1948    png_ptr->chunkdata = NULL;
   1949 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
   1950    png_free(png_ptr, swidth);
   1951    png_free(png_ptr, sheight);
   1952 #endif
   1953 }
   1954 #endif
   1955 
   1956 #ifdef PNG_READ_tIME_SUPPORTED
   1957 void /* PRIVATE */
   1958 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   1959 {
   1960    png_byte buf[7];
   1961    png_time mod_time;
   1962 
   1963    png_debug(1, "in png_handle_tIME");
   1964 
   1965    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   1966       png_error(png_ptr, "Out of place tIME chunk");
   1967    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
   1968    {
   1969       png_warning(png_ptr, "Duplicate tIME chunk");
   1970       png_crc_finish(png_ptr, length);
   1971       return;
   1972    }
   1973 
   1974    if (png_ptr->mode & PNG_HAVE_IDAT)
   1975       png_ptr->mode |= PNG_AFTER_IDAT;
   1976 
   1977    if (length != 7)
   1978    {
   1979       png_warning(png_ptr, "Incorrect tIME chunk length");
   1980       png_crc_finish(png_ptr, length);
   1981       return;
   1982    }
   1983 
   1984    png_crc_read(png_ptr, buf, 7);
   1985    if (png_crc_finish(png_ptr, 0))
   1986       return;
   1987 
   1988    mod_time.second = buf[6];
   1989    mod_time.minute = buf[5];
   1990    mod_time.hour = buf[4];
   1991    mod_time.day = buf[3];
   1992    mod_time.month = buf[2];
   1993    mod_time.year = png_get_uint_16(buf);
   1994 
   1995    png_set_tIME(png_ptr, info_ptr, &mod_time);
   1996 }
   1997 #endif
   1998 
   1999 #ifdef PNG_READ_tEXt_SUPPORTED
   2000 /* Note: this does not properly handle chunks that are > 64K under DOS */
   2001 void /* PRIVATE */
   2002 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2003 {
   2004    png_textp text_ptr;
   2005    png_charp key;
   2006    png_charp text;
   2007    png_uint_32 skip = 0;
   2008    png_size_t slength;
   2009    int ret;
   2010 
   2011    png_debug(1, "in png_handle_tEXt");
   2012 
   2013 #ifdef PNG_USER_LIMITS_SUPPORTED
   2014    if (png_ptr->user_chunk_cache_max != 0)
   2015    {
   2016       if (png_ptr->user_chunk_cache_max == 1)
   2017       {
   2018          png_crc_finish(png_ptr, length);
   2019          return;
   2020       }
   2021       if (--png_ptr->user_chunk_cache_max == 1)
   2022       {
   2023          png_warning(png_ptr, "No space in chunk cache for tEXt");
   2024          png_crc_finish(png_ptr, length);
   2025          return;
   2026       }
   2027    }
   2028 #endif
   2029 
   2030    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2031       png_error(png_ptr, "Missing IHDR before tEXt");
   2032 
   2033    if (png_ptr->mode & PNG_HAVE_IDAT)
   2034       png_ptr->mode |= PNG_AFTER_IDAT;
   2035 
   2036 #ifdef PNG_MAX_MALLOC_64K
   2037    if (length > (png_uint_32)65535L)
   2038    {
   2039       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
   2040       skip = length - (png_uint_32)65535L;
   2041       length = (png_uint_32)65535L;
   2042    }
   2043 #endif
   2044 
   2045    png_free(png_ptr, png_ptr->chunkdata);
   2046 
   2047    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2048    if (png_ptr->chunkdata == NULL)
   2049    {
   2050      png_warning(png_ptr, "No memory to process text chunk.");
   2051      return;
   2052    }
   2053    slength = (png_size_t)length;
   2054    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2055 
   2056    if (png_crc_finish(png_ptr, skip))
   2057    {
   2058       png_free(png_ptr, png_ptr->chunkdata);
   2059       png_ptr->chunkdata = NULL;
   2060       return;
   2061    }
   2062 
   2063    key = png_ptr->chunkdata;
   2064 
   2065    key[slength] = 0x00;
   2066 
   2067    for (text = key; *text; text++)
   2068       /* Empty loop to find end of key */ ;
   2069 
   2070    if (text != key + slength)
   2071       text++;
   2072 
   2073    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2074       (png_uint_32)png_sizeof(png_text));
   2075    if (text_ptr == NULL)
   2076    {
   2077      png_warning(png_ptr, "Not enough memory to process text chunk.");
   2078      png_free(png_ptr, png_ptr->chunkdata);
   2079      png_ptr->chunkdata = NULL;
   2080      return;
   2081    }
   2082    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
   2083    text_ptr->key = key;
   2084 #ifdef PNG_iTXt_SUPPORTED
   2085    text_ptr->lang = NULL;
   2086    text_ptr->lang_key = NULL;
   2087    text_ptr->itxt_length = 0;
   2088 #endif
   2089    text_ptr->text = text;
   2090    text_ptr->text_length = png_strlen(text);
   2091 
   2092    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2093 
   2094    png_free(png_ptr, png_ptr->chunkdata);
   2095    png_ptr->chunkdata = NULL;
   2096    png_free(png_ptr, text_ptr);
   2097    if (ret)
   2098      png_warning(png_ptr, "Insufficient memory to process text chunk.");
   2099 }
   2100 #endif
   2101 
   2102 #ifdef PNG_READ_zTXt_SUPPORTED
   2103 /* Note: this does not correctly handle chunks that are > 64K under DOS */
   2104 void /* PRIVATE */
   2105 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2106 {
   2107    png_textp text_ptr;
   2108    png_charp text;
   2109    int comp_type;
   2110    int ret;
   2111    png_size_t slength, prefix_len, data_len;
   2112 
   2113    png_debug(1, "in png_handle_zTXt");
   2114 
   2115 #ifdef PNG_USER_LIMITS_SUPPORTED
   2116    if (png_ptr->user_chunk_cache_max != 0)
   2117    {
   2118       if (png_ptr->user_chunk_cache_max == 1)
   2119       {
   2120          png_crc_finish(png_ptr, length);
   2121          return;
   2122       }
   2123       if (--png_ptr->user_chunk_cache_max == 1)
   2124       {
   2125          png_warning(png_ptr, "No space in chunk cache for zTXt");
   2126          png_crc_finish(png_ptr, length);
   2127          return;
   2128       }
   2129    }
   2130 #endif
   2131 
   2132    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2133       png_error(png_ptr, "Missing IHDR before zTXt");
   2134 
   2135    if (png_ptr->mode & PNG_HAVE_IDAT)
   2136       png_ptr->mode |= PNG_AFTER_IDAT;
   2137 
   2138 #ifdef PNG_MAX_MALLOC_64K
   2139    /* We will no doubt have problems with chunks even half this size, but
   2140       there is no hard and fast rule to tell us where to stop. */
   2141    if (length > (png_uint_32)65535L)
   2142    {
   2143      png_warning(png_ptr, "zTXt chunk too large to fit in memory");
   2144      png_crc_finish(png_ptr, length);
   2145      return;
   2146    }
   2147 #endif
   2148 
   2149    png_free(png_ptr, png_ptr->chunkdata);
   2150    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2151    if (png_ptr->chunkdata == NULL)
   2152    {
   2153      png_warning(png_ptr, "Out of memory processing zTXt chunk.");
   2154      return;
   2155    }
   2156    slength = (png_size_t)length;
   2157    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2158    if (png_crc_finish(png_ptr, 0))
   2159    {
   2160       png_free(png_ptr, png_ptr->chunkdata);
   2161       png_ptr->chunkdata = NULL;
   2162       return;
   2163    }
   2164 
   2165    png_ptr->chunkdata[slength] = 0x00;
   2166 
   2167    for (text = png_ptr->chunkdata; *text; text++)
   2168       /* Empty loop */ ;
   2169 
   2170    /* zTXt must have some text after the chunkdataword */
   2171    if (text >= png_ptr->chunkdata + slength - 2)
   2172    {
   2173       png_warning(png_ptr, "Truncated zTXt chunk");
   2174       png_free(png_ptr, png_ptr->chunkdata);
   2175       png_ptr->chunkdata = NULL;
   2176       return;
   2177    }
   2178    else
   2179    {
   2180        comp_type = *(++text);
   2181        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
   2182        {
   2183           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
   2184           comp_type = PNG_TEXT_COMPRESSION_zTXt;
   2185        }
   2186        text++;        /* Skip the compression_method byte */
   2187    }
   2188    prefix_len = text - png_ptr->chunkdata;
   2189 
   2190    png_decompress_chunk(png_ptr, comp_type,
   2191      (png_size_t)length, prefix_len, &data_len);
   2192 
   2193    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2194       (png_uint_32)png_sizeof(png_text));
   2195    if (text_ptr == NULL)
   2196    {
   2197      png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
   2198      png_free(png_ptr, png_ptr->chunkdata);
   2199      png_ptr->chunkdata = NULL;
   2200      return;
   2201    }
   2202    text_ptr->compression = comp_type;
   2203    text_ptr->key = png_ptr->chunkdata;
   2204 #ifdef PNG_iTXt_SUPPORTED
   2205    text_ptr->lang = NULL;
   2206    text_ptr->lang_key = NULL;
   2207    text_ptr->itxt_length = 0;
   2208 #endif
   2209    text_ptr->text = png_ptr->chunkdata + prefix_len;
   2210    text_ptr->text_length = data_len;
   2211 
   2212    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2213 
   2214    png_free(png_ptr, text_ptr);
   2215    png_free(png_ptr, png_ptr->chunkdata);
   2216    png_ptr->chunkdata = NULL;
   2217    if (ret)
   2218      png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
   2219 }
   2220 #endif
   2221 
   2222 #ifdef PNG_READ_iTXt_SUPPORTED
   2223 /* Note: this does not correctly handle chunks that are > 64K under DOS */
   2224 void /* PRIVATE */
   2225 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2226 {
   2227    png_textp text_ptr;
   2228    png_charp key, lang, text, lang_key;
   2229    int comp_flag;
   2230    int comp_type = 0;
   2231    int ret;
   2232    png_size_t slength, prefix_len, data_len;
   2233 
   2234    png_debug(1, "in png_handle_iTXt");
   2235 
   2236 #ifdef PNG_USER_LIMITS_SUPPORTED
   2237    if (png_ptr->user_chunk_cache_max != 0)
   2238    {
   2239       if (png_ptr->user_chunk_cache_max == 1)
   2240       {
   2241          png_crc_finish(png_ptr, length);
   2242          return;
   2243       }
   2244       if (--png_ptr->user_chunk_cache_max == 1)
   2245       {
   2246          png_warning(png_ptr, "No space in chunk cache for iTXt");
   2247          png_crc_finish(png_ptr, length);
   2248          return;
   2249       }
   2250    }
   2251 #endif
   2252 
   2253    if (!(png_ptr->mode & PNG_HAVE_IHDR))
   2254       png_error(png_ptr, "Missing IHDR before iTXt");
   2255 
   2256    if (png_ptr->mode & PNG_HAVE_IDAT)
   2257       png_ptr->mode |= PNG_AFTER_IDAT;
   2258 
   2259 #ifdef PNG_MAX_MALLOC_64K
   2260    /* We will no doubt have problems with chunks even half this size, but
   2261       there is no hard and fast rule to tell us where to stop. */
   2262    if (length > (png_uint_32)65535L)
   2263    {
   2264      png_warning(png_ptr, "iTXt chunk too large to fit in memory");
   2265      png_crc_finish(png_ptr, length);
   2266      return;
   2267    }
   2268 #endif
   2269 
   2270    png_free(png_ptr, png_ptr->chunkdata);
   2271    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
   2272    if (png_ptr->chunkdata == NULL)
   2273    {
   2274      png_warning(png_ptr, "No memory to process iTXt chunk.");
   2275      return;
   2276    }
   2277    slength = (png_size_t)length;
   2278    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
   2279    if (png_crc_finish(png_ptr, 0))
   2280    {
   2281       png_free(png_ptr, png_ptr->chunkdata);
   2282       png_ptr->chunkdata = NULL;
   2283       return;
   2284    }
   2285 
   2286    png_ptr->chunkdata[slength] = 0x00;
   2287 
   2288    for (lang = png_ptr->chunkdata; *lang; lang++)
   2289       /* Empty loop */ ;
   2290    lang++;        /* Skip NUL separator */
   2291 
   2292    /* iTXt must have a language tag (possibly empty), two compression bytes,
   2293     * translated keyword (possibly empty), and possibly some text after the
   2294     * keyword
   2295     */
   2296 
   2297    if (lang >= png_ptr->chunkdata + slength - 3)
   2298    {
   2299       png_warning(png_ptr, "Truncated iTXt chunk");
   2300       png_free(png_ptr, png_ptr->chunkdata);
   2301       png_ptr->chunkdata = NULL;
   2302       return;
   2303    }
   2304    else
   2305    {
   2306        comp_flag = *lang++;
   2307        comp_type = *lang++;
   2308    }
   2309 
   2310    for (lang_key = lang; *lang_key; lang_key++)
   2311       /* Empty loop */ ;
   2312    lang_key++;        /* Skip NUL separator */
   2313 
   2314    if (lang_key >= png_ptr->chunkdata + slength)
   2315    {
   2316       png_warning(png_ptr, "Truncated iTXt chunk");
   2317       png_free(png_ptr, png_ptr->chunkdata);
   2318       png_ptr->chunkdata = NULL;
   2319       return;
   2320    }
   2321 
   2322    for (text = lang_key; *text; text++)
   2323       /* Empty loop */ ;
   2324    text++;        /* Skip NUL separator */
   2325    if (text >= png_ptr->chunkdata + slength)
   2326    {
   2327       png_warning(png_ptr, "Malformed iTXt chunk");
   2328       png_free(png_ptr, png_ptr->chunkdata);
   2329       png_ptr->chunkdata = NULL;
   2330       return;
   2331    }
   2332 
   2333    prefix_len = text - png_ptr->chunkdata;
   2334 
   2335    key=png_ptr->chunkdata;
   2336    if (comp_flag)
   2337        png_decompress_chunk(png_ptr, comp_type,
   2338          (size_t)length, prefix_len, &data_len);
   2339    else
   2340        data_len = png_strlen(png_ptr->chunkdata + prefix_len);
   2341    text_ptr = (png_textp)png_malloc_warn(png_ptr,
   2342       (png_uint_32)png_sizeof(png_text));
   2343    if (text_ptr == NULL)
   2344    {
   2345      png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
   2346      png_free(png_ptr, png_ptr->chunkdata);
   2347      png_ptr->chunkdata = NULL;
   2348      return;
   2349    }
   2350    text_ptr->compression = (int)comp_flag + 1;
   2351    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
   2352    text_ptr->lang = png_ptr->chunkdata + (lang - key);
   2353    text_ptr->itxt_length = data_len;
   2354    text_ptr->text_length = 0;
   2355    text_ptr->key = png_ptr->chunkdata;
   2356    text_ptr->text = png_ptr->chunkdata + prefix_len;
   2357 
   2358    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   2359 
   2360    png_free(png_ptr, text_ptr);
   2361    png_free(png_ptr, png_ptr->chunkdata);
   2362    png_ptr->chunkdata = NULL;
   2363    if (ret)
   2364      png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
   2365 }
   2366 #endif
   2367 
   2368 /* This function is called when we haven't found a handler for a
   2369    chunk.  If there isn't a problem with the chunk itself (ie bad
   2370    chunk name, CRC, or a critical chunk), the chunk is silently ignored
   2371    -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
   2372    case it will be saved away to be written out later. */
   2373 void /* PRIVATE */
   2374 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
   2375 {
   2376    png_uint_32 skip = 0;
   2377 
   2378    png_debug(1, "in png_handle_unknown");
   2379 
   2380 #ifdef PNG_USER_LIMITS_SUPPORTED
   2381    if (png_ptr->user_chunk_cache_max != 0)
   2382    {
   2383       if (png_ptr->user_chunk_cache_max == 1)
   2384       {
   2385          png_crc_finish(png_ptr, length);
   2386          return;
   2387       }
   2388       if (--png_ptr->user_chunk_cache_max == 1)
   2389       {
   2390          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
   2391          png_crc_finish(png_ptr, length);
   2392          return;
   2393       }
   2394    }
   2395 #endif
   2396 
   2397    if (png_ptr->mode & PNG_HAVE_IDAT)
   2398    {
   2399 #ifdef PNG_USE_LOCAL_ARRAYS
   2400       PNG_CONST PNG_IDAT;
   2401 #endif
   2402       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
   2403          png_ptr->mode |= PNG_AFTER_IDAT;
   2404    }
   2405 
   2406    if (!(png_ptr->chunk_name[0] & 0x20))
   2407    {
   2408 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   2409       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   2410            PNG_HANDLE_CHUNK_ALWAYS
   2411 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2412            && png_ptr->read_user_chunk_fn == NULL
   2413 #endif
   2414         )
   2415 #endif
   2416           png_chunk_error(png_ptr, "unknown critical chunk");
   2417    }
   2418 
   2419 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   2420    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   2421 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2422        || (png_ptr->read_user_chunk_fn != NULL)
   2423 #endif
   2424         )
   2425    {
   2426 #ifdef PNG_MAX_MALLOC_64K
   2427        if (length > (png_uint_32)65535L)
   2428        {
   2429            png_warning(png_ptr, "unknown chunk too large to fit in memory");
   2430            skip = length - (png_uint_32)65535L;
   2431            length = (png_uint_32)65535L;
   2432        }
   2433 #endif
   2434        png_memcpy((png_charp)png_ptr->unknown_chunk.name,
   2435                   (png_charp)png_ptr->chunk_name,
   2436                   png_sizeof(png_ptr->unknown_chunk.name));
   2437        png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
   2438            = '\0';
   2439        png_ptr->unknown_chunk.size = (png_size_t)length;
   2440        if (length == 0)
   2441          png_ptr->unknown_chunk.data = NULL;
   2442        else
   2443        {
   2444          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
   2445          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
   2446        }
   2447 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   2448        if (png_ptr->read_user_chunk_fn != NULL)
   2449        {
   2450           /* Callback to user unknown chunk handler */
   2451           int ret;
   2452           ret = (*(png_ptr->read_user_chunk_fn))
   2453             (png_ptr, &png_ptr->unknown_chunk);
   2454           if (ret < 0)
   2455              png_chunk_error(png_ptr, "error in user chunk");
   2456           if (ret == 0)
   2457           {
   2458              if (!(png_ptr->chunk_name[0] & 0x20))
   2459 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   2460                 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   2461                      PNG_HANDLE_CHUNK_ALWAYS)
   2462 #endif
   2463                    png_chunk_error(png_ptr, "unknown critical chunk");
   2464              png_set_unknown_chunks(png_ptr, info_ptr,
   2465                &png_ptr->unknown_chunk, 1);
   2466           }
   2467        }
   2468        else
   2469 #endif
   2470        png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
   2471        png_free(png_ptr, png_ptr->unknown_chunk.data);
   2472        png_ptr->unknown_chunk.data = NULL;
   2473    }
   2474    else
   2475 #endif
   2476       skip = length;
   2477 
   2478    png_crc_finish(png_ptr, skip);
   2479 
   2480 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
   2481    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
   2482 #endif
   2483 }
   2484 
   2485 /* This function is called to verify that a chunk name is valid.
   2486    This function can't have the "critical chunk check" incorporated
   2487    into it, since in the future we will need to be able to call user
   2488    functions to handle unknown critical chunks after we check that
   2489    the chunk name itself is valid. */
   2490 
   2491 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
   2492 
   2493 void /* PRIVATE */
   2494 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
   2495 {
   2496    png_debug(1, "in png_check_chunk_name");
   2497    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
   2498        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
   2499    {
   2500       png_chunk_error(png_ptr, "invalid chunk type");
   2501    }
   2502 }
   2503 
   2504 /* Combines the row recently read in with the existing pixels in the
   2505    row.  This routine takes care of alpha and transparency if requested.
   2506    This routine also handles the two methods of progressive display
   2507    of interlaced images, depending on the mask value.
   2508    The mask value describes which pixels are to be combined with
   2509    the row.  The pattern always repeats every 8 pixels, so just 8
   2510    bits are needed.  A one indicates the pixel is to be combined,
   2511    a zero indicates the pixel is to be skipped.  This is in addition
   2512    to any alpha or transparency value associated with the pixel.  If
   2513    you want all pixels to be combined, pass 0xff (255) in mask.  */
   2514 
   2515 void /* PRIVATE */
   2516 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
   2517 {
   2518    png_debug(1, "in png_combine_row");
   2519    if (mask == 0xff)
   2520    {
   2521       png_memcpy(row, png_ptr->row_buf + 1,
   2522          PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
   2523    }
   2524    else
   2525    {
   2526       switch (png_ptr->row_info.pixel_depth)
   2527       {
   2528          case 1:
   2529          {
   2530             png_bytep sp = png_ptr->row_buf + 1;
   2531             png_bytep dp = row;
   2532             int s_inc, s_start, s_end;
   2533             int m = 0x80;
   2534             int shift;
   2535             png_uint_32 i;
   2536             png_uint_32 row_width = png_ptr->width;
   2537 
   2538 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2539             if (png_ptr->transformations & PNG_PACKSWAP)
   2540             {
   2541                 s_start = 0;
   2542                 s_end = 7;
   2543                 s_inc = 1;
   2544             }
   2545             else
   2546 #endif
   2547             {
   2548                 s_start = 7;
   2549                 s_end = 0;
   2550                 s_inc = -1;
   2551             }
   2552 
   2553             shift = s_start;
   2554 
   2555             for (i = 0; i < row_width; i++)
   2556             {
   2557                if (m & mask)
   2558                {
   2559                   int value;
   2560 
   2561                   value = (*sp >> shift) & 0x01;
   2562                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
   2563                   *dp |= (png_byte)(value << shift);
   2564                }
   2565 
   2566                if (shift == s_end)
   2567                {
   2568                   shift = s_start;
   2569                   sp++;
   2570                   dp++;
   2571                }
   2572                else
   2573                   shift += s_inc;
   2574 
   2575                if (m == 1)
   2576                   m = 0x80;
   2577                else
   2578                   m >>= 1;
   2579             }
   2580             break;
   2581          }
   2582          case 2:
   2583          {
   2584             png_bytep sp = png_ptr->row_buf + 1;
   2585             png_bytep dp = row;
   2586             int s_start, s_end, s_inc;
   2587             int m = 0x80;
   2588             int shift;
   2589             png_uint_32 i;
   2590             png_uint_32 row_width = png_ptr->width;
   2591             int value;
   2592 
   2593 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2594             if (png_ptr->transformations & PNG_PACKSWAP)
   2595             {
   2596                s_start = 0;
   2597                s_end = 6;
   2598                s_inc = 2;
   2599             }
   2600             else
   2601 #endif
   2602             {
   2603                s_start = 6;
   2604                s_end = 0;
   2605                s_inc = -2;
   2606             }
   2607 
   2608             shift = s_start;
   2609 
   2610             for (i = 0; i < row_width; i++)
   2611             {
   2612                if (m & mask)
   2613                {
   2614                   value = (*sp >> shift) & 0x03;
   2615                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
   2616                   *dp |= (png_byte)(value << shift);
   2617                }
   2618 
   2619                if (shift == s_end)
   2620                {
   2621                   shift = s_start;
   2622                   sp++;
   2623                   dp++;
   2624                }
   2625                else
   2626                   shift += s_inc;
   2627                if (m == 1)
   2628                   m = 0x80;
   2629                else
   2630                   m >>= 1;
   2631             }
   2632             break;
   2633          }
   2634          case 4:
   2635          {
   2636             png_bytep sp = png_ptr->row_buf + 1;
   2637             png_bytep dp = row;
   2638             int s_start, s_end, s_inc;
   2639             int m = 0x80;
   2640             int shift;
   2641             png_uint_32 i;
   2642             png_uint_32 row_width = png_ptr->width;
   2643             int value;
   2644 
   2645 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2646             if (png_ptr->transformations & PNG_PACKSWAP)
   2647             {
   2648                s_start = 0;
   2649                s_end = 4;
   2650                s_inc = 4;
   2651             }
   2652             else
   2653 #endif
   2654             {
   2655                s_start = 4;
   2656                s_end = 0;
   2657                s_inc = -4;
   2658             }
   2659             shift = s_start;
   2660 
   2661             for (i = 0; i < row_width; i++)
   2662             {
   2663                if (m & mask)
   2664                {
   2665                   value = (*sp >> shift) & 0xf;
   2666                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
   2667                   *dp |= (png_byte)(value << shift);
   2668                }
   2669 
   2670                if (shift == s_end)
   2671                {
   2672                   shift = s_start;
   2673                   sp++;
   2674                   dp++;
   2675                }
   2676                else
   2677                   shift += s_inc;
   2678                if (m == 1)
   2679                   m = 0x80;
   2680                else
   2681                   m >>= 1;
   2682             }
   2683             break;
   2684          }
   2685          default:
   2686          {
   2687             png_bytep sp = png_ptr->row_buf + 1;
   2688             png_bytep dp = row;
   2689             png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
   2690             png_uint_32 i;
   2691             png_uint_32 row_width = png_ptr->width;
   2692             png_byte m = 0x80;
   2693 
   2694 
   2695             for (i = 0; i < row_width; i++)
   2696             {
   2697                if (m & mask)
   2698                {
   2699                   png_memcpy(dp, sp, pixel_bytes);
   2700                }
   2701 
   2702                sp += pixel_bytes;
   2703                dp += pixel_bytes;
   2704 
   2705                if (m == 1)
   2706                   m = 0x80;
   2707                else
   2708                   m >>= 1;
   2709             }
   2710             break;
   2711          }
   2712       }
   2713    }
   2714 }
   2715 
   2716 #ifdef PNG_READ_INTERLACING_SUPPORTED
   2717 /* OLD pre-1.0.9 interface:
   2718 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
   2719    png_uint_32 transformations)
   2720  */
   2721 void /* PRIVATE */
   2722 png_do_read_interlace(png_structp png_ptr)
   2723 {
   2724    png_row_infop row_info = &(png_ptr->row_info);
   2725    png_bytep row = png_ptr->row_buf + 1;
   2726    int pass = png_ptr->pass;
   2727    png_uint_32 transformations = png_ptr->transformations;
   2728    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   2729    /* Offset to next interlace block */
   2730    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   2731 
   2732    png_debug(1, "in png_do_read_interlace");
   2733    if (row != NULL && row_info != NULL)
   2734    {
   2735       png_uint_32 final_width;
   2736 
   2737       final_width = row_info->width * png_pass_inc[pass];
   2738 
   2739       switch (row_info->pixel_depth)
   2740       {
   2741          case 1:
   2742          {
   2743             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
   2744             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
   2745             int sshift, dshift;
   2746             int s_start, s_end, s_inc;
   2747             int jstop = png_pass_inc[pass];
   2748             png_byte v;
   2749             png_uint_32 i;
   2750             int j;
   2751 
   2752 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2753             if (transformations & PNG_PACKSWAP)
   2754             {
   2755                 sshift = (int)((row_info->width + 7) & 0x07);
   2756                 dshift = (int)((final_width + 7) & 0x07);
   2757                 s_start = 7;
   2758                 s_end = 0;
   2759                 s_inc = -1;
   2760             }
   2761             else
   2762 #endif
   2763             {
   2764                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
   2765                 dshift = 7 - (int)((final_width + 7) & 0x07);
   2766                 s_start = 0;
   2767                 s_end = 7;
   2768                 s_inc = 1;
   2769             }
   2770 
   2771             for (i = 0; i < row_info->width; i++)
   2772             {
   2773                v = (png_byte)((*sp >> sshift) & 0x01);
   2774                for (j = 0; j < jstop; j++)
   2775                {
   2776                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
   2777                   *dp |= (png_byte)(v << dshift);
   2778                   if (dshift == s_end)
   2779                   {
   2780                      dshift = s_start;
   2781                      dp--;
   2782                   }
   2783                   else
   2784                      dshift += s_inc;
   2785                }
   2786                if (sshift == s_end)
   2787                {
   2788                   sshift = s_start;
   2789                   sp--;
   2790                }
   2791                else
   2792                   sshift += s_inc;
   2793             }
   2794             break;
   2795          }
   2796          case 2:
   2797          {
   2798             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
   2799             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
   2800             int sshift, dshift;
   2801             int s_start, s_end, s_inc;
   2802             int jstop = png_pass_inc[pass];
   2803             png_uint_32 i;
   2804 
   2805 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2806             if (transformations & PNG_PACKSWAP)
   2807             {
   2808                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
   2809                dshift = (int)(((final_width + 3) & 0x03) << 1);
   2810                s_start = 6;
   2811                s_end = 0;
   2812                s_inc = -2;
   2813             }
   2814             else
   2815 #endif
   2816             {
   2817                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
   2818                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
   2819                s_start = 0;
   2820                s_end = 6;
   2821                s_inc = 2;
   2822             }
   2823 
   2824             for (i = 0; i < row_info->width; i++)
   2825             {
   2826                png_byte v;
   2827                int j;
   2828 
   2829                v = (png_byte)((*sp >> sshift) & 0x03);
   2830                for (j = 0; j < jstop; j++)
   2831                {
   2832                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
   2833                   *dp |= (png_byte)(v << dshift);
   2834                   if (dshift == s_end)
   2835                   {
   2836                      dshift = s_start;
   2837                      dp--;
   2838                   }
   2839                   else
   2840                      dshift += s_inc;
   2841                }
   2842                if (sshift == s_end)
   2843                {
   2844                   sshift = s_start;
   2845                   sp--;
   2846                }
   2847                else
   2848                   sshift += s_inc;
   2849             }
   2850             break;
   2851          }
   2852          case 4:
   2853          {
   2854             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
   2855             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
   2856             int sshift, dshift;
   2857             int s_start, s_end, s_inc;
   2858             png_uint_32 i;
   2859             int jstop = png_pass_inc[pass];
   2860 
   2861 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   2862             if (transformations & PNG_PACKSWAP)
   2863             {
   2864                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
   2865                dshift = (int)(((final_width + 1) & 0x01) << 2);
   2866                s_start = 4;
   2867                s_end = 0;
   2868                s_inc = -4;
   2869             }
   2870             else
   2871 #endif
   2872             {
   2873                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
   2874                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
   2875                s_start = 0;
   2876                s_end = 4;
   2877                s_inc = 4;
   2878             }
   2879 
   2880             for (i = 0; i < row_info->width; i++)
   2881             {
   2882                png_byte v = (png_byte)((*sp >> sshift) & 0xf);
   2883                int j;
   2884 
   2885                for (j = 0; j < jstop; j++)
   2886                {
   2887                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
   2888                   *dp |= (png_byte)(v << dshift);
   2889                   if (dshift == s_end)
   2890                   {
   2891                      dshift = s_start;
   2892                      dp--;
   2893                   }
   2894                   else
   2895                      dshift += s_inc;
   2896                }
   2897                if (sshift == s_end)
   2898                {
   2899                   sshift = s_start;
   2900                   sp--;
   2901                }
   2902                else
   2903                   sshift += s_inc;
   2904             }
   2905             break;
   2906          }
   2907          default:
   2908          {
   2909             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
   2910             png_bytep sp = row + (png_size_t)(row_info->width - 1)
   2911                 * pixel_bytes;
   2912             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
   2913 
   2914             int jstop = png_pass_inc[pass];
   2915             png_uint_32 i;
   2916 
   2917             for (i = 0; i < row_info->width; i++)
   2918             {
   2919                png_byte v[8];
   2920                int j;
   2921 
   2922                png_memcpy(v, sp, pixel_bytes);
   2923                for (j = 0; j < jstop; j++)
   2924                {
   2925                   png_memcpy(dp, v, pixel_bytes);
   2926                   dp -= pixel_bytes;
   2927                }
   2928                sp -= pixel_bytes;
   2929             }
   2930             break;
   2931          }
   2932       }
   2933       row_info->width = final_width;
   2934       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
   2935    }
   2936 #ifndef PNG_READ_PACKSWAP_SUPPORTED
   2937    transformations = transformations; /* Silence compiler warning */
   2938 #endif
   2939 }
   2940 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   2941 
   2942 void /* PRIVATE */
   2943 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
   2944    png_bytep prev_row, int filter)
   2945 {
   2946    png_debug(1, "in png_read_filter_row");
   2947    png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
   2948    switch (filter)
   2949    {
   2950       case PNG_FILTER_VALUE_NONE:
   2951          break;
   2952       case PNG_FILTER_VALUE_SUB:
   2953       {
   2954          png_uint_32 i;
   2955          png_uint_32 istop = row_info->rowbytes;
   2956          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   2957          png_bytep rp = row + bpp;
   2958          png_bytep lp = row;
   2959 
   2960          for (i = bpp; i < istop; i++)
   2961          {
   2962             *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
   2963             rp++;
   2964          }
   2965          break;
   2966       }
   2967       case PNG_FILTER_VALUE_UP:
   2968       {
   2969          png_uint_32 i;
   2970          png_uint_32 istop = row_info->rowbytes;
   2971          png_bytep rp = row;
   2972          png_bytep pp = prev_row;
   2973 
   2974          for (i = 0; i < istop; i++)
   2975          {
   2976             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
   2977             rp++;
   2978          }
   2979          break;
   2980       }
   2981       case PNG_FILTER_VALUE_AVG:
   2982       {
   2983          png_uint_32 i;
   2984          png_bytep rp = row;
   2985          png_bytep pp = prev_row;
   2986          png_bytep lp = row;
   2987          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   2988          png_uint_32 istop = row_info->rowbytes - bpp;
   2989 
   2990          for (i = 0; i < bpp; i++)
   2991          {
   2992             *rp = (png_byte)(((int)(*rp) +
   2993                ((int)(*pp++) / 2 )) & 0xff);
   2994             rp++;
   2995          }
   2996 
   2997          for (i = 0; i < istop; i++)
   2998          {
   2999             *rp = (png_byte)(((int)(*rp) +
   3000                (int)(*pp++ + *lp++) / 2 ) & 0xff);
   3001             rp++;
   3002          }
   3003          break;
   3004       }
   3005       case PNG_FILTER_VALUE_PAETH:
   3006       {
   3007          png_uint_32 i;
   3008          png_bytep rp = row;
   3009          png_bytep pp = prev_row;
   3010          png_bytep lp = row;
   3011          png_bytep cp = prev_row;
   3012          png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
   3013          png_uint_32 istop=row_info->rowbytes - bpp;
   3014 
   3015          for (i = 0; i < bpp; i++)
   3016          {
   3017             *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
   3018             rp++;
   3019          }
   3020 
   3021          for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
   3022          {
   3023             int a, b, c, pa, pb, pc, p;
   3024 
   3025             a = *lp++;
   3026             b = *pp++;
   3027             c = *cp++;
   3028 
   3029             p = b - c;
   3030             pc = a - c;
   3031 
   3032 #ifdef PNG_USE_ABS
   3033             pa = abs(p);
   3034             pb = abs(pc);
   3035             pc = abs(p + pc);
   3036 #else
   3037             pa = p < 0 ? -p : p;
   3038             pb = pc < 0 ? -pc : pc;
   3039             pc = (p + pc) < 0 ? -(p + pc) : p + pc;
   3040 #endif
   3041 
   3042             /*
   3043                if (pa <= pb && pa <= pc)
   3044                   p = a;
   3045                else if (pb <= pc)
   3046                   p = b;
   3047                else
   3048                   p = c;
   3049              */
   3050 
   3051             p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
   3052 
   3053             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
   3054             rp++;
   3055          }
   3056          break;
   3057       }
   3058       default:
   3059          png_warning(png_ptr, "Ignoring bad adaptive filter type");
   3060          *row = 0;
   3061          break;
   3062    }
   3063 }
   3064 
   3065 #ifdef PNG_INDEX_SUPPORTED
   3066 void /* PRIVATE */
   3067 png_set_interlaced_pass(png_structp png_ptr, int pass)
   3068 {
   3069    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   3070 
   3071    /* Start of interlace block */
   3072    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
   3073 
   3074    /* Offset to next interlace block */
   3075    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   3076 
   3077    /* Start of interlace block in the y direction */
   3078    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
   3079 
   3080    /* Offset to next interlace block in the y direction */
   3081    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
   3082 
   3083    png_ptr->pass = pass;
   3084    png_ptr->iwidth = (png_ptr->width +
   3085          png_pass_inc[png_ptr->pass] - 1 -
   3086          png_pass_start[png_ptr->pass]) /
   3087       png_pass_inc[png_ptr->pass];
   3088 }
   3089 #endif
   3090 
   3091 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
   3092 void /* PRIVATE */
   3093 png_read_finish_row(png_structp png_ptr)
   3094 {
   3095 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3096    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   3097 
   3098    /* Start of interlace block */
   3099    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
   3100 
   3101    /* Offset to next interlace block */
   3102    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   3103 
   3104    /* Start of interlace block in the y direction */
   3105    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
   3106 
   3107    /* Offset to next interlace block in the y direction */
   3108    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
   3109 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3110 
   3111    png_debug(1, "in png_read_finish_row");
   3112    png_ptr->row_number++;
   3113    if (png_ptr->row_number < png_ptr->num_rows)
   3114       return;
   3115 
   3116 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3117    if (png_ptr->interlaced)
   3118    {
   3119       png_ptr->row_number = 0;
   3120       png_memset_check(png_ptr, png_ptr->prev_row, 0,
   3121          png_ptr->rowbytes + 1);
   3122       do
   3123       {
   3124          png_ptr->pass++;
   3125          if (png_ptr->pass >= 7)
   3126             break;
   3127          png_ptr->iwidth = (png_ptr->width +
   3128             png_pass_inc[png_ptr->pass] - 1 -
   3129             png_pass_start[png_ptr->pass]) /
   3130             png_pass_inc[png_ptr->pass];
   3131 
   3132          if (!(png_ptr->transformations & PNG_INTERLACE))
   3133          {
   3134             png_ptr->num_rows = (png_ptr->height +
   3135                png_pass_yinc[png_ptr->pass] - 1 -
   3136                png_pass_ystart[png_ptr->pass]) /
   3137                png_pass_yinc[png_ptr->pass];
   3138             if (!(png_ptr->num_rows))
   3139                continue;
   3140          }
   3141          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
   3142             break;
   3143       } while (png_ptr->iwidth == 0);
   3144 
   3145       if (png_ptr->pass < 7)
   3146          return;
   3147    }
   3148 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3149 
   3150    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
   3151    {
   3152 #ifdef PNG_USE_LOCAL_ARRAYS
   3153       PNG_CONST PNG_IDAT;
   3154 #endif
   3155       char extra;
   3156       int ret;
   3157 
   3158       png_ptr->zstream.next_out = (Byte *)&extra;
   3159       png_ptr->zstream.avail_out = (uInt)1;
   3160       for (;;)
   3161       {
   3162          if (!(png_ptr->zstream.avail_in))
   3163          {
   3164             while (!png_ptr->idat_size)
   3165             {
   3166                png_byte chunk_length[4];
   3167 
   3168                png_crc_finish(png_ptr, 0);
   3169 
   3170                png_read_data(png_ptr, chunk_length, 4);
   3171                png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
   3172                png_reset_crc(png_ptr);
   3173                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
   3174                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
   3175                   png_error(png_ptr, "Not enough image data");
   3176 
   3177             }
   3178             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
   3179             png_ptr->zstream.next_in = png_ptr->zbuf;
   3180             if (png_ptr->zbuf_size > png_ptr->idat_size)
   3181                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
   3182             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
   3183             png_ptr->idat_size -= png_ptr->zstream.avail_in;
   3184          }
   3185          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
   3186          if (ret == Z_STREAM_END)
   3187          {
   3188             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
   3189                png_ptr->idat_size)
   3190                png_warning(png_ptr, "Extra compressed data.");
   3191             png_ptr->mode |= PNG_AFTER_IDAT;
   3192             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   3193             break;
   3194          }
   3195          if (ret != Z_OK)
   3196             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
   3197                       "Decompression Error");
   3198 
   3199          if (!(png_ptr->zstream.avail_out))
   3200          {
   3201             png_warning(png_ptr, "Extra compressed data.");
   3202             png_ptr->mode |= PNG_AFTER_IDAT;
   3203             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
   3204             break;
   3205          }
   3206 
   3207       }
   3208       png_ptr->zstream.avail_out = 0;
   3209    }
   3210 
   3211    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
   3212       png_warning(png_ptr, "Extra compression data.");
   3213 
   3214    inflateReset(&png_ptr->zstream);
   3215 
   3216    png_ptr->mode |= PNG_AFTER_IDAT;
   3217 }
   3218 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
   3219 
   3220 void /* PRIVATE */
   3221 png_read_start_row(png_structp png_ptr)
   3222 {
   3223 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3224    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   3225 
   3226    /* Start of interlace block */
   3227    PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
   3228 
   3229    /* Offset to next interlace block */
   3230    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
   3231 
   3232    /* Start of interlace block in the y direction */
   3233    PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
   3234 
   3235    /* Offset to next interlace block in the y direction */
   3236    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
   3237 #endif
   3238 
   3239    int max_pixel_depth;
   3240    png_size_t row_bytes;
   3241 
   3242    png_debug(1, "in png_read_start_row");
   3243    png_ptr->zstream.avail_in = 0;
   3244    png_init_read_transformations(png_ptr);
   3245 #ifdef PNG_READ_INTERLACING_SUPPORTED
   3246    if (png_ptr->interlaced)
   3247    {
   3248       if (!(png_ptr->transformations & PNG_INTERLACE))
   3249          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
   3250             png_pass_ystart[0]) / png_pass_yinc[0];
   3251       else
   3252          png_ptr->num_rows = png_ptr->height;
   3253 
   3254       png_ptr->iwidth = (png_ptr->width +
   3255          png_pass_inc[png_ptr->pass] - 1 -
   3256          png_pass_start[png_ptr->pass]) /
   3257          png_pass_inc[png_ptr->pass];
   3258    }
   3259    else
   3260 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   3261    {
   3262       png_ptr->num_rows = png_ptr->height;
   3263       png_ptr->iwidth = png_ptr->width;
   3264    }
   3265    max_pixel_depth = png_ptr->pixel_depth;
   3266 
   3267 #ifdef PNG_READ_PACK_SUPPORTED
   3268    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
   3269       max_pixel_depth = 8;
   3270 #endif
   3271 
   3272 #ifdef PNG_READ_EXPAND_SUPPORTED
   3273    if (png_ptr->transformations & PNG_EXPAND)
   3274    {
   3275       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   3276       {
   3277          if (png_ptr->num_trans)
   3278             max_pixel_depth = 32;
   3279          else
   3280             max_pixel_depth = 24;
   3281       }
   3282       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
   3283       {
   3284          if (max_pixel_depth < 8)
   3285             max_pixel_depth = 8;
   3286          if (png_ptr->num_trans)
   3287             max_pixel_depth *= 2;
   3288       }
   3289       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   3290       {
   3291          if (png_ptr->num_trans)
   3292          {
   3293             max_pixel_depth *= 4;
   3294             max_pixel_depth /= 3;
   3295          }
   3296       }
   3297    }
   3298 #endif
   3299 
   3300 #ifdef PNG_READ_FILLER_SUPPORTED
   3301    if (png_ptr->transformations & (PNG_FILLER))
   3302    {
   3303       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   3304          max_pixel_depth = 32;
   3305       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
   3306       {
   3307          if (max_pixel_depth <= 8)
   3308             max_pixel_depth = 16;
   3309          else
   3310             max_pixel_depth = 32;
   3311       }
   3312       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
   3313       {
   3314          if (max_pixel_depth <= 32)
   3315             max_pixel_depth = 32;
   3316          else
   3317             max_pixel_depth = 64;
   3318       }
   3319    }
   3320 #endif
   3321 
   3322 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   3323    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
   3324    {
   3325       if (
   3326 #ifdef PNG_READ_EXPAND_SUPPORTED
   3327         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
   3328 #endif
   3329 #ifdef PNG_READ_FILLER_SUPPORTED
   3330         (png_ptr->transformations & (PNG_FILLER)) ||
   3331 #endif
   3332         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
   3333       {
   3334          if (max_pixel_depth <= 16)
   3335             max_pixel_depth = 32;
   3336          else
   3337             max_pixel_depth = 64;
   3338       }
   3339       else
   3340       {
   3341          if (max_pixel_depth <= 8)
   3342            {
   3343              if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   3344                max_pixel_depth = 32;
   3345              else
   3346                max_pixel_depth = 24;
   3347            }
   3348          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
   3349             max_pixel_depth = 64;
   3350          else
   3351             max_pixel_depth = 48;
   3352       }
   3353    }
   3354 #endif
   3355 
   3356 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
   3357 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
   3358    if (png_ptr->transformations & PNG_USER_TRANSFORM)
   3359      {
   3360        int user_pixel_depth = png_ptr->user_transform_depth*
   3361          png_ptr->user_transform_channels;
   3362        if (user_pixel_depth > max_pixel_depth)
   3363          max_pixel_depth=user_pixel_depth;
   3364      }
   3365 #endif
   3366 
   3367    /* Align the width on the next larger 8 pixels.  Mainly used
   3368     * for interlacing
   3369     */
   3370    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
   3371    /* Calculate the maximum bytes needed, adding a byte and a pixel
   3372     * for safety's sake
   3373     */
   3374    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
   3375       1 + ((max_pixel_depth + 7) >> 3);
   3376 #ifdef PNG_MAX_MALLOC_64K
   3377    if (row_bytes > (png_uint_32)65536L)
   3378       png_error(png_ptr, "This image requires a row greater than 64KB");
   3379 #endif
   3380 
   3381    if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
   3382    {
   3383      png_free(png_ptr, png_ptr->big_row_buf);
   3384      if (png_ptr->interlaced)
   3385         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
   3386             row_bytes + 64);
   3387      else
   3388         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
   3389             row_bytes + 64);
   3390      png_ptr->old_big_row_buf_size = row_bytes + 64;
   3391 
   3392      /* Use 32 bytes of padding before and after row_buf. */
   3393      png_ptr->row_buf = png_ptr->big_row_buf + 32;
   3394      png_ptr->old_big_row_buf_size = row_bytes + 64;
   3395    }
   3396 
   3397 #ifdef PNG_MAX_MALLOC_64K
   3398    if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
   3399       png_error(png_ptr, "This image requires a row greater than 64KB");
   3400 #endif
   3401    if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
   3402       png_error(png_ptr, "Row has too many bytes to allocate in memory.");
   3403 
   3404    if (row_bytes + 1 > png_ptr->old_prev_row_size)
   3405    {
   3406       png_free(png_ptr, png_ptr->prev_row);
   3407       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
   3408         row_bytes + 1));
   3409       png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
   3410       png_ptr->old_prev_row_size = row_bytes + 1;
   3411    }
   3412 
   3413    png_ptr->rowbytes = row_bytes;
   3414 
   3415    png_debug1(3, "width = %lu,", png_ptr->width);
   3416    png_debug1(3, "height = %lu,", png_ptr->height);
   3417    png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
   3418    png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
   3419    png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
   3420    png_debug1(3, "irowbytes = %lu",
   3421        PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
   3422 
   3423    png_ptr->flags |= PNG_FLAG_ROW_INIT;
   3424 }
   3425 #endif /* PNG_READ_SUPPORTED */
   3426