Home | History | Annotate | Download | only in libpng
      1 
      2 /* pngpread.c - read a png file in push mode
      3  *
      4  * Last changed in libpng 1.2.44 [June 26, 2010]
      5  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
      6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      8  *
      9  * This code is released under the libpng license.
     10  * For conditions of distribution and use, see the disclaimer
     11  * and license in png.h
     12  */
     13 
     14 #define PNG_INTERNAL
     15 #define PNG_NO_PEDANTIC_WARNINGS
     16 #include "png.h"
     17 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
     18 
     19 /* Push model modes */
     20 #define PNG_READ_SIG_MODE   0
     21 #define PNG_READ_CHUNK_MODE 1
     22 #define PNG_READ_IDAT_MODE  2
     23 #define PNG_SKIP_MODE       3
     24 #define PNG_READ_tEXt_MODE  4
     25 #define PNG_READ_zTXt_MODE  5
     26 #define PNG_READ_DONE_MODE  6
     27 #define PNG_READ_iTXt_MODE  7
     28 #define PNG_ERROR_MODE      8
     29 
     30 void PNGAPI
     31 png_process_data(png_structp png_ptr, png_infop info_ptr,
     32    png_bytep buffer, png_size_t buffer_size)
     33 {
     34    if (png_ptr == NULL || info_ptr == NULL)
     35       return;
     36 
     37    png_push_restore_buffer(png_ptr, buffer, buffer_size);
     38 
     39    while (png_ptr->buffer_size)
     40    {
     41       png_process_some_data(png_ptr, info_ptr);
     42    }
     43 }
     44 
     45 /* What we do with the incoming data depends on what we were previously
     46  * doing before we ran out of data...
     47  */
     48 void /* PRIVATE */
     49 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
     50 {
     51    if (png_ptr == NULL)
     52       return;
     53 
     54    switch (png_ptr->process_mode)
     55    {
     56       case PNG_READ_SIG_MODE:
     57       {
     58          png_push_read_sig(png_ptr, info_ptr);
     59          break;
     60       }
     61 
     62       case PNG_READ_CHUNK_MODE:
     63       {
     64          png_push_read_chunk(png_ptr, info_ptr);
     65          break;
     66       }
     67 
     68       case PNG_READ_IDAT_MODE:
     69       {
     70          png_push_read_IDAT(png_ptr);
     71          break;
     72       }
     73 
     74 #ifdef PNG_READ_tEXt_SUPPORTED
     75       case PNG_READ_tEXt_MODE:
     76       {
     77          png_push_read_tEXt(png_ptr, info_ptr);
     78          break;
     79       }
     80 
     81 #endif
     82 #ifdef PNG_READ_zTXt_SUPPORTED
     83       case PNG_READ_zTXt_MODE:
     84       {
     85          png_push_read_zTXt(png_ptr, info_ptr);
     86          break;
     87       }
     88 
     89 #endif
     90 #ifdef PNG_READ_iTXt_SUPPORTED
     91       case PNG_READ_iTXt_MODE:
     92       {
     93          png_push_read_iTXt(png_ptr, info_ptr);
     94          break;
     95       }
     96 
     97 #endif
     98       case PNG_SKIP_MODE:
     99       {
    100          png_push_crc_finish(png_ptr);
    101          break;
    102       }
    103 
    104       default:
    105       {
    106          png_ptr->buffer_size = 0;
    107          break;
    108       }
    109    }
    110 }
    111 
    112 /* Read any remaining signature bytes from the stream and compare them with
    113  * the correct PNG signature.  It is possible that this routine is called
    114  * with bytes already read from the signature, either because they have been
    115  * checked by the calling application, or because of multiple calls to this
    116  * routine.
    117  */
    118 void /* PRIVATE */
    119 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
    120 {
    121    png_size_t num_checked = png_ptr->sig_bytes,
    122              num_to_check = 8 - num_checked;
    123 
    124    if (png_ptr->buffer_size < num_to_check)
    125    {
    126       num_to_check = png_ptr->buffer_size;
    127    }
    128 
    129    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
    130       num_to_check);
    131    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
    132 
    133    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
    134    {
    135       if (num_checked < 4 &&
    136           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
    137          png_error(png_ptr, "Not a PNG file");
    138       else
    139          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    140    }
    141    else
    142    {
    143       if (png_ptr->sig_bytes >= 8)
    144       {
    145          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    146       }
    147    }
    148 }
    149 
    150 void /* PRIVATE */
    151 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
    152 {
    153 #ifdef PNG_USE_LOCAL_ARRAYS
    154       PNG_CONST PNG_IHDR;
    155       PNG_CONST PNG_IDAT;
    156       PNG_CONST PNG_IEND;
    157       PNG_CONST PNG_PLTE;
    158 #ifdef PNG_READ_bKGD_SUPPORTED
    159       PNG_CONST PNG_bKGD;
    160 #endif
    161 #ifdef PNG_READ_cHRM_SUPPORTED
    162       PNG_CONST PNG_cHRM;
    163 #endif
    164 #ifdef PNG_READ_gAMA_SUPPORTED
    165       PNG_CONST PNG_gAMA;
    166 #endif
    167 #ifdef PNG_READ_hIST_SUPPORTED
    168       PNG_CONST PNG_hIST;
    169 #endif
    170 #ifdef PNG_READ_iCCP_SUPPORTED
    171       PNG_CONST PNG_iCCP;
    172 #endif
    173 #ifdef PNG_READ_iTXt_SUPPORTED
    174       PNG_CONST PNG_iTXt;
    175 #endif
    176 #ifdef PNG_READ_oFFs_SUPPORTED
    177       PNG_CONST PNG_oFFs;
    178 #endif
    179 #ifdef PNG_READ_pCAL_SUPPORTED
    180       PNG_CONST PNG_pCAL;
    181 #endif
    182 #ifdef PNG_READ_pHYs_SUPPORTED
    183       PNG_CONST PNG_pHYs;
    184 #endif
    185 #ifdef PNG_READ_sBIT_SUPPORTED
    186       PNG_CONST PNG_sBIT;
    187 #endif
    188 #ifdef PNG_READ_sCAL_SUPPORTED
    189       PNG_CONST PNG_sCAL;
    190 #endif
    191 #ifdef PNG_READ_sRGB_SUPPORTED
    192       PNG_CONST PNG_sRGB;
    193 #endif
    194 #ifdef PNG_READ_sPLT_SUPPORTED
    195       PNG_CONST PNG_sPLT;
    196 #endif
    197 #ifdef PNG_READ_tEXt_SUPPORTED
    198       PNG_CONST PNG_tEXt;
    199 #endif
    200 #ifdef PNG_READ_tIME_SUPPORTED
    201       PNG_CONST PNG_tIME;
    202 #endif
    203 #ifdef PNG_READ_tRNS_SUPPORTED
    204       PNG_CONST PNG_tRNS;
    205 #endif
    206 #ifdef PNG_READ_zTXt_SUPPORTED
    207       PNG_CONST PNG_zTXt;
    208 #endif
    209 #endif /* PNG_USE_LOCAL_ARRAYS */
    210 
    211    /* First we make sure we have enough data for the 4 byte chunk name
    212     * and the 4 byte chunk length before proceeding with decoding the
    213     * chunk data.  To fully decode each of these chunks, we also make
    214     * sure we have enough data in the buffer for the 4 byte CRC at the
    215     * end of every chunk (except IDAT, which is handled separately).
    216     */
    217    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    218    {
    219       png_byte chunk_length[4];
    220 
    221       if (png_ptr->buffer_size < 8)
    222       {
    223          png_push_save_buffer(png_ptr);
    224          return;
    225       }
    226 
    227       png_push_fill_buffer(png_ptr, chunk_length, 4);
    228       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    229       png_reset_crc(png_ptr);
    230       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
    231       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    232       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    233    }
    234 
    235    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    236      if (png_ptr->mode & PNG_AFTER_IDAT)
    237         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
    238 
    239    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
    240    {
    241       if (png_ptr->push_length != 13)
    242          png_error(png_ptr, "Invalid IHDR length");
    243 
    244       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    245       {
    246          png_push_save_buffer(png_ptr);
    247          return;
    248       }
    249 
    250       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
    251    }
    252 
    253    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
    254    {
    255       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    256       {
    257          png_push_save_buffer(png_ptr);
    258          return;
    259       }
    260 
    261       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
    262 
    263       png_ptr->process_mode = PNG_READ_DONE_MODE;
    264       png_push_have_end(png_ptr, info_ptr);
    265    }
    266 
    267 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    268    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
    269    {
    270       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    271       {
    272          png_push_save_buffer(png_ptr);
    273          return;
    274       }
    275 
    276       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    277          png_ptr->mode |= PNG_HAVE_IDAT;
    278 
    279       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    280 
    281       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
    282          png_ptr->mode |= PNG_HAVE_PLTE;
    283 
    284       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    285       {
    286          if (!(png_ptr->mode & PNG_HAVE_IHDR))
    287             png_error(png_ptr, "Missing IHDR before IDAT");
    288 
    289          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    290                   !(png_ptr->mode & PNG_HAVE_PLTE))
    291             png_error(png_ptr, "Missing PLTE before IDAT");
    292       }
    293    }
    294 
    295 #endif
    296    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
    297    {
    298       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    299       {
    300          png_push_save_buffer(png_ptr);
    301          return;
    302       }
    303       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    304    }
    305 
    306    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    307    {
    308       /* If we reach an IDAT chunk, this means we have read all of the
    309        * header chunks, and we can start reading the image (or if this
    310        * is called after the image has been read - we have an error).
    311        */
    312 
    313       if (!(png_ptr->mode & PNG_HAVE_IHDR))
    314          png_error(png_ptr, "Missing IHDR before IDAT");
    315 
    316       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    317           !(png_ptr->mode & PNG_HAVE_PLTE))
    318          png_error(png_ptr, "Missing PLTE before IDAT");
    319 
    320       if (png_ptr->mode & PNG_HAVE_IDAT)
    321       {
    322          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
    323             if (png_ptr->push_length == 0)
    324                return;
    325 
    326          if (png_ptr->mode & PNG_AFTER_IDAT)
    327             png_error(png_ptr, "Too many IDAT's found");
    328       }
    329 
    330       png_ptr->idat_size = png_ptr->push_length;
    331       png_ptr->mode |= PNG_HAVE_IDAT;
    332       png_ptr->process_mode = PNG_READ_IDAT_MODE;
    333       png_push_have_info(png_ptr, info_ptr);
    334       png_ptr->zstream.avail_out =
    335           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
    336           png_ptr->iwidth) + 1;
    337       png_ptr->zstream.next_out = png_ptr->row_buf;
    338       return;
    339    }
    340 
    341 #ifdef PNG_READ_gAMA_SUPPORTED
    342    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
    343    {
    344       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    345       {
    346          png_push_save_buffer(png_ptr);
    347          return;
    348       }
    349 
    350       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
    351    }
    352 
    353 #endif
    354 #ifdef PNG_READ_sBIT_SUPPORTED
    355    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
    356    {
    357       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    358       {
    359          png_push_save_buffer(png_ptr);
    360          return;
    361       }
    362 
    363       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
    364    }
    365 
    366 #endif
    367 #ifdef PNG_READ_cHRM_SUPPORTED
    368    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
    369    {
    370       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    371       {
    372          png_push_save_buffer(png_ptr);
    373          return;
    374       }
    375 
    376       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
    377    }
    378 
    379 #endif
    380 #ifdef PNG_READ_sRGB_SUPPORTED
    381    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
    382    {
    383       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    384       {
    385          png_push_save_buffer(png_ptr);
    386          return;
    387       }
    388 
    389       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
    390    }
    391 
    392 #endif
    393 #ifdef PNG_READ_iCCP_SUPPORTED
    394    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
    395    {
    396       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    397       {
    398          png_push_save_buffer(png_ptr);
    399          return;
    400       }
    401 
    402       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
    403    }
    404 
    405 #endif
    406 #ifdef PNG_READ_sPLT_SUPPORTED
    407    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
    408    {
    409       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    410       {
    411          png_push_save_buffer(png_ptr);
    412          return;
    413       }
    414 
    415       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
    416    }
    417 
    418 #endif
    419 #ifdef PNG_READ_tRNS_SUPPORTED
    420    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
    421    {
    422       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    423       {
    424          png_push_save_buffer(png_ptr);
    425          return;
    426       }
    427 
    428       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
    429    }
    430 
    431 #endif
    432 #ifdef PNG_READ_bKGD_SUPPORTED
    433    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
    434    {
    435       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    436       {
    437          png_push_save_buffer(png_ptr);
    438          return;
    439       }
    440 
    441       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
    442    }
    443 
    444 #endif
    445 #ifdef PNG_READ_hIST_SUPPORTED
    446    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
    447    {
    448       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    449       {
    450          png_push_save_buffer(png_ptr);
    451          return;
    452       }
    453 
    454       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
    455    }
    456 
    457 #endif
    458 #ifdef PNG_READ_pHYs_SUPPORTED
    459    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
    460    {
    461       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    462       {
    463          png_push_save_buffer(png_ptr);
    464          return;
    465       }
    466 
    467       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
    468    }
    469 
    470 #endif
    471 #ifdef PNG_READ_oFFs_SUPPORTED
    472    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
    473    {
    474       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    475       {
    476          png_push_save_buffer(png_ptr);
    477          return;
    478       }
    479 
    480       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
    481    }
    482 #endif
    483 
    484 #ifdef PNG_READ_pCAL_SUPPORTED
    485    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
    486    {
    487       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    488       {
    489          png_push_save_buffer(png_ptr);
    490          return;
    491       }
    492 
    493       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
    494    }
    495 
    496 #endif
    497 #ifdef PNG_READ_sCAL_SUPPORTED
    498    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
    499    {
    500       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    501       {
    502          png_push_save_buffer(png_ptr);
    503          return;
    504       }
    505 
    506       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
    507    }
    508 
    509 #endif
    510 #ifdef PNG_READ_tIME_SUPPORTED
    511    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
    512    {
    513       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    514       {
    515          png_push_save_buffer(png_ptr);
    516          return;
    517       }
    518 
    519       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
    520    }
    521 
    522 #endif
    523 #ifdef PNG_READ_tEXt_SUPPORTED
    524    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
    525    {
    526       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    527       {
    528          png_push_save_buffer(png_ptr);
    529          return;
    530       }
    531 
    532       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
    533    }
    534 
    535 #endif
    536 #ifdef PNG_READ_zTXt_SUPPORTED
    537    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
    538    {
    539       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    540       {
    541          png_push_save_buffer(png_ptr);
    542          return;
    543       }
    544 
    545       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
    546    }
    547 
    548 #endif
    549 #ifdef PNG_READ_iTXt_SUPPORTED
    550    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
    551    {
    552       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    553       {
    554          png_push_save_buffer(png_ptr);
    555          return;
    556       }
    557 
    558       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    559    }
    560 
    561 #endif
    562    else
    563    {
    564       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    565       {
    566          png_push_save_buffer(png_ptr);
    567          return;
    568       }
    569       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    570    }
    571 
    572    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    573 }
    574 
    575 void /* PRIVATE */
    576 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
    577 {
    578    png_ptr->process_mode = PNG_SKIP_MODE;
    579    png_ptr->skip_length = skip;
    580 }
    581 
    582 void /* PRIVATE */
    583 png_push_crc_finish(png_structp png_ptr)
    584 {
    585    if (png_ptr->skip_length && png_ptr->save_buffer_size)
    586    {
    587       png_size_t save_size;
    588 
    589       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
    590          save_size = (png_size_t)png_ptr->skip_length;
    591       else
    592          save_size = png_ptr->save_buffer_size;
    593 
    594       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    595 
    596       png_ptr->skip_length -= save_size;
    597       png_ptr->buffer_size -= save_size;
    598       png_ptr->save_buffer_size -= save_size;
    599       png_ptr->save_buffer_ptr += save_size;
    600    }
    601    if (png_ptr->skip_length && png_ptr->current_buffer_size)
    602    {
    603       png_size_t save_size;
    604 
    605       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
    606          save_size = (png_size_t)png_ptr->skip_length;
    607       else
    608          save_size = png_ptr->current_buffer_size;
    609 
    610       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    611 
    612       png_ptr->skip_length -= save_size;
    613       png_ptr->buffer_size -= save_size;
    614       png_ptr->current_buffer_size -= save_size;
    615       png_ptr->current_buffer_ptr += save_size;
    616    }
    617    if (!png_ptr->skip_length)
    618    {
    619       if (png_ptr->buffer_size < 4)
    620       {
    621          png_push_save_buffer(png_ptr);
    622          return;
    623       }
    624 
    625       png_crc_finish(png_ptr, 0);
    626       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    627    }
    628 }
    629 
    630 void PNGAPI
    631 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
    632 {
    633    png_bytep ptr;
    634 
    635    if (png_ptr == NULL)
    636       return;
    637 
    638    ptr = buffer;
    639    if (png_ptr->save_buffer_size)
    640    {
    641       png_size_t save_size;
    642 
    643       if (length < png_ptr->save_buffer_size)
    644          save_size = length;
    645       else
    646          save_size = png_ptr->save_buffer_size;
    647 
    648       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
    649       length -= save_size;
    650       ptr += save_size;
    651       png_ptr->buffer_size -= save_size;
    652       png_ptr->save_buffer_size -= save_size;
    653       png_ptr->save_buffer_ptr += save_size;
    654    }
    655    if (length && png_ptr->current_buffer_size)
    656    {
    657       png_size_t save_size;
    658 
    659       if (length < png_ptr->current_buffer_size)
    660          save_size = length;
    661 
    662       else
    663          save_size = png_ptr->current_buffer_size;
    664 
    665       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
    666       png_ptr->buffer_size -= save_size;
    667       png_ptr->current_buffer_size -= save_size;
    668       png_ptr->current_buffer_ptr += save_size;
    669    }
    670 }
    671 
    672 void /* PRIVATE */
    673 png_push_save_buffer(png_structp png_ptr)
    674 {
    675    if (png_ptr->save_buffer_size)
    676    {
    677       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
    678       {
    679          png_size_t i, istop;
    680          png_bytep sp;
    681          png_bytep dp;
    682 
    683          istop = png_ptr->save_buffer_size;
    684          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
    685             i < istop; i++, sp++, dp++)
    686          {
    687             *dp = *sp;
    688          }
    689       }
    690    }
    691    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
    692       png_ptr->save_buffer_max)
    693    {
    694       png_size_t new_max;
    695       png_bytep old_buffer;
    696 
    697       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
    698          (png_ptr->current_buffer_size + 256))
    699       {
    700         png_error(png_ptr, "Potential overflow of save_buffer");
    701       }
    702 
    703       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
    704       old_buffer = png_ptr->save_buffer;
    705       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
    706          (png_uint_32)new_max);
    707       if (png_ptr->save_buffer == NULL)
    708       {
    709         png_free(png_ptr, old_buffer);
    710         png_error(png_ptr, "Insufficient memory for save_buffer");
    711       }
    712       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
    713       png_free(png_ptr, old_buffer);
    714       png_ptr->save_buffer_max = new_max;
    715    }
    716    if (png_ptr->current_buffer_size)
    717    {
    718       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
    719          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
    720       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
    721       png_ptr->current_buffer_size = 0;
    722    }
    723    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
    724    png_ptr->buffer_size = 0;
    725 }
    726 
    727 void /* PRIVATE */
    728 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
    729    png_size_t buffer_length)
    730 {
    731    png_ptr->current_buffer = buffer;
    732    png_ptr->current_buffer_size = buffer_length;
    733    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
    734    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
    735 }
    736 
    737 void /* PRIVATE */
    738 png_push_read_IDAT(png_structp png_ptr)
    739 {
    740 #ifdef PNG_USE_LOCAL_ARRAYS
    741    PNG_CONST PNG_IDAT;
    742 #endif
    743    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    744    {
    745       png_byte chunk_length[4];
    746 
    747       if (png_ptr->buffer_size < 8)
    748       {
    749          png_push_save_buffer(png_ptr);
    750          return;
    751       }
    752 
    753       png_push_fill_buffer(png_ptr, chunk_length, 4);
    754       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    755       png_reset_crc(png_ptr);
    756       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
    757       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    758 
    759       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    760       {
    761          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    762          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    763             png_error(png_ptr, "Not enough compressed data");
    764          return;
    765       }
    766 
    767       png_ptr->idat_size = png_ptr->push_length;
    768    }
    769    if (png_ptr->idat_size && png_ptr->save_buffer_size)
    770    {
    771       png_size_t save_size;
    772 
    773       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
    774       {
    775          save_size = (png_size_t)png_ptr->idat_size;
    776 
    777          /* Check for overflow */
    778          if ((png_uint_32)save_size != png_ptr->idat_size)
    779             png_error(png_ptr, "save_size overflowed in pngpread");
    780       }
    781       else
    782          save_size = png_ptr->save_buffer_size;
    783 
    784       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    785 
    786       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
    787 
    788       png_ptr->idat_size -= save_size;
    789       png_ptr->buffer_size -= save_size;
    790       png_ptr->save_buffer_size -= save_size;
    791       png_ptr->save_buffer_ptr += save_size;
    792    }
    793    if (png_ptr->idat_size && png_ptr->current_buffer_size)
    794    {
    795       png_size_t save_size;
    796 
    797       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
    798       {
    799          save_size = (png_size_t)png_ptr->idat_size;
    800 
    801          /* Check for overflow */
    802          if ((png_uint_32)save_size != png_ptr->idat_size)
    803             png_error(png_ptr, "save_size overflowed in pngpread");
    804       }
    805       else
    806          save_size = png_ptr->current_buffer_size;
    807 
    808       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    809 
    810       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
    811 
    812       png_ptr->idat_size -= save_size;
    813       png_ptr->buffer_size -= save_size;
    814       png_ptr->current_buffer_size -= save_size;
    815       png_ptr->current_buffer_ptr += save_size;
    816    }
    817    if (!png_ptr->idat_size)
    818    {
    819       if (png_ptr->buffer_size < 4)
    820       {
    821          png_push_save_buffer(png_ptr);
    822          return;
    823       }
    824 
    825       png_crc_finish(png_ptr, 0);
    826       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    827       png_ptr->mode |= PNG_AFTER_IDAT;
    828    }
    829 }
    830 
    831 void /* PRIVATE */
    832 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    833    png_size_t buffer_length)
    834 {
    835    /* The caller checks for a non-zero buffer length. */
    836    if (!(buffer_length > 0) || buffer == NULL)
    837       png_error(png_ptr, "No IDAT data (internal error)");
    838 
    839    /* This routine must process all the data it has been given
    840     * before returning, calling the row callback as required to
    841     * handle the uncompressed results.
    842     */
    843    png_ptr->zstream.next_in = buffer;
    844    png_ptr->zstream.avail_in = (uInt)buffer_length;
    845 
    846    /* Keep going until the decompressed data is all processed
    847     * or the stream marked as finished.
    848     */
    849    while (png_ptr->zstream.avail_in > 0 &&
    850 	  !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    851    {
    852       int ret;
    853 
    854       /* We have data for zlib, but we must check that zlib
    855        * has somewhere to put the results.  It doesn't matter
    856        * if we don't expect any results -- it may be the input
    857        * data is just the LZ end code.
    858        */
    859       if (!(png_ptr->zstream.avail_out > 0))
    860       {
    861          png_ptr->zstream.avail_out =
    862              (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
    863              png_ptr->iwidth) + 1;
    864          png_ptr->zstream.next_out = png_ptr->row_buf;
    865       }
    866 
    867       /* Using Z_SYNC_FLUSH here means that an unterminated
    868        * LZ stream can still be handled (a stream with a missing
    869        * end code), otherwise (Z_NO_FLUSH) a future zlib
    870        * implementation might defer output and, therefore,
    871        * change the current behavior.  (See comments in inflate.c
    872        * for why this doesn't happen at present with zlib 1.2.5.)
    873        */
    874       ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
    875 
    876       /* Check for any failure before proceeding. */
    877       if (ret != Z_OK && ret != Z_STREAM_END)
    878       {
    879 	 /* Terminate the decompression. */
    880 	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    881 
    882          /* This may be a truncated stream (missing or
    883 	  * damaged end code).  Treat that as a warning.
    884 	  */
    885          if (png_ptr->row_number >= png_ptr->num_rows ||
    886 	     png_ptr->pass > 6)
    887 	    png_warning(png_ptr, "Truncated compressed data in IDAT");
    888 	 else
    889 	    png_error(png_ptr, "Decompression error in IDAT");
    890 
    891 	 /* Skip the check on unprocessed input */
    892          return;
    893       }
    894 
    895       /* Did inflate output any data? */
    896       if (png_ptr->zstream.next_out != png_ptr->row_buf)
    897       {
    898 	 /* Is this unexpected data after the last row?
    899 	  * If it is, artificially terminate the LZ output
    900 	  * here.
    901 	  */
    902          if (png_ptr->row_number >= png_ptr->num_rows ||
    903 	     png_ptr->pass > 6)
    904          {
    905 	    /* Extra data. */
    906 	    png_warning(png_ptr, "Extra compressed data in IDAT");
    907             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    908 	    /* Do no more processing; skip the unprocessed
    909 	     * input check below.
    910 	     */
    911             return;
    912 	 }
    913 
    914 	 /* Do we have a complete row? */
    915 	 if (png_ptr->zstream.avail_out == 0)
    916 	    png_push_process_row(png_ptr);
    917       }
    918 
    919       /* And check for the end of the stream. */
    920       if (ret == Z_STREAM_END)
    921 	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    922    }
    923 
    924    /* All the data should have been processed, if anything
    925     * is left at this point we have bytes of IDAT data
    926     * after the zlib end code.
    927     */
    928    if (png_ptr->zstream.avail_in > 0)
    929       png_warning(png_ptr, "Extra compression data");
    930 }
    931 
    932 void /* PRIVATE */
    933 png_push_process_row(png_structp png_ptr)
    934 {
    935    png_ptr->row_info.color_type = png_ptr->color_type;
    936    png_ptr->row_info.width = png_ptr->iwidth;
    937    png_ptr->row_info.channels = png_ptr->channels;
    938    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    939    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
    940 
    941    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
    942        png_ptr->row_info.width);
    943 
    944    png_read_filter_row(png_ptr, &(png_ptr->row_info),
    945        png_ptr->row_buf + 1, png_ptr->prev_row + 1,
    946        (int)(png_ptr->row_buf[0]));
    947 
    948    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
    949       png_ptr->rowbytes + 1);
    950 
    951    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
    952       png_do_read_transformations(png_ptr);
    953 
    954 #ifdef PNG_READ_INTERLACING_SUPPORTED
    955    /* Blow up interlaced rows to full size */
    956    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    957    {
    958       if (png_ptr->pass < 6)
    959 /*       old interface (pre-1.0.9):
    960          png_do_read_interlace(&(png_ptr->row_info),
    961              png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
    962  */
    963          png_do_read_interlace(png_ptr);
    964 
    965     switch (png_ptr->pass)
    966     {
    967          case 0:
    968          {
    969             int i;
    970             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
    971             {
    972                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    973                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
    974             }
    975 
    976             if (png_ptr->pass == 2) /* Pass 1 might be empty */
    977             {
    978                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    979                {
    980                   png_push_have_row(png_ptr, png_bytep_NULL);
    981                   png_read_push_finish_row(png_ptr);
    982                }
    983             }
    984 
    985             if (png_ptr->pass == 4 && png_ptr->height <= 4)
    986             {
    987                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    988                {
    989                   png_push_have_row(png_ptr, png_bytep_NULL);
    990                   png_read_push_finish_row(png_ptr);
    991                }
    992             }
    993 
    994             if (png_ptr->pass == 6 && png_ptr->height <= 4)
    995             {
    996                   png_push_have_row(png_ptr, png_bytep_NULL);
    997                 png_read_push_finish_row(png_ptr);
    998             }
    999 
   1000             break;
   1001          }
   1002 
   1003          case 1:
   1004          {
   1005             int i;
   1006             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
   1007             {
   1008                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1009                png_read_push_finish_row(png_ptr);
   1010             }
   1011 
   1012             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
   1013             {
   1014                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1015                {
   1016                   png_push_have_row(png_ptr, png_bytep_NULL);
   1017                   png_read_push_finish_row(png_ptr);
   1018                }
   1019             }
   1020 
   1021             break;
   1022          }
   1023 
   1024          case 2:
   1025          {
   1026             int i;
   1027 
   1028             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1029             {
   1030                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1031                png_read_push_finish_row(png_ptr);
   1032             }
   1033 
   1034             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1035             {
   1036                   png_push_have_row(png_ptr, png_bytep_NULL);
   1037                png_read_push_finish_row(png_ptr);
   1038             }
   1039 
   1040             if (png_ptr->pass == 4) /* Pass 3 might be empty */
   1041             {
   1042                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1043                {
   1044                   png_push_have_row(png_ptr, png_bytep_NULL);
   1045                   png_read_push_finish_row(png_ptr);
   1046                }
   1047             }
   1048 
   1049             break;
   1050          }
   1051 
   1052          case 3:
   1053          {
   1054             int i;
   1055 
   1056             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
   1057             {
   1058                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1059                png_read_push_finish_row(png_ptr);
   1060             }
   1061 
   1062             if (png_ptr->pass == 4) /* Skip top two generated rows */
   1063             {
   1064                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1065                {
   1066                   png_push_have_row(png_ptr, png_bytep_NULL);
   1067                   png_read_push_finish_row(png_ptr);
   1068                }
   1069             }
   1070 
   1071             break;
   1072          }
   1073 
   1074          case 4:
   1075          {
   1076             int i;
   1077 
   1078             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1079             {
   1080                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1081                png_read_push_finish_row(png_ptr);
   1082             }
   1083 
   1084             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1085             {
   1086                   png_push_have_row(png_ptr, png_bytep_NULL);
   1087                png_read_push_finish_row(png_ptr);
   1088             }
   1089 
   1090             if (png_ptr->pass == 6) /* Pass 5 might be empty */
   1091             {
   1092                   png_push_have_row(png_ptr, png_bytep_NULL);
   1093                png_read_push_finish_row(png_ptr);
   1094             }
   1095 
   1096             break;
   1097          }
   1098 
   1099          case 5:
   1100          {
   1101             int i;
   1102 
   1103             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
   1104             {
   1105                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1106                png_read_push_finish_row(png_ptr);
   1107             }
   1108 
   1109             if (png_ptr->pass == 6) /* Skip top generated row */
   1110             {
   1111                   png_push_have_row(png_ptr, png_bytep_NULL);
   1112                png_read_push_finish_row(png_ptr);
   1113             }
   1114 
   1115             break;
   1116          }
   1117          case 6:
   1118          {
   1119             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1120             png_read_push_finish_row(png_ptr);
   1121 
   1122             if (png_ptr->pass != 6)
   1123                break;
   1124 
   1125                   png_push_have_row(png_ptr, png_bytep_NULL);
   1126             png_read_push_finish_row(png_ptr);
   1127          }
   1128       }
   1129    }
   1130    else
   1131 #endif
   1132    {
   1133       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1134       png_read_push_finish_row(png_ptr);
   1135    }
   1136 }
   1137 
   1138 void /* PRIVATE */
   1139 png_read_push_finish_row(png_structp png_ptr)
   1140 {
   1141 #ifdef PNG_USE_LOCAL_ARRAYS
   1142    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   1143 
   1144    /* Start of interlace block */
   1145    PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
   1146 
   1147    /* Offset to next interlace block */
   1148    PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
   1149 
   1150    /* Start of interlace block in the y direction */
   1151    PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
   1152 
   1153    /* Offset to next interlace block in the y direction */
   1154    PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
   1155 
   1156    /* Height of interlace block.  This is not currently used - if you need
   1157     * it, uncomment it here and in png.h
   1158    PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
   1159    */
   1160 #endif
   1161 
   1162    png_ptr->row_number++;
   1163    if (png_ptr->row_number < png_ptr->num_rows)
   1164       return;
   1165 
   1166 #ifdef PNG_READ_INTERLACING_SUPPORTED
   1167    if (png_ptr->interlaced)
   1168    {
   1169       png_ptr->row_number = 0;
   1170       png_memset_check(png_ptr, png_ptr->prev_row, 0,
   1171          png_ptr->rowbytes + 1);
   1172       do
   1173       {
   1174          png_ptr->pass++;
   1175          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
   1176              (png_ptr->pass == 3 && png_ptr->width < 3) ||
   1177              (png_ptr->pass == 5 && png_ptr->width < 2))
   1178            png_ptr->pass++;
   1179 
   1180          if (png_ptr->pass > 7)
   1181             png_ptr->pass--;
   1182 
   1183          if (png_ptr->pass >= 7)
   1184             break;
   1185 
   1186          png_ptr->iwidth = (png_ptr->width +
   1187             png_pass_inc[png_ptr->pass] - 1 -
   1188             png_pass_start[png_ptr->pass]) /
   1189             png_pass_inc[png_ptr->pass];
   1190 
   1191          if (png_ptr->transformations & PNG_INTERLACE)
   1192             break;
   1193 
   1194          png_ptr->num_rows = (png_ptr->height +
   1195             png_pass_yinc[png_ptr->pass] - 1 -
   1196             png_pass_ystart[png_ptr->pass]) /
   1197             png_pass_yinc[png_ptr->pass];
   1198 
   1199       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
   1200    }
   1201 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   1202 }
   1203 
   1204 #ifdef PNG_READ_tEXt_SUPPORTED
   1205 void /* PRIVATE */
   1206 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
   1207    length)
   1208 {
   1209    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
   1210       {
   1211          png_error(png_ptr, "Out of place tEXt");
   1212          info_ptr = info_ptr; /* To quiet some compiler warnings */
   1213       }
   1214 
   1215 #ifdef PNG_MAX_MALLOC_64K
   1216    png_ptr->skip_length = 0;  /* This may not be necessary */
   1217 
   1218    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
   1219    {
   1220       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
   1221       png_ptr->skip_length = length - (png_uint_32)65535L;
   1222       length = (png_uint_32)65535L;
   1223    }
   1224 #endif
   1225 
   1226    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
   1227       (png_uint_32)(length + 1));
   1228    png_ptr->current_text[length] = '\0';
   1229    png_ptr->current_text_ptr = png_ptr->current_text;
   1230    png_ptr->current_text_size = (png_size_t)length;
   1231    png_ptr->current_text_left = (png_size_t)length;
   1232    png_ptr->process_mode = PNG_READ_tEXt_MODE;
   1233 }
   1234 
   1235 void /* PRIVATE */
   1236 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
   1237 {
   1238    if (png_ptr->buffer_size && png_ptr->current_text_left)
   1239    {
   1240       png_size_t text_size;
   1241 
   1242       if (png_ptr->buffer_size < png_ptr->current_text_left)
   1243          text_size = png_ptr->buffer_size;
   1244 
   1245       else
   1246          text_size = png_ptr->current_text_left;
   1247 
   1248       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
   1249       png_ptr->current_text_left -= text_size;
   1250       png_ptr->current_text_ptr += text_size;
   1251    }
   1252    if (!(png_ptr->current_text_left))
   1253    {
   1254       png_textp text_ptr;
   1255       png_charp text;
   1256       png_charp key;
   1257       int ret;
   1258 
   1259       if (png_ptr->buffer_size < 4)
   1260       {
   1261          png_push_save_buffer(png_ptr);
   1262          return;
   1263       }
   1264 
   1265       png_push_crc_finish(png_ptr);
   1266 
   1267 #ifdef PNG_MAX_MALLOC_64K
   1268       if (png_ptr->skip_length)
   1269          return;
   1270 #endif
   1271 
   1272       key = png_ptr->current_text;
   1273 
   1274       for (text = key; *text; text++)
   1275          /* Empty loop */ ;
   1276 
   1277       if (text < key + png_ptr->current_text_size)
   1278          text++;
   1279 
   1280       text_ptr = (png_textp)png_malloc(png_ptr,
   1281          (png_uint_32)png_sizeof(png_text));
   1282       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
   1283       text_ptr->key = key;
   1284 #ifdef PNG_iTXt_SUPPORTED
   1285       text_ptr->lang = NULL;
   1286       text_ptr->lang_key = NULL;
   1287 #endif
   1288       text_ptr->text = text;
   1289 
   1290       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   1291 
   1292       png_free(png_ptr, key);
   1293       png_free(png_ptr, text_ptr);
   1294       png_ptr->current_text = NULL;
   1295 
   1296       if (ret)
   1297         png_warning(png_ptr, "Insufficient memory to store text chunk.");
   1298    }
   1299 }
   1300 #endif
   1301 
   1302 #ifdef PNG_READ_zTXt_SUPPORTED
   1303 void /* PRIVATE */
   1304 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
   1305    length)
   1306 {
   1307    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
   1308       {
   1309          png_error(png_ptr, "Out of place zTXt");
   1310          info_ptr = info_ptr; /* To quiet some compiler warnings */
   1311       }
   1312 
   1313 #ifdef PNG_MAX_MALLOC_64K
   1314    /* We can't handle zTXt chunks > 64K, since we don't have enough space
   1315     * to be able to store the uncompressed data.  Actually, the threshold
   1316     * is probably around 32K, but it isn't as definite as 64K is.
   1317     */
   1318    if (length > (png_uint_32)65535L)
   1319    {
   1320       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
   1321       png_push_crc_skip(png_ptr, length);
   1322       return;
   1323    }
   1324 #endif
   1325 
   1326    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
   1327       (png_uint_32)(length + 1));
   1328    png_ptr->current_text[length] = '\0';
   1329    png_ptr->current_text_ptr = png_ptr->current_text;
   1330    png_ptr->current_text_size = (png_size_t)length;
   1331    png_ptr->current_text_left = (png_size_t)length;
   1332    png_ptr->process_mode = PNG_READ_zTXt_MODE;
   1333 }
   1334 
   1335 void /* PRIVATE */
   1336 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
   1337 {
   1338    if (png_ptr->buffer_size && png_ptr->current_text_left)
   1339    {
   1340       png_size_t text_size;
   1341 
   1342       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
   1343          text_size = png_ptr->buffer_size;
   1344 
   1345       else
   1346          text_size = png_ptr->current_text_left;
   1347 
   1348       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
   1349       png_ptr->current_text_left -= text_size;
   1350       png_ptr->current_text_ptr += text_size;
   1351    }
   1352    if (!(png_ptr->current_text_left))
   1353    {
   1354       png_textp text_ptr;
   1355       png_charp text;
   1356       png_charp key;
   1357       int ret;
   1358       png_size_t text_size, key_size;
   1359 
   1360       if (png_ptr->buffer_size < 4)
   1361       {
   1362          png_push_save_buffer(png_ptr);
   1363          return;
   1364       }
   1365 
   1366       png_push_crc_finish(png_ptr);
   1367 
   1368       key = png_ptr->current_text;
   1369 
   1370       for (text = key; *text; text++)
   1371          /* Empty loop */ ;
   1372 
   1373       /* zTXt can't have zero text */
   1374       if (text >= key + png_ptr->current_text_size)
   1375       {
   1376          png_ptr->current_text = NULL;
   1377          png_free(png_ptr, key);
   1378          return;
   1379       }
   1380 
   1381       text++;
   1382 
   1383       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
   1384       {
   1385          png_ptr->current_text = NULL;
   1386          png_free(png_ptr, key);
   1387          return;
   1388       }
   1389 
   1390       text++;
   1391 
   1392       png_ptr->zstream.next_in = (png_bytep )text;
   1393       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
   1394          (text - key));
   1395       png_ptr->zstream.next_out = png_ptr->zbuf;
   1396       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
   1397 
   1398       key_size = text - key;
   1399       text_size = 0;
   1400       text = NULL;
   1401       ret = Z_STREAM_END;
   1402 
   1403       while (png_ptr->zstream.avail_in)
   1404       {
   1405          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
   1406          if (ret != Z_OK && ret != Z_STREAM_END)
   1407          {
   1408             inflateReset(&png_ptr->zstream);
   1409             png_ptr->zstream.avail_in = 0;
   1410             png_ptr->current_text = NULL;
   1411             png_free(png_ptr, key);
   1412             png_free(png_ptr, text);
   1413             return;
   1414          }
   1415          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
   1416          {
   1417             if (text == NULL)
   1418             {
   1419                text = (png_charp)png_malloc(png_ptr,
   1420                      (png_uint_32)(png_ptr->zbuf_size
   1421                      - png_ptr->zstream.avail_out + key_size + 1));
   1422 
   1423                png_memcpy(text + key_size, png_ptr->zbuf,
   1424                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
   1425 
   1426                png_memcpy(text, key, key_size);
   1427 
   1428                text_size = key_size + png_ptr->zbuf_size -
   1429                   png_ptr->zstream.avail_out;
   1430 
   1431                *(text + text_size) = '\0';
   1432             }
   1433             else
   1434             {
   1435                png_charp tmp;
   1436 
   1437                tmp = text;
   1438                text = (png_charp)png_malloc(png_ptr, text_size +
   1439                   (png_uint_32)(png_ptr->zbuf_size
   1440                   - png_ptr->zstream.avail_out + 1));
   1441 
   1442                png_memcpy(text, tmp, text_size);
   1443                png_free(png_ptr, tmp);
   1444 
   1445                png_memcpy(text + text_size, png_ptr->zbuf,
   1446                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
   1447 
   1448                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
   1449                *(text + text_size) = '\0';
   1450             }
   1451             if (ret != Z_STREAM_END)
   1452             {
   1453                png_ptr->zstream.next_out = png_ptr->zbuf;
   1454                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
   1455             }
   1456          }
   1457          else
   1458          {
   1459             break;
   1460          }
   1461 
   1462          if (ret == Z_STREAM_END)
   1463             break;
   1464       }
   1465 
   1466       inflateReset(&png_ptr->zstream);
   1467       png_ptr->zstream.avail_in = 0;
   1468 
   1469       if (ret != Z_STREAM_END)
   1470       {
   1471          png_ptr->current_text = NULL;
   1472          png_free(png_ptr, key);
   1473          png_free(png_ptr, text);
   1474          return;
   1475       }
   1476 
   1477       png_ptr->current_text = NULL;
   1478       png_free(png_ptr, key);
   1479       key = text;
   1480       text += key_size;
   1481 
   1482       text_ptr = (png_textp)png_malloc(png_ptr,
   1483           (png_uint_32)png_sizeof(png_text));
   1484       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
   1485       text_ptr->key = key;
   1486 #ifdef PNG_iTXt_SUPPORTED
   1487       text_ptr->lang = NULL;
   1488       text_ptr->lang_key = NULL;
   1489 #endif
   1490       text_ptr->text = text;
   1491 
   1492       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   1493 
   1494       png_free(png_ptr, key);
   1495       png_free(png_ptr, text_ptr);
   1496 
   1497       if (ret)
   1498         png_warning(png_ptr, "Insufficient memory to store text chunk.");
   1499    }
   1500 }
   1501 #endif
   1502 
   1503 #ifdef PNG_READ_iTXt_SUPPORTED
   1504 void /* PRIVATE */
   1505 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
   1506    length)
   1507 {
   1508    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
   1509       {
   1510          png_error(png_ptr, "Out of place iTXt");
   1511          info_ptr = info_ptr; /* To quiet some compiler warnings */
   1512       }
   1513 
   1514 #ifdef PNG_MAX_MALLOC_64K
   1515    png_ptr->skip_length = 0;  /* This may not be necessary */
   1516 
   1517    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
   1518    {
   1519       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
   1520       png_ptr->skip_length = length - (png_uint_32)65535L;
   1521       length = (png_uint_32)65535L;
   1522    }
   1523 #endif
   1524 
   1525    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
   1526       (png_uint_32)(length + 1));
   1527    png_ptr->current_text[length] = '\0';
   1528    png_ptr->current_text_ptr = png_ptr->current_text;
   1529    png_ptr->current_text_size = (png_size_t)length;
   1530    png_ptr->current_text_left = (png_size_t)length;
   1531    png_ptr->process_mode = PNG_READ_iTXt_MODE;
   1532 }
   1533 
   1534 void /* PRIVATE */
   1535 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
   1536 {
   1537 
   1538    if (png_ptr->buffer_size && png_ptr->current_text_left)
   1539    {
   1540       png_size_t text_size;
   1541 
   1542       if (png_ptr->buffer_size < png_ptr->current_text_left)
   1543          text_size = png_ptr->buffer_size;
   1544 
   1545       else
   1546          text_size = png_ptr->current_text_left;
   1547 
   1548       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
   1549       png_ptr->current_text_left -= text_size;
   1550       png_ptr->current_text_ptr += text_size;
   1551    }
   1552    if (!(png_ptr->current_text_left))
   1553    {
   1554       png_textp text_ptr;
   1555       png_charp key;
   1556       int comp_flag;
   1557       png_charp lang;
   1558       png_charp lang_key;
   1559       png_charp text;
   1560       int ret;
   1561 
   1562       if (png_ptr->buffer_size < 4)
   1563       {
   1564          png_push_save_buffer(png_ptr);
   1565          return;
   1566       }
   1567 
   1568       png_push_crc_finish(png_ptr);
   1569 
   1570 #ifdef PNG_MAX_MALLOC_64K
   1571       if (png_ptr->skip_length)
   1572          return;
   1573 #endif
   1574 
   1575       key = png_ptr->current_text;
   1576 
   1577       for (lang = key; *lang; lang++)
   1578          /* Empty loop */ ;
   1579 
   1580       if (lang < key + png_ptr->current_text_size - 3)
   1581          lang++;
   1582 
   1583       comp_flag = *lang++;
   1584       lang++;     /* Skip comp_type, always zero */
   1585 
   1586       for (lang_key = lang; *lang_key; lang_key++)
   1587          /* Empty loop */ ;
   1588 
   1589       lang_key++;        /* Skip NUL separator */
   1590 
   1591       text=lang_key;
   1592 
   1593       if (lang_key < key + png_ptr->current_text_size - 1)
   1594       {
   1595         for (; *text; text++)
   1596            /* Empty loop */ ;
   1597       }
   1598 
   1599       if (text < key + png_ptr->current_text_size)
   1600          text++;
   1601 
   1602       text_ptr = (png_textp)png_malloc(png_ptr,
   1603          (png_uint_32)png_sizeof(png_text));
   1604 
   1605       text_ptr->compression = comp_flag + 2;
   1606       text_ptr->key = key;
   1607       text_ptr->lang = lang;
   1608       text_ptr->lang_key = lang_key;
   1609       text_ptr->text = text;
   1610       text_ptr->text_length = 0;
   1611       text_ptr->itxt_length = png_strlen(text);
   1612 
   1613       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
   1614 
   1615       png_ptr->current_text = NULL;
   1616 
   1617       png_free(png_ptr, text_ptr);
   1618       if (ret)
   1619          png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
   1620    }
   1621 }
   1622 #endif
   1623 
   1624 /* This function is called when we haven't found a handler for this
   1625  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
   1626  * name or a critical chunk), the chunk is (currently) silently ignored.
   1627  */
   1628 void /* PRIVATE */
   1629 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
   1630    length)
   1631 {
   1632    png_uint_32 skip = 0;
   1633 
   1634    if (!(png_ptr->chunk_name[0] & 0x20))
   1635    {
   1636 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   1637       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   1638          PNG_HANDLE_CHUNK_ALWAYS
   1639 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   1640          && png_ptr->read_user_chunk_fn == NULL
   1641 #endif
   1642          )
   1643 #endif
   1644          png_chunk_error(png_ptr, "unknown critical chunk");
   1645 
   1646       info_ptr = info_ptr; /* To quiet some compiler warnings */
   1647    }
   1648 
   1649 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
   1650    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
   1651    {
   1652 #ifdef PNG_MAX_MALLOC_64K
   1653       if (length > (png_uint_32)65535L)
   1654       {
   1655           png_warning(png_ptr, "unknown chunk too large to fit in memory");
   1656           skip = length - (png_uint_32)65535L;
   1657           length = (png_uint_32)65535L;
   1658       }
   1659 #endif
   1660       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
   1661                  (png_charp)png_ptr->chunk_name,
   1662                  png_sizeof(png_ptr->unknown_chunk.name));
   1663       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
   1664         = '\0';
   1665 
   1666       png_ptr->unknown_chunk.size = (png_size_t)length;
   1667 
   1668       if (length == 0)
   1669          png_ptr->unknown_chunk.data = NULL;
   1670 
   1671       else
   1672       {
   1673          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
   1674             (png_uint_32)length);
   1675          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
   1676       }
   1677 
   1678 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
   1679       if (png_ptr->read_user_chunk_fn != NULL)
   1680       {
   1681          /* Callback to user unknown chunk handler */
   1682          int ret;
   1683          ret = (*(png_ptr->read_user_chunk_fn))
   1684            (png_ptr, &png_ptr->unknown_chunk);
   1685 
   1686          if (ret < 0)
   1687             png_chunk_error(png_ptr, "error in user chunk");
   1688 
   1689          if (ret == 0)
   1690          {
   1691             if (!(png_ptr->chunk_name[0] & 0x20))
   1692                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
   1693                     PNG_HANDLE_CHUNK_ALWAYS)
   1694                   png_chunk_error(png_ptr, "unknown critical chunk");
   1695             png_set_unknown_chunks(png_ptr, info_ptr,
   1696                &png_ptr->unknown_chunk, 1);
   1697          }
   1698       }
   1699 
   1700       else
   1701 #endif
   1702         png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
   1703       png_free(png_ptr, png_ptr->unknown_chunk.data);
   1704       png_ptr->unknown_chunk.data = NULL;
   1705    }
   1706 
   1707    else
   1708 #endif
   1709       skip=length;
   1710    png_push_crc_skip(png_ptr, skip);
   1711 }
   1712 
   1713 void /* PRIVATE */
   1714 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
   1715 {
   1716    if (png_ptr->info_fn != NULL)
   1717       (*(png_ptr->info_fn))(png_ptr, info_ptr);
   1718 }
   1719 
   1720 void /* PRIVATE */
   1721 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
   1722 {
   1723    if (png_ptr->end_fn != NULL)
   1724       (*(png_ptr->end_fn))(png_ptr, info_ptr);
   1725 }
   1726 
   1727 void /* PRIVATE */
   1728 png_push_have_row(png_structp png_ptr, png_bytep row)
   1729 {
   1730    if (png_ptr->row_fn != NULL)
   1731       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
   1732          (int)png_ptr->pass);
   1733 }
   1734 
   1735 void PNGAPI
   1736 png_progressive_combine_row (png_structp png_ptr,
   1737    png_bytep old_row, png_bytep new_row)
   1738 {
   1739 #ifdef PNG_USE_LOCAL_ARRAYS
   1740    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
   1741       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
   1742 #endif
   1743 
   1744    if (png_ptr == NULL)
   1745       return;
   1746 
   1747    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
   1748       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
   1749 }
   1750 
   1751 void PNGAPI
   1752 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
   1753    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
   1754    png_progressive_end_ptr end_fn)
   1755 {
   1756    if (png_ptr == NULL)
   1757       return;
   1758 
   1759    png_ptr->info_fn = info_fn;
   1760    png_ptr->row_fn = row_fn;
   1761    png_ptr->end_fn = end_fn;
   1762 
   1763    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
   1764 }
   1765 
   1766 png_voidp PNGAPI
   1767 png_get_progressive_ptr(png_structp png_ptr)
   1768 {
   1769    if (png_ptr == NULL)
   1770       return (NULL);
   1771 
   1772    return png_ptr->io_ptr;
   1773 }
   1774 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
   1775