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