graphics

experiments with opengl3.2/ogles3.3 on linux and win7
git clone http://frotz.net/git/graphics.git
Log | Files | Refs

pngpread.c (34194B)


      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       case PNG_SKIP_MODE:
     75       {
     76          png_push_crc_finish(png_ptr);
     77          break;
     78       }
     79 
     80       default:
     81       {
     82          png_ptr->buffer_size = 0;
     83          break;
     84       }
     85    }
     86 }
     87 
     88 /* Read any remaining signature bytes from the stream and compare them with
     89  * the correct PNG signature.  It is possible that this routine is called
     90  * with bytes already read from the signature, either because they have been
     91  * checked by the calling application, or because of multiple calls to this
     92  * routine.
     93  */
     94 void /* PRIVATE */
     95 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
     96 {
     97    png_size_t num_checked = png_ptr->sig_bytes,
     98              num_to_check = 8 - num_checked;
     99 
    100    if (png_ptr->buffer_size < num_to_check)
    101    {
    102       num_to_check = png_ptr->buffer_size;
    103    }
    104 
    105    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
    106       num_to_check);
    107    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
    108 
    109    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
    110    {
    111       if (num_checked < 4 &&
    112           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
    113          png_error(png_ptr, "Not a PNG file");
    114       else
    115          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    116    }
    117    else
    118    {
    119       if (png_ptr->sig_bytes >= 8)
    120       {
    121          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    122       }
    123    }
    124 }
    125 
    126 void /* PRIVATE */
    127 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
    128 {
    129 #ifdef PNG_USE_LOCAL_ARRAYS
    130       PNG_CONST PNG_IHDR;
    131       PNG_CONST PNG_IDAT;
    132       PNG_CONST PNG_IEND;
    133       PNG_CONST PNG_PLTE;
    134 #ifdef PNG_READ_bKGD_SUPPORTED
    135       PNG_CONST PNG_bKGD;
    136 #endif
    137 #ifdef PNG_READ_cHRM_SUPPORTED
    138       PNG_CONST PNG_cHRM;
    139 #endif
    140 #ifdef PNG_READ_gAMA_SUPPORTED
    141       PNG_CONST PNG_gAMA;
    142 #endif
    143 #ifdef PNG_READ_hIST_SUPPORTED
    144       PNG_CONST PNG_hIST;
    145 #endif
    146 #ifdef PNG_READ_iCCP_SUPPORTED
    147       PNG_CONST PNG_iCCP;
    148 #endif
    149 #ifdef PNG_READ_iTXt_SUPPORTED
    150       PNG_CONST PNG_iTXt;
    151 #endif
    152 #ifdef PNG_READ_oFFs_SUPPORTED
    153       PNG_CONST PNG_oFFs;
    154 #endif
    155 #ifdef PNG_READ_pCAL_SUPPORTED
    156       PNG_CONST PNG_pCAL;
    157 #endif
    158 #ifdef PNG_READ_pHYs_SUPPORTED
    159       PNG_CONST PNG_pHYs;
    160 #endif
    161 #ifdef PNG_READ_sBIT_SUPPORTED
    162       PNG_CONST PNG_sBIT;
    163 #endif
    164 #ifdef PNG_READ_sCAL_SUPPORTED
    165       PNG_CONST PNG_sCAL;
    166 #endif
    167 #ifdef PNG_READ_sRGB_SUPPORTED
    168       PNG_CONST PNG_sRGB;
    169 #endif
    170 #ifdef PNG_READ_sPLT_SUPPORTED
    171       PNG_CONST PNG_sPLT;
    172 #endif
    173 #ifdef PNG_READ_tEXt_SUPPORTED
    174       PNG_CONST PNG_tEXt;
    175 #endif
    176 #ifdef PNG_READ_tIME_SUPPORTED
    177       PNG_CONST PNG_tIME;
    178 #endif
    179 #ifdef PNG_READ_tRNS_SUPPORTED
    180       PNG_CONST PNG_tRNS;
    181 #endif
    182 #ifdef PNG_READ_zTXt_SUPPORTED
    183       PNG_CONST PNG_zTXt;
    184 #endif
    185 #endif /* PNG_USE_LOCAL_ARRAYS */
    186 
    187    /* First we make sure we have enough data for the 4 byte chunk name
    188     * and the 4 byte chunk length before proceeding with decoding the
    189     * chunk data.  To fully decode each of these chunks, we also make
    190     * sure we have enough data in the buffer for the 4 byte CRC at the
    191     * end of every chunk (except IDAT, which is handled separately).
    192     */
    193    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    194    {
    195       png_byte chunk_length[4];
    196 
    197       if (png_ptr->buffer_size < 8)
    198       {
    199          png_push_save_buffer(png_ptr);
    200          return;
    201       }
    202 
    203       png_push_fill_buffer(png_ptr, chunk_length, 4);
    204       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    205       png_reset_crc(png_ptr);
    206       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
    207       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
    208       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    209    }
    210 
    211    if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    212      if (png_ptr->mode & PNG_AFTER_IDAT)
    213         png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
    214 
    215    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
    216    {
    217       if (png_ptr->push_length != 13)
    218          png_error(png_ptr, "Invalid IHDR length");
    219 
    220       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    221       {
    222          png_push_save_buffer(png_ptr);
    223          return;
    224       }
    225 
    226       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
    227    }
    228 
    229    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
    230    {
    231       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    232       {
    233          png_push_save_buffer(png_ptr);
    234          return;
    235       }
    236 
    237       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
    238 
    239       png_ptr->process_mode = PNG_READ_DONE_MODE;
    240       png_push_have_end(png_ptr, info_ptr);
    241    }
    242 
    243 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    244    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
    245    {
    246       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    247       {
    248          png_push_save_buffer(png_ptr);
    249          return;
    250       }
    251 
    252       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    253          png_ptr->mode |= PNG_HAVE_IDAT;
    254 
    255       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    256 
    257       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
    258          png_ptr->mode |= PNG_HAVE_PLTE;
    259 
    260       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    261       {
    262          if (!(png_ptr->mode & PNG_HAVE_IHDR))
    263             png_error(png_ptr, "Missing IHDR before IDAT");
    264 
    265          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    266                   !(png_ptr->mode & PNG_HAVE_PLTE))
    267             png_error(png_ptr, "Missing PLTE before IDAT");
    268       }
    269    }
    270 
    271 #endif
    272    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
    273    {
    274       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    275       {
    276          png_push_save_buffer(png_ptr);
    277          return;
    278       }
    279       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
    280    }
    281 
    282    else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    283    {
    284       /* If we reach an IDAT chunk, this means we have read all of the
    285        * header chunks, and we can start reading the image (or if this
    286        * is called after the image has been read - we have an error).
    287        */
    288 
    289       if (!(png_ptr->mode & PNG_HAVE_IHDR))
    290          png_error(png_ptr, "Missing IHDR before IDAT");
    291 
    292       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    293           !(png_ptr->mode & PNG_HAVE_PLTE))
    294          png_error(png_ptr, "Missing PLTE before IDAT");
    295 
    296       if (png_ptr->mode & PNG_HAVE_IDAT)
    297       {
    298          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
    299             if (png_ptr->push_length == 0)
    300                return;
    301 
    302          if (png_ptr->mode & PNG_AFTER_IDAT)
    303             png_error(png_ptr, "Too many IDAT's found");
    304       }
    305 
    306       png_ptr->idat_size = png_ptr->push_length;
    307       png_ptr->mode |= PNG_HAVE_IDAT;
    308       png_ptr->process_mode = PNG_READ_IDAT_MODE;
    309       png_push_have_info(png_ptr, info_ptr);
    310       png_ptr->zstream.avail_out =
    311           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
    312           png_ptr->iwidth) + 1;
    313       png_ptr->zstream.next_out = png_ptr->row_buf;
    314       return;
    315    }
    316 
    317 #ifdef PNG_READ_gAMA_SUPPORTED
    318    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 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 
    326       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
    327    }
    328 
    329 #endif
    330 #ifdef PNG_READ_sBIT_SUPPORTED
    331    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
    332    {
    333       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    334       {
    335          png_push_save_buffer(png_ptr);
    336          return;
    337       }
    338 
    339       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
    340    }
    341 
    342 #endif
    343 #ifdef PNG_READ_cHRM_SUPPORTED
    344    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
    345    {
    346       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    347       {
    348          png_push_save_buffer(png_ptr);
    349          return;
    350       }
    351 
    352       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
    353    }
    354 
    355 #endif
    356 #ifdef PNG_READ_sRGB_SUPPORTED
    357    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
    358    {
    359       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    360       {
    361          png_push_save_buffer(png_ptr);
    362          return;
    363       }
    364 
    365       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
    366    }
    367 
    368 #endif
    369 #ifdef PNG_READ_iCCP_SUPPORTED
    370    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
    371    {
    372       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    373       {
    374          png_push_save_buffer(png_ptr);
    375          return;
    376       }
    377 
    378       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
    379    }
    380 
    381 #endif
    382 #ifdef PNG_READ_sPLT_SUPPORTED
    383    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
    384    {
    385       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    386       {
    387          png_push_save_buffer(png_ptr);
    388          return;
    389       }
    390 
    391       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
    392    }
    393 
    394 #endif
    395 #ifdef PNG_READ_tRNS_SUPPORTED
    396    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
    397    {
    398       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    399       {
    400          png_push_save_buffer(png_ptr);
    401          return;
    402       }
    403 
    404       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
    405    }
    406 
    407 #endif
    408 #ifdef PNG_READ_bKGD_SUPPORTED
    409    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
    410    {
    411       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    412       {
    413          png_push_save_buffer(png_ptr);
    414          return;
    415       }
    416 
    417       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
    418    }
    419 
    420 #endif
    421 #ifdef PNG_READ_hIST_SUPPORTED
    422    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
    423    {
    424       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    425       {
    426          png_push_save_buffer(png_ptr);
    427          return;
    428       }
    429 
    430       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
    431    }
    432 
    433 #endif
    434 #ifdef PNG_READ_pHYs_SUPPORTED
    435    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
    436    {
    437       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    438       {
    439          png_push_save_buffer(png_ptr);
    440          return;
    441       }
    442 
    443       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
    444    }
    445 
    446 #endif
    447 #ifdef PNG_READ_oFFs_SUPPORTED
    448    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
    449    {
    450       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    451       {
    452          png_push_save_buffer(png_ptr);
    453          return;
    454       }
    455 
    456       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
    457    }
    458 #endif
    459 
    460 #ifdef PNG_READ_pCAL_SUPPORTED
    461    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 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 
    469       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
    470    }
    471 
    472 #endif
    473 #ifdef PNG_READ_sCAL_SUPPORTED
    474    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
    475    {
    476       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    477       {
    478          png_push_save_buffer(png_ptr);
    479          return;
    480       }
    481 
    482       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
    483    }
    484 
    485 #endif
    486 #ifdef PNG_READ_tIME_SUPPORTED
    487    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
    488    {
    489       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    490       {
    491          png_push_save_buffer(png_ptr);
    492          return;
    493       }
    494 
    495       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
    496    }
    497 
    498 #endif
    499 #ifdef PNG_READ_tEXt_SUPPORTED
    500    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
    501    {
    502       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    503       {
    504          png_push_save_buffer(png_ptr);
    505          return;
    506       }
    507 
    508       png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
    509    }
    510 
    511 #endif
    512 #ifdef PNG_READ_zTXt_SUPPORTED
    513    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
    514    {
    515       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    516       {
    517          png_push_save_buffer(png_ptr);
    518          return;
    519       }
    520 
    521       png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
    522    }
    523 
    524 #endif
    525 #ifdef PNG_READ_iTXt_SUPPORTED
    526    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
    527    {
    528       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    529       {
    530          png_push_save_buffer(png_ptr);
    531          return;
    532       }
    533 
    534       png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
    535    }
    536 
    537 #endif
    538    else
    539    {
    540       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
    541       {
    542          png_push_save_buffer(png_ptr);
    543          return;
    544       }
    545       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
    546    }
    547 
    548    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    549 }
    550 
    551 void /* PRIVATE */
    552 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
    553 {
    554    png_ptr->process_mode = PNG_SKIP_MODE;
    555    png_ptr->skip_length = skip;
    556 }
    557 
    558 void /* PRIVATE */
    559 png_push_crc_finish(png_structp png_ptr)
    560 {
    561    if (png_ptr->skip_length && png_ptr->save_buffer_size)
    562    {
    563       png_size_t save_size;
    564 
    565       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
    566          save_size = (png_size_t)png_ptr->skip_length;
    567       else
    568          save_size = png_ptr->save_buffer_size;
    569 
    570       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    571 
    572       png_ptr->skip_length -= save_size;
    573       png_ptr->buffer_size -= save_size;
    574       png_ptr->save_buffer_size -= save_size;
    575       png_ptr->save_buffer_ptr += save_size;
    576    }
    577    if (png_ptr->skip_length && png_ptr->current_buffer_size)
    578    {
    579       png_size_t save_size;
    580 
    581       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
    582          save_size = (png_size_t)png_ptr->skip_length;
    583       else
    584          save_size = png_ptr->current_buffer_size;
    585 
    586       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    587 
    588       png_ptr->skip_length -= save_size;
    589       png_ptr->buffer_size -= save_size;
    590       png_ptr->current_buffer_size -= save_size;
    591       png_ptr->current_buffer_ptr += save_size;
    592    }
    593    if (!png_ptr->skip_length)
    594    {
    595       if (png_ptr->buffer_size < 4)
    596       {
    597          png_push_save_buffer(png_ptr);
    598          return;
    599       }
    600 
    601       png_crc_finish(png_ptr, 0);
    602       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    603    }
    604 }
    605 
    606 void PNGAPI
    607 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
    608 {
    609    png_bytep ptr;
    610 
    611    if (png_ptr == NULL)
    612       return;
    613 
    614    ptr = buffer;
    615    if (png_ptr->save_buffer_size)
    616    {
    617       png_size_t save_size;
    618 
    619       if (length < png_ptr->save_buffer_size)
    620          save_size = length;
    621       else
    622          save_size = png_ptr->save_buffer_size;
    623 
    624       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
    625       length -= save_size;
    626       ptr += save_size;
    627       png_ptr->buffer_size -= save_size;
    628       png_ptr->save_buffer_size -= save_size;
    629       png_ptr->save_buffer_ptr += save_size;
    630    }
    631    if (length && png_ptr->current_buffer_size)
    632    {
    633       png_size_t save_size;
    634 
    635       if (length < png_ptr->current_buffer_size)
    636          save_size = length;
    637 
    638       else
    639          save_size = png_ptr->current_buffer_size;
    640 
    641       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
    642       png_ptr->buffer_size -= save_size;
    643       png_ptr->current_buffer_size -= save_size;
    644       png_ptr->current_buffer_ptr += save_size;
    645    }
    646 }
    647 
    648 void /* PRIVATE */
    649 png_push_save_buffer(png_structp png_ptr)
    650 {
    651    if (png_ptr->save_buffer_size)
    652    {
    653       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
    654       {
    655          png_size_t i, istop;
    656          png_bytep sp;
    657          png_bytep dp;
    658 
    659          istop = png_ptr->save_buffer_size;
    660          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
    661             i < istop; i++, sp++, dp++)
    662          {
    663             *dp = *sp;
    664          }
    665       }
    666    }
    667    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
    668       png_ptr->save_buffer_max)
    669    {
    670       png_size_t new_max;
    671       png_bytep old_buffer;
    672 
    673       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
    674          (png_ptr->current_buffer_size + 256))
    675       {
    676         png_error(png_ptr, "Potential overflow of save_buffer");
    677       }
    678 
    679       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
    680       old_buffer = png_ptr->save_buffer;
    681       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
    682          (png_uint_32)new_max);
    683       if (png_ptr->save_buffer == NULL)
    684       {
    685         png_free(png_ptr, old_buffer);
    686         png_error(png_ptr, "Insufficient memory for save_buffer");
    687       }
    688       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
    689       png_free(png_ptr, old_buffer);
    690       png_ptr->save_buffer_max = new_max;
    691    }
    692    if (png_ptr->current_buffer_size)
    693    {
    694       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
    695          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
    696       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
    697       png_ptr->current_buffer_size = 0;
    698    }
    699    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
    700    png_ptr->buffer_size = 0;
    701 }
    702 
    703 void /* PRIVATE */
    704 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
    705    png_size_t buffer_length)
    706 {
    707    png_ptr->current_buffer = buffer;
    708    png_ptr->current_buffer_size = buffer_length;
    709    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
    710    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
    711 }
    712 
    713 void /* PRIVATE */
    714 png_push_read_IDAT(png_structp png_ptr)
    715 {
    716 #ifdef PNG_USE_LOCAL_ARRAYS
    717    PNG_CONST PNG_IDAT;
    718 #endif
    719    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
    720    {
    721       png_byte chunk_length[4];
    722 
    723       if (png_ptr->buffer_size < 8)
    724       {
    725          png_push_save_buffer(png_ptr);
    726          return;
    727       }
    728 
    729       png_push_fill_buffer(png_ptr, chunk_length, 4);
    730       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
    731       png_reset_crc(png_ptr);
    732       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
    733       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
    734 
    735       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    736       {
    737          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
    738          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    739             png_error(png_ptr, "Not enough compressed data");
    740          return;
    741       }
    742 
    743       png_ptr->idat_size = png_ptr->push_length;
    744    }
    745    if (png_ptr->idat_size && png_ptr->save_buffer_size)
    746    {
    747       png_size_t save_size;
    748 
    749       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
    750       {
    751          save_size = (png_size_t)png_ptr->idat_size;
    752 
    753          /* Check for overflow */
    754          if ((png_uint_32)save_size != png_ptr->idat_size)
    755             png_error(png_ptr, "save_size overflowed in pngpread");
    756       }
    757       else
    758          save_size = png_ptr->save_buffer_size;
    759 
    760       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    761 
    762       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
    763 
    764       png_ptr->idat_size -= save_size;
    765       png_ptr->buffer_size -= save_size;
    766       png_ptr->save_buffer_size -= save_size;
    767       png_ptr->save_buffer_ptr += save_size;
    768    }
    769    if (png_ptr->idat_size && png_ptr->current_buffer_size)
    770    {
    771       png_size_t save_size;
    772 
    773       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_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->current_buffer_size;
    783 
    784       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    785 
    786       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
    787 
    788       png_ptr->idat_size -= save_size;
    789       png_ptr->buffer_size -= save_size;
    790       png_ptr->current_buffer_size -= save_size;
    791       png_ptr->current_buffer_ptr += save_size;
    792    }
    793    if (!png_ptr->idat_size)
    794    {
    795       if (png_ptr->buffer_size < 4)
    796       {
    797          png_push_save_buffer(png_ptr);
    798          return;
    799       }
    800 
    801       png_crc_finish(png_ptr, 0);
    802       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    803       png_ptr->mode |= PNG_AFTER_IDAT;
    804    }
    805 }
    806 
    807 void /* PRIVATE */
    808 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    809    png_size_t buffer_length)
    810 {
    811    /* The caller checks for a non-zero buffer length. */
    812    if (!(buffer_length > 0) || buffer == NULL)
    813       png_error(png_ptr, "No IDAT data (internal error)");
    814 
    815    /* This routine must process all the data it has been given
    816     * before returning, calling the row callback as required to
    817     * handle the uncompressed results.
    818     */
    819    png_ptr->zstream.next_in = buffer;
    820    png_ptr->zstream.avail_in = (uInt)buffer_length;
    821 
    822    /* Keep going until the decompressed data is all processed
    823     * or the stream marked as finished.
    824     */
    825    while (png_ptr->zstream.avail_in > 0 &&
    826 	  !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    827    {
    828       int ret;
    829 
    830       /* We have data for zlib, but we must check that zlib
    831        * has somewhere to put the results.  It doesn't matter
    832        * if we don't expect any results -- it may be the input
    833        * data is just the LZ end code.
    834        */
    835       if (!(png_ptr->zstream.avail_out > 0))
    836       {
    837          png_ptr->zstream.avail_out =
    838              (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
    839              png_ptr->iwidth) + 1;
    840          png_ptr->zstream.next_out = png_ptr->row_buf;
    841       }
    842 
    843       /* Using Z_SYNC_FLUSH here means that an unterminated
    844        * LZ stream can still be handled (a stream with a missing
    845        * end code), otherwise (Z_NO_FLUSH) a future zlib
    846        * implementation might defer output and, therefore,
    847        * change the current behavior.  (See comments in inflate.c
    848        * for why this doesn't happen at present with zlib 1.2.5.)
    849        */
    850       ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
    851 
    852       /* Check for any failure before proceeding. */
    853       if (ret != Z_OK && ret != Z_STREAM_END)
    854       {
    855 	 /* Terminate the decompression. */
    856 	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    857 
    858          /* This may be a truncated stream (missing or
    859 	  * damaged end code).  Treat that as a warning.
    860 	  */
    861          if (png_ptr->row_number >= png_ptr->num_rows ||
    862 	     png_ptr->pass > 6)
    863 	    png_warning(png_ptr, "Truncated compressed data in IDAT");
    864 	 else
    865 	    png_error(png_ptr, "Decompression error in IDAT");
    866 
    867 	 /* Skip the check on unprocessed input */
    868          return;
    869       }
    870 
    871       /* Did inflate output any data? */
    872       if (png_ptr->zstream.next_out != png_ptr->row_buf)
    873       {
    874 	 /* Is this unexpected data after the last row?
    875 	  * If it is, artificially terminate the LZ output
    876 	  * here.
    877 	  */
    878          if (png_ptr->row_number >= png_ptr->num_rows ||
    879 	     png_ptr->pass > 6)
    880          {
    881 	    /* Extra data. */
    882 	    png_warning(png_ptr, "Extra compressed data in IDAT");
    883             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    884 	    /* Do no more processing; skip the unprocessed
    885 	     * input check below.
    886 	     */
    887             return;
    888 	 }
    889 
    890 	 /* Do we have a complete row? */
    891 	 if (png_ptr->zstream.avail_out == 0)
    892 	    png_push_process_row(png_ptr);
    893       }
    894 
    895       /* And check for the end of the stream. */
    896       if (ret == Z_STREAM_END)
    897 	 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    898    }
    899 
    900    /* All the data should have been processed, if anything
    901     * is left at this point we have bytes of IDAT data
    902     * after the zlib end code.
    903     */
    904    if (png_ptr->zstream.avail_in > 0)
    905       png_warning(png_ptr, "Extra compression data");
    906 }
    907 
    908 void /* PRIVATE */
    909 png_push_process_row(png_structp png_ptr)
    910 {
    911    png_ptr->row_info.color_type = png_ptr->color_type;
    912    png_ptr->row_info.width = png_ptr->iwidth;
    913    png_ptr->row_info.channels = png_ptr->channels;
    914    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    915    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
    916 
    917    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
    918        png_ptr->row_info.width);
    919 
    920    png_read_filter_row(png_ptr, &(png_ptr->row_info),
    921        png_ptr->row_buf + 1, png_ptr->prev_row + 1,
    922        (int)(png_ptr->row_buf[0]));
    923 
    924    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
    925       png_ptr->rowbytes + 1);
    926 
    927    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
    928       png_do_read_transformations(png_ptr);
    929 
    930 #ifdef PNG_READ_INTERLACING_SUPPORTED
    931    /* Blow up interlaced rows to full size */
    932    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    933    {
    934       if (png_ptr->pass < 6)
    935 /*       old interface (pre-1.0.9):
    936          png_do_read_interlace(&(png_ptr->row_info),
    937              png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
    938  */
    939          png_do_read_interlace(png_ptr);
    940 
    941     switch (png_ptr->pass)
    942     {
    943          case 0:
    944          {
    945             int i;
    946             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
    947             {
    948                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    949                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
    950             }
    951 
    952             if (png_ptr->pass == 2) /* Pass 1 might be empty */
    953             {
    954                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    955                {
    956                   png_push_have_row(png_ptr, png_bytep_NULL);
    957                   png_read_push_finish_row(png_ptr);
    958                }
    959             }
    960 
    961             if (png_ptr->pass == 4 && png_ptr->height <= 4)
    962             {
    963                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    964                {
    965                   png_push_have_row(png_ptr, png_bytep_NULL);
    966                   png_read_push_finish_row(png_ptr);
    967                }
    968             }
    969 
    970             if (png_ptr->pass == 6 && png_ptr->height <= 4)
    971             {
    972                   png_push_have_row(png_ptr, png_bytep_NULL);
    973                 png_read_push_finish_row(png_ptr);
    974             }
    975 
    976             break;
    977          }
    978 
    979          case 1:
    980          {
    981             int i;
    982             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
    983             {
    984                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    985                png_read_push_finish_row(png_ptr);
    986             }
    987 
    988             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
    989             {
    990                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    991                {
    992                   png_push_have_row(png_ptr, png_bytep_NULL);
    993                   png_read_push_finish_row(png_ptr);
    994                }
    995             }
    996 
    997             break;
    998          }
    999 
   1000          case 2:
   1001          {
   1002             int i;
   1003 
   1004             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1005             {
   1006                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1007                png_read_push_finish_row(png_ptr);
   1008             }
   1009 
   1010             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
   1011             {
   1012                   png_push_have_row(png_ptr, png_bytep_NULL);
   1013                png_read_push_finish_row(png_ptr);
   1014             }
   1015 
   1016             if (png_ptr->pass == 4) /* Pass 3 might be empty */
   1017             {
   1018                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1019                {
   1020                   png_push_have_row(png_ptr, png_bytep_NULL);
   1021                   png_read_push_finish_row(png_ptr);
   1022                }
   1023             }
   1024 
   1025             break;
   1026          }
   1027 
   1028          case 3:
   1029          {
   1030             int i;
   1031 
   1032             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
   1033             {
   1034                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1035                png_read_push_finish_row(png_ptr);
   1036             }
   1037 
   1038             if (png_ptr->pass == 4) /* Skip top two generated rows */
   1039             {
   1040                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1041                {
   1042                   png_push_have_row(png_ptr, png_bytep_NULL);
   1043                   png_read_push_finish_row(png_ptr);
   1044                }
   1045             }
   1046 
   1047             break;
   1048          }
   1049 
   1050          case 4:
   1051          {
   1052             int i;
   1053 
   1054             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1055             {
   1056                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1057                png_read_push_finish_row(png_ptr);
   1058             }
   1059 
   1060             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
   1061             {
   1062                   png_push_have_row(png_ptr, png_bytep_NULL);
   1063                png_read_push_finish_row(png_ptr);
   1064             }
   1065 
   1066             if (png_ptr->pass == 6) /* Pass 5 might be empty */
   1067             {
   1068                   png_push_have_row(png_ptr, png_bytep_NULL);
   1069                png_read_push_finish_row(png_ptr);
   1070             }
   1071 
   1072             break;
   1073          }
   1074 
   1075          case 5:
   1076          {
   1077             int i;
   1078 
   1079             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
   1080             {
   1081                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1082                png_read_push_finish_row(png_ptr);
   1083             }
   1084 
   1085             if (png_ptr->pass == 6) /* Skip top generated row */
   1086             {
   1087                   png_push_have_row(png_ptr, png_bytep_NULL);
   1088                png_read_push_finish_row(png_ptr);
   1089             }
   1090 
   1091             break;
   1092          }
   1093          case 6:
   1094          {
   1095             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1096             png_read_push_finish_row(png_ptr);
   1097 
   1098             if (png_ptr->pass != 6)
   1099                break;
   1100 
   1101                   png_push_have_row(png_ptr, png_bytep_NULL);
   1102             png_read_push_finish_row(png_ptr);
   1103          }
   1104       }
   1105    }
   1106    else
   1107 #endif
   1108    {
   1109       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
   1110       png_read_push_finish_row(png_ptr);
   1111    }
   1112 }
   1113 
   1114 void /* PRIVATE */
   1115 png_read_push_finish_row(png_structp png_ptr)
   1116 {
   1117 #ifdef PNG_USE_LOCAL_ARRAYS
   1118    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
   1119 
   1120    /* Start of interlace block */
   1121    PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
   1122 
   1123    /* Offset to next interlace block */
   1124    PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
   1125 
   1126    /* Start of interlace block in the y direction */
   1127    PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
   1128 
   1129    /* Offset to next interlace block in the y direction */
   1130    PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
   1131 
   1132    /* Height of interlace block.  This is not currently used - if you need
   1133     * it, uncomment it here and in png.h
   1134    PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
   1135    */
   1136 #endif
   1137 
   1138    png_ptr->row_number++;
   1139    if (png_ptr->row_number < png_ptr->num_rows)
   1140       return;
   1141 
   1142 #ifdef PNG_READ_INTERLACING_SUPPORTED
   1143    if (png_ptr->interlaced)
   1144    {
   1145       png_ptr->row_number = 0;
   1146       png_memset_check(png_ptr, png_ptr->prev_row, 0,
   1147          png_ptr->rowbytes + 1);
   1148       do
   1149       {
   1150          png_ptr->pass++;
   1151          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
   1152              (png_ptr->pass == 3 && png_ptr->width < 3) ||
   1153              (png_ptr->pass == 5 && png_ptr->width < 2))
   1154            png_ptr->pass++;
   1155 
   1156          if (png_ptr->pass > 7)
   1157             png_ptr->pass--;
   1158 
   1159          if (png_ptr->pass >= 7)
   1160             break;
   1161 
   1162          png_ptr->iwidth = (png_ptr->width +
   1163             png_pass_inc[png_ptr->pass] - 1 -
   1164             png_pass_start[png_ptr->pass]) /
   1165             png_pass_inc[png_ptr->pass];
   1166 
   1167          if (png_ptr->transformations & PNG_INTERLACE)
   1168             break;
   1169 
   1170          png_ptr->num_rows = (png_ptr->height +
   1171             png_pass_yinc[png_ptr->pass] - 1 -
   1172             png_pass_ystart[png_ptr->pass]) /
   1173             png_pass_yinc[png_ptr->pass];
   1174 
   1175       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
   1176    }
   1177 #endif /* PNG_READ_INTERLACING_SUPPORTED */
   1178 }
   1179 
   1180 void /* PRIVATE */
   1181 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
   1182 {
   1183    if (png_ptr->info_fn != NULL)
   1184       (*(png_ptr->info_fn))(png_ptr, info_ptr);
   1185 }
   1186 
   1187 void /* PRIVATE */
   1188 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
   1189 {
   1190    if (png_ptr->end_fn != NULL)
   1191       (*(png_ptr->end_fn))(png_ptr, info_ptr);
   1192 }
   1193 
   1194 void /* PRIVATE */
   1195 png_push_have_row(png_structp png_ptr, png_bytep row)
   1196 {
   1197    if (png_ptr->row_fn != NULL)
   1198       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
   1199          (int)png_ptr->pass);
   1200 }
   1201 
   1202 void PNGAPI
   1203 png_progressive_combine_row (png_structp png_ptr,
   1204    png_bytep old_row, png_bytep new_row)
   1205 {
   1206 #ifdef PNG_USE_LOCAL_ARRAYS
   1207    PNG_CONST int FARDATA png_pass_dsp_mask[7] =
   1208       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
   1209 #endif
   1210 
   1211    if (png_ptr == NULL)
   1212       return;
   1213 
   1214    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
   1215       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
   1216 }
   1217 
   1218 void PNGAPI
   1219 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
   1220    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
   1221    png_progressive_end_ptr end_fn)
   1222 {
   1223    if (png_ptr == NULL)
   1224       return;
   1225 
   1226    png_ptr->info_fn = info_fn;
   1227    png_ptr->row_fn = row_fn;
   1228    png_ptr->end_fn = end_fn;
   1229 
   1230    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
   1231 }
   1232 
   1233 png_voidp PNGAPI
   1234 png_get_progressive_ptr(png_structp png_ptr)
   1235 {
   1236    if (png_ptr == NULL)
   1237       return (NULL);
   1238 
   1239    return png_ptr->io_ptr;
   1240 }
   1241 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */