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