Back to index

lightning-sunbird  0.9+nobinonly
pngpread.c
Go to the documentation of this file.
00001 
00002 /* pngpread.c - read a png file in push mode
00003  *
00004  * libpng version 1.2.7 - September 12, 2004
00005  * For conditions of distribution and use, see copyright notice in png.h
00006  * Copyright (c) 1998-2004 Glenn Randers-Pehrson
00007  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00008  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00009  */
00010 
00011 #define PNG_INTERNAL
00012 #include "png.h"
00013 
00014 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
00015 
00016 /* push model modes */
00017 #define PNG_READ_SIG_MODE   0
00018 #define PNG_READ_CHUNK_MODE 1
00019 #define PNG_READ_IDAT_MODE  2
00020 #define PNG_SKIP_MODE       3
00021 #define PNG_READ_tEXt_MODE  4
00022 #define PNG_READ_zTXt_MODE  5
00023 #define PNG_READ_DONE_MODE  6
00024 #define PNG_READ_iTXt_MODE  7
00025 #define PNG_ERROR_MODE      8
00026 
00027 void PNGAPI
00028 png_process_data(png_structp png_ptr, png_infop info_ptr,
00029    png_bytep buffer, png_size_t buffer_size)
00030 {
00031    png_push_restore_buffer(png_ptr, buffer, buffer_size);
00032 
00033    while (png_ptr->buffer_size)
00034    {
00035       png_process_some_data(png_ptr, info_ptr);
00036    }
00037 }
00038 
00039 /* What we do with the incoming data depends on what we were previously
00040  * doing before we ran out of data...
00041  */
00042 void /* PRIVATE */
00043 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
00044 {
00045    switch (png_ptr->process_mode)
00046    {
00047       case PNG_READ_SIG_MODE:
00048       {
00049          png_push_read_sig(png_ptr, info_ptr);
00050          break;
00051       }
00052       case PNG_READ_CHUNK_MODE:
00053       {
00054          png_push_read_chunk(png_ptr, info_ptr);
00055          break;
00056       }
00057       case PNG_READ_IDAT_MODE:
00058       {
00059          png_push_read_IDAT(png_ptr);
00060          break;
00061       }
00062 #if defined(PNG_READ_tEXt_SUPPORTED)
00063       case PNG_READ_tEXt_MODE:
00064       {
00065          png_push_read_tEXt(png_ptr, info_ptr);
00066          break;
00067       }
00068 #endif
00069 #if defined(PNG_READ_zTXt_SUPPORTED)
00070       case PNG_READ_zTXt_MODE:
00071       {
00072          png_push_read_zTXt(png_ptr, info_ptr);
00073          break;
00074       }
00075 #endif
00076 #if defined(PNG_READ_iTXt_SUPPORTED)
00077       case PNG_READ_iTXt_MODE:
00078       {
00079          png_push_read_iTXt(png_ptr, info_ptr);
00080          break;
00081       }
00082 #endif
00083       case PNG_SKIP_MODE:
00084       {
00085          png_push_crc_finish(png_ptr);
00086          break;
00087       }
00088       default:
00089       {
00090          png_ptr->buffer_size = 0;
00091          break;
00092       }
00093    }
00094 }
00095 
00096 /* Read any remaining signature bytes from the stream and compare them with
00097  * the correct PNG signature.  It is possible that this routine is called
00098  * with bytes already read from the signature, either because they have been
00099  * checked by the calling application, or because of multiple calls to this
00100  * routine.
00101  */
00102 void /* PRIVATE */
00103 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
00104 {
00105    png_size_t num_checked = png_ptr->sig_bytes,
00106              num_to_check = 8 - num_checked;
00107 
00108    if (png_ptr->buffer_size < num_to_check)
00109    {
00110       num_to_check = png_ptr->buffer_size;
00111    }
00112 
00113    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
00114       num_to_check);
00115    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
00116 
00117    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
00118    {
00119       if (num_checked < 4 &&
00120           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
00121          png_error(png_ptr, "Not a PNG file");
00122       else
00123          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
00124    }
00125    else
00126    {
00127       if (png_ptr->sig_bytes >= 8)
00128       {
00129          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00130       }
00131    }
00132 }
00133 
00134 void /* PRIVATE */
00135 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
00136 {
00137 #ifdef PNG_USE_LOCAL_ARRAYS
00138       PNG_IHDR;
00139       PNG_IDAT;
00140       PNG_IEND;
00141       PNG_PLTE;
00142 #if defined(PNG_READ_bKGD_SUPPORTED)
00143       PNG_bKGD;
00144 #endif
00145 #if defined(PNG_READ_cHRM_SUPPORTED)
00146       PNG_cHRM;
00147 #endif
00148 #if defined(PNG_READ_gAMA_SUPPORTED)
00149       PNG_gAMA;
00150 #endif
00151 #if defined(PNG_READ_hIST_SUPPORTED)
00152       PNG_hIST;
00153 #endif
00154 #if defined(PNG_READ_iCCP_SUPPORTED)
00155       PNG_iCCP;
00156 #endif
00157 #if defined(PNG_READ_iTXt_SUPPORTED)
00158       PNG_iTXt;
00159 #endif
00160 #if defined(PNG_READ_oFFs_SUPPORTED)
00161       PNG_oFFs;
00162 #endif
00163 #if defined(PNG_READ_pCAL_SUPPORTED)
00164       PNG_pCAL;
00165 #endif
00166 #if defined(PNG_READ_pHYs_SUPPORTED)
00167       PNG_pHYs;
00168 #endif
00169 #if defined(PNG_READ_sBIT_SUPPORTED)
00170       PNG_sBIT;
00171 #endif
00172 #if defined(PNG_READ_sCAL_SUPPORTED)
00173       PNG_sCAL;
00174 #endif
00175 #if defined(PNG_READ_sRGB_SUPPORTED)
00176       PNG_sRGB;
00177 #endif
00178 #if defined(PNG_READ_sPLT_SUPPORTED)
00179       PNG_sPLT;
00180 #endif
00181 #if defined(PNG_READ_tEXt_SUPPORTED)
00182       PNG_tEXt;
00183 #endif
00184 #if defined(PNG_READ_tIME_SUPPORTED)
00185       PNG_tIME;
00186 #endif
00187 #if defined(PNG_READ_tRNS_SUPPORTED)
00188       PNG_tRNS;
00189 #endif
00190 #if defined(PNG_READ_zTXt_SUPPORTED)
00191       PNG_zTXt;
00192 #endif
00193 #endif /* PNG_USE_LOCAL_ARRAYS */
00194    /* First we make sure we have enough data for the 4 byte chunk name
00195     * and the 4 byte chunk length before proceeding with decoding the
00196     * chunk data.  To fully decode each of these chunks, we also make
00197     * sure we have enough data in the buffer for the 4 byte CRC at the
00198     * end of every chunk (except IDAT, which is handled separately).
00199     */
00200    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
00201    {
00202       png_byte chunk_length[4];
00203 
00204       if (png_ptr->buffer_size < 8)
00205       {
00206          png_push_save_buffer(png_ptr);
00207          return;
00208       }
00209 
00210       png_push_fill_buffer(png_ptr, chunk_length, 4);
00211       png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
00212       png_reset_crc(png_ptr);
00213       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
00214       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
00215    }
00216 
00217    if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
00218    {
00219       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00220       {
00221          png_push_save_buffer(png_ptr);
00222          return;
00223       }
00224       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
00225    }
00226    else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
00227    {
00228       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00229       {
00230          png_push_save_buffer(png_ptr);
00231          return;
00232       }
00233       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
00234 
00235       png_ptr->process_mode = PNG_READ_DONE_MODE;
00236       png_push_have_end(png_ptr, info_ptr);
00237    }
00238 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00239    else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
00240    {
00241       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00242       {
00243          png_push_save_buffer(png_ptr);
00244          return;
00245       }
00246       if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
00247          png_ptr->mode |= PNG_HAVE_IDAT;
00248       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
00249       if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
00250          png_ptr->mode |= PNG_HAVE_PLTE;
00251       else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
00252       {
00253          if (!(png_ptr->mode & PNG_HAVE_IHDR))
00254             png_error(png_ptr, "Missing IHDR before IDAT");
00255          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00256                   !(png_ptr->mode & PNG_HAVE_PLTE))
00257             png_error(png_ptr, "Missing PLTE before IDAT");
00258       }
00259    }
00260 #endif
00261    else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
00262    {
00263       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00264       {
00265          png_push_save_buffer(png_ptr);
00266          return;
00267       }
00268       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
00269    }
00270    else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
00271    {
00272       /* If we reach an IDAT chunk, this means we have read all of the
00273        * header chunks, and we can start reading the image (or if this
00274        * is called after the image has been read - we have an error).
00275        */
00276      if (!(png_ptr->mode & PNG_HAVE_IHDR))
00277        png_error(png_ptr, "Missing IHDR before IDAT");
00278      else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00279          !(png_ptr->mode & PNG_HAVE_PLTE))
00280        png_error(png_ptr, "Missing PLTE before IDAT");
00281 
00282       if (png_ptr->mode & PNG_HAVE_IDAT)
00283       {
00284          if (png_ptr->push_length == 0)
00285             return;
00286 
00287          if (png_ptr->mode & PNG_AFTER_IDAT)
00288             png_error(png_ptr, "Too many IDAT's found");
00289       }
00290 
00291       png_ptr->idat_size = png_ptr->push_length;
00292       png_ptr->mode |= PNG_HAVE_IDAT;
00293       png_ptr->process_mode = PNG_READ_IDAT_MODE;
00294       png_push_have_info(png_ptr, info_ptr);
00295       png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
00296       png_ptr->zstream.next_out = png_ptr->row_buf;
00297       return;
00298    }
00299 #if defined(PNG_READ_gAMA_SUPPORTED)
00300    else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
00301    {
00302       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00303       {
00304          png_push_save_buffer(png_ptr);
00305          return;
00306       }
00307       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
00308    }
00309 #endif
00310 #if defined(PNG_READ_sBIT_SUPPORTED)
00311    else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
00312    {
00313       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00314       {
00315          png_push_save_buffer(png_ptr);
00316          return;
00317       }
00318       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
00319    }
00320 #endif
00321 #if defined(PNG_READ_cHRM_SUPPORTED)
00322    else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
00323    {
00324       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00325       {
00326          png_push_save_buffer(png_ptr);
00327          return;
00328       }
00329       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
00330    }
00331 #endif
00332 #if defined(PNG_READ_sRGB_SUPPORTED)
00333    else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
00334    {
00335       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00336       {
00337          png_push_save_buffer(png_ptr);
00338          return;
00339       }
00340       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
00341    }
00342 #endif
00343 #if defined(PNG_READ_iCCP_SUPPORTED)
00344    else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
00345    {
00346       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00347       {
00348          png_push_save_buffer(png_ptr);
00349          return;
00350       }
00351       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
00352    }
00353 #endif
00354 #if defined(PNG_READ_sPLT_SUPPORTED)
00355    else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
00356    {
00357       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00358       {
00359          png_push_save_buffer(png_ptr);
00360          return;
00361       }
00362       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
00363    }
00364 #endif
00365 #if defined(PNG_READ_tRNS_SUPPORTED)
00366    else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
00367    {
00368       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00369       {
00370          png_push_save_buffer(png_ptr);
00371          return;
00372       }
00373       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
00374    }
00375 #endif
00376 #if defined(PNG_READ_bKGD_SUPPORTED)
00377    else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
00378    {
00379       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00380       {
00381          png_push_save_buffer(png_ptr);
00382          return;
00383       }
00384       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
00385    }
00386 #endif
00387 #if defined(PNG_READ_hIST_SUPPORTED)
00388    else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
00389    {
00390       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00391       {
00392          png_push_save_buffer(png_ptr);
00393          return;
00394       }
00395       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
00396    }
00397 #endif
00398 #if defined(PNG_READ_pHYs_SUPPORTED)
00399    else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
00400    {
00401       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00402       {
00403          png_push_save_buffer(png_ptr);
00404          return;
00405       }
00406       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
00407    }
00408 #endif
00409 #if defined(PNG_READ_oFFs_SUPPORTED)
00410    else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
00411    {
00412       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00413       {
00414          png_push_save_buffer(png_ptr);
00415          return;
00416       }
00417       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
00418    }
00419 #endif
00420 #if defined(PNG_READ_pCAL_SUPPORTED)
00421    else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
00422    {
00423       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00424       {
00425          png_push_save_buffer(png_ptr);
00426          return;
00427       }
00428       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
00429    }
00430 #endif
00431 #if defined(PNG_READ_sCAL_SUPPORTED)
00432    else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
00433    {
00434       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00435       {
00436          png_push_save_buffer(png_ptr);
00437          return;
00438       }
00439       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
00440    }
00441 #endif
00442 #if defined(PNG_READ_tIME_SUPPORTED)
00443    else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
00444    {
00445       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00446       {
00447          png_push_save_buffer(png_ptr);
00448          return;
00449       }
00450       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
00451    }
00452 #endif
00453 #if defined(PNG_READ_tEXt_SUPPORTED)
00454    else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
00455    {
00456       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00457       {
00458          png_push_save_buffer(png_ptr);
00459          return;
00460       }
00461       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
00462    }
00463 #endif
00464 #if defined(PNG_READ_zTXt_SUPPORTED)
00465    else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
00466    {
00467       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00468       {
00469          png_push_save_buffer(png_ptr);
00470          return;
00471       }
00472       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
00473    }
00474 #endif
00475 #if defined(PNG_READ_iTXt_SUPPORTED)
00476    else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
00477    {
00478       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00479       {
00480          png_push_save_buffer(png_ptr);
00481          return;
00482       }
00483       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
00484    }
00485 #endif
00486    else
00487    {
00488       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00489       {
00490          png_push_save_buffer(png_ptr);
00491          return;
00492       }
00493       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
00494    }
00495 
00496    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
00497 }
00498 
00499 void /* PRIVATE */
00500 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
00501 {
00502    png_ptr->process_mode = PNG_SKIP_MODE;
00503    png_ptr->skip_length = skip;
00504 }
00505 
00506 void /* PRIVATE */
00507 png_push_crc_finish(png_structp png_ptr)
00508 {
00509    if (png_ptr->skip_length && png_ptr->save_buffer_size)
00510    {
00511       png_size_t save_size;
00512 
00513       if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
00514          save_size = (png_size_t)png_ptr->skip_length;
00515       else
00516          save_size = png_ptr->save_buffer_size;
00517 
00518       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
00519 
00520       png_ptr->skip_length -= save_size;
00521       png_ptr->buffer_size -= save_size;
00522       png_ptr->save_buffer_size -= save_size;
00523       png_ptr->save_buffer_ptr += save_size;
00524    }
00525    if (png_ptr->skip_length && png_ptr->current_buffer_size)
00526    {
00527       png_size_t save_size;
00528 
00529       if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
00530          save_size = (png_size_t)png_ptr->skip_length;
00531       else
00532          save_size = png_ptr->current_buffer_size;
00533 
00534       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
00535 
00536       png_ptr->skip_length -= save_size;
00537       png_ptr->buffer_size -= save_size;
00538       png_ptr->current_buffer_size -= save_size;
00539       png_ptr->current_buffer_ptr += save_size;
00540    }
00541    if (!png_ptr->skip_length)
00542    {
00543       if (png_ptr->buffer_size < 4)
00544       {
00545          png_push_save_buffer(png_ptr);
00546          return;
00547       }
00548 
00549       png_crc_finish(png_ptr, 0);
00550       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00551    }
00552 }
00553 
00554 void PNGAPI
00555 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
00556 {
00557    png_bytep ptr;
00558 
00559    ptr = buffer;
00560    if (png_ptr->save_buffer_size)
00561    {
00562       png_size_t save_size;
00563 
00564       if (length < png_ptr->save_buffer_size)
00565          save_size = length;
00566       else
00567          save_size = png_ptr->save_buffer_size;
00568 
00569       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
00570       length -= save_size;
00571       ptr += save_size;
00572       png_ptr->buffer_size -= save_size;
00573       png_ptr->save_buffer_size -= save_size;
00574       png_ptr->save_buffer_ptr += save_size;
00575    }
00576    if (length && png_ptr->current_buffer_size)
00577    {
00578       png_size_t save_size;
00579 
00580       if (length < png_ptr->current_buffer_size)
00581          save_size = length;
00582       else
00583          save_size = png_ptr->current_buffer_size;
00584 
00585       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
00586       png_ptr->buffer_size -= save_size;
00587       png_ptr->current_buffer_size -= save_size;
00588       png_ptr->current_buffer_ptr += save_size;
00589    }
00590 }
00591 
00592 void /* PRIVATE */
00593 png_push_save_buffer(png_structp png_ptr)
00594 {
00595    if (png_ptr->save_buffer_size)
00596    {
00597       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
00598       {
00599          png_size_t i,istop;
00600          png_bytep sp;
00601          png_bytep dp;
00602 
00603          istop = png_ptr->save_buffer_size;
00604          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
00605             i < istop; i++, sp++, dp++)
00606          {
00607             *dp = *sp;
00608          }
00609       }
00610    }
00611    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
00612       png_ptr->save_buffer_max)
00613    {
00614       png_size_t new_max;
00615       png_bytep old_buffer;
00616 
00617       if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 
00618          (png_ptr->current_buffer_size + 256))
00619       {
00620         png_error(png_ptr, "Potential overflow of save_buffer");
00621       }
00622       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
00623       old_buffer = png_ptr->save_buffer;
00624       png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
00625          (png_uint_32)new_max);
00626       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
00627       png_free(png_ptr, old_buffer);
00628       png_ptr->save_buffer_max = new_max;
00629    }
00630    if (png_ptr->current_buffer_size)
00631    {
00632       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
00633          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
00634       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
00635       png_ptr->current_buffer_size = 0;
00636    }
00637    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
00638    png_ptr->buffer_size = 0;
00639 }
00640 
00641 void /* PRIVATE */
00642 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
00643    png_size_t buffer_length)
00644 {
00645    png_ptr->current_buffer = buffer;
00646    png_ptr->current_buffer_size = buffer_length;
00647    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
00648    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
00649 }
00650 
00651 void /* PRIVATE */
00652 png_push_read_IDAT(png_structp png_ptr)
00653 {
00654 #ifdef PNG_USE_LOCAL_ARRAYS
00655    PNG_IDAT;
00656 #endif
00657    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
00658    {
00659       png_byte chunk_length[4];
00660 
00661       if (png_ptr->buffer_size < 8)
00662       {
00663          png_push_save_buffer(png_ptr);
00664          return;
00665       }
00666 
00667       png_push_fill_buffer(png_ptr, chunk_length, 4);
00668       png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
00669       png_reset_crc(png_ptr);
00670       png_crc_read(png_ptr, png_ptr->chunk_name, 4);
00671       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
00672 
00673       if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
00674       {
00675          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00676          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
00677             png_error(png_ptr, "Not enough compressed data");
00678          return;
00679       }
00680 
00681       png_ptr->idat_size = png_ptr->push_length;
00682    }
00683    if (png_ptr->idat_size && png_ptr->save_buffer_size)
00684    {
00685       png_size_t save_size;
00686 
00687       if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
00688       {
00689          save_size = (png_size_t)png_ptr->idat_size;
00690          /* check for overflow */
00691          if((png_uint_32)save_size != png_ptr->idat_size)
00692             png_error(png_ptr, "save_size overflowed in pngpread");
00693       }
00694       else
00695          save_size = png_ptr->save_buffer_size;
00696 
00697       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
00698       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
00699          png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
00700       png_ptr->idat_size -= save_size;
00701       png_ptr->buffer_size -= save_size;
00702       png_ptr->save_buffer_size -= save_size;
00703       png_ptr->save_buffer_ptr += save_size;
00704    }
00705    if (png_ptr->idat_size && png_ptr->current_buffer_size)
00706    {
00707       png_size_t save_size;
00708 
00709       if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
00710       {
00711          save_size = (png_size_t)png_ptr->idat_size;
00712          /* check for overflow */
00713          if((png_uint_32)save_size != png_ptr->idat_size)
00714             png_error(png_ptr, "save_size overflowed in pngpread");
00715       }
00716       else
00717          save_size = png_ptr->current_buffer_size;
00718 
00719       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
00720       if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
00721         png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
00722 
00723       png_ptr->idat_size -= save_size;
00724       png_ptr->buffer_size -= save_size;
00725       png_ptr->current_buffer_size -= save_size;
00726       png_ptr->current_buffer_ptr += save_size;
00727    }
00728    if (!png_ptr->idat_size)
00729    {
00730       if (png_ptr->buffer_size < 4)
00731       {
00732          png_push_save_buffer(png_ptr);
00733          return;
00734       }
00735 
00736       png_crc_finish(png_ptr, 0);
00737       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
00738       png_ptr->mode |= PNG_AFTER_IDAT;
00739    }
00740 }
00741 
00742 void /* PRIVATE */
00743 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
00744    png_size_t buffer_length)
00745 {
00746    int ret;
00747 
00748    if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
00749       png_error(png_ptr, "Extra compression data");
00750 
00751    png_ptr->zstream.next_in = buffer;
00752    png_ptr->zstream.avail_in = (uInt)buffer_length;
00753    for(;;)
00754    {
00755       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
00756       if (ret != Z_OK)
00757       {
00758          if (ret == Z_STREAM_END)
00759          {
00760             if (png_ptr->zstream.avail_in)
00761                png_error(png_ptr, "Extra compressed data");
00762             if (!(png_ptr->zstream.avail_out))
00763             {
00764                png_push_process_row(png_ptr);
00765             }
00766 
00767             png_ptr->mode |= PNG_AFTER_IDAT;
00768             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00769             break;
00770          }
00771          else if (ret == Z_BUF_ERROR)
00772             break;
00773          else
00774             png_error(png_ptr, "Decompression Error");
00775       }
00776       if (!(png_ptr->zstream.avail_out))
00777       {
00778          if ((
00779 #if defined(PNG_READ_INTERLACING_SUPPORTED)
00780              png_ptr->interlaced && png_ptr->pass > 6) ||
00781              (!png_ptr->interlaced &&
00782 #endif
00783              png_ptr->row_number == png_ptr->num_rows))
00784          {
00785            if (png_ptr->zstream.avail_in)
00786              png_warning(png_ptr, "Too much data in IDAT chunks");
00787            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00788            break;
00789          }
00790          png_push_process_row(png_ptr);
00791          png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
00792          png_ptr->zstream.next_out = png_ptr->row_buf;
00793       }
00794       else
00795          break;
00796    }
00797 }
00798 
00799 void /* PRIVATE */
00800 png_push_process_row(png_structp png_ptr)
00801 {
00802    png_ptr->row_info.color_type = png_ptr->color_type;
00803    png_ptr->row_info.width = png_ptr->iwidth;
00804    png_ptr->row_info.channels = png_ptr->channels;
00805    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
00806    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
00807 
00808    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
00809        png_ptr->row_info.width);
00810 
00811    png_read_filter_row(png_ptr, &(png_ptr->row_info),
00812       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
00813       (int)(png_ptr->row_buf[0]));
00814 
00815    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
00816       png_ptr->rowbytes + 1);
00817 
00818    if (png_ptr->transformations)
00819       png_do_read_transformations(png_ptr);
00820 
00821 #if defined(PNG_READ_INTERLACING_SUPPORTED)
00822    /* blow up interlaced rows to full size */
00823    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
00824    {
00825       if (png_ptr->pass < 6)
00826 /*       old interface (pre-1.0.9):
00827          png_do_read_interlace(&(png_ptr->row_info),
00828             png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
00829  */
00830          png_do_read_interlace(png_ptr);
00831 
00832     switch (png_ptr->pass)
00833     {
00834          case 0:
00835          {
00836             int i;
00837             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
00838             {
00839                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00840                png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
00841             }
00842             if (png_ptr->pass == 2) /* pass 1 might be empty */
00843             {
00844                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
00845                {
00846                   png_push_have_row(png_ptr, png_bytep_NULL);
00847                   png_read_push_finish_row(png_ptr);
00848                }
00849             }
00850             if (png_ptr->pass == 4 && png_ptr->height <= 4)
00851             {
00852                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
00853                {
00854                   png_push_have_row(png_ptr, png_bytep_NULL);
00855                   png_read_push_finish_row(png_ptr);
00856                }
00857             }
00858             if (png_ptr->pass == 6 && png_ptr->height <= 4)
00859             {
00860                 png_push_have_row(png_ptr, png_bytep_NULL);
00861                 png_read_push_finish_row(png_ptr);
00862             }
00863             break;
00864          }
00865          case 1:
00866          {
00867             int i;
00868             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
00869             {
00870                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00871                png_read_push_finish_row(png_ptr);
00872             }
00873             if (png_ptr->pass == 2) /* skip top 4 generated rows */
00874             {
00875                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
00876                {
00877                   png_push_have_row(png_ptr, png_bytep_NULL);
00878                   png_read_push_finish_row(png_ptr);
00879                }
00880             }
00881             break;
00882          }
00883          case 2:
00884          {
00885             int i;
00886             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
00887             {
00888                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00889                png_read_push_finish_row(png_ptr);
00890             }
00891             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
00892             {
00893                png_push_have_row(png_ptr, png_bytep_NULL);
00894                png_read_push_finish_row(png_ptr);
00895             }
00896             if (png_ptr->pass == 4) /* pass 3 might be empty */
00897             {
00898                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
00899                {
00900                   png_push_have_row(png_ptr, png_bytep_NULL);
00901                   png_read_push_finish_row(png_ptr);
00902                }
00903             }
00904             break;
00905          }
00906          case 3:
00907          {
00908             int i;
00909             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
00910             {
00911                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00912                png_read_push_finish_row(png_ptr);
00913             }
00914             if (png_ptr->pass == 4) /* skip top two generated rows */
00915             {
00916                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
00917                {
00918                   png_push_have_row(png_ptr, png_bytep_NULL);
00919                   png_read_push_finish_row(png_ptr);
00920                }
00921             }
00922             break;
00923          }
00924          case 4:
00925          {
00926             int i;
00927             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
00928             {
00929                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00930                png_read_push_finish_row(png_ptr);
00931             }
00932             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
00933             {
00934                png_push_have_row(png_ptr, png_bytep_NULL);
00935                png_read_push_finish_row(png_ptr);
00936             }
00937             if (png_ptr->pass == 6) /* pass 5 might be empty */
00938             {
00939                png_push_have_row(png_ptr, png_bytep_NULL);
00940                png_read_push_finish_row(png_ptr);
00941             }
00942             break;
00943          }
00944          case 5:
00945          {
00946             int i;
00947             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
00948             {
00949                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00950                png_read_push_finish_row(png_ptr);
00951             }
00952             if (png_ptr->pass == 6) /* skip top generated row */
00953             {
00954                png_push_have_row(png_ptr, png_bytep_NULL);
00955                png_read_push_finish_row(png_ptr);
00956             }
00957             break;
00958          }
00959          case 6:
00960          {
00961             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00962             png_read_push_finish_row(png_ptr);
00963             if (png_ptr->pass != 6)
00964                break;
00965             png_push_have_row(png_ptr, png_bytep_NULL);
00966             png_read_push_finish_row(png_ptr);
00967          }
00968       }
00969    }
00970    else
00971 #endif
00972    {
00973       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
00974       png_read_push_finish_row(png_ptr);
00975    }
00976 }
00977 
00978 void /* PRIVATE */
00979 png_read_push_finish_row(png_structp png_ptr)
00980 {
00981 #ifdef PNG_USE_LOCAL_ARRAYS
00982    /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
00983 
00984    /* start of interlace block */
00985    const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
00986 
00987    /* offset to next interlace block */
00988    const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
00989 
00990    /* start of interlace block in the y direction */
00991    const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
00992 
00993    /* offset to next interlace block in the y direction */
00994    const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
00995 
00996    /* Width of interlace block.  This is not currently used - if you need
00997     * it, uncomment it here and in png.h
00998    const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
00999    */
01000 
01001    /* Height of interlace block.  This is not currently used - if you need
01002     * it, uncomment it here and in png.h
01003    const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
01004    */
01005 #endif
01006 
01007    png_ptr->row_number++;
01008    if (png_ptr->row_number < png_ptr->num_rows)
01009       return;
01010 
01011    if (png_ptr->interlaced)
01012    {
01013       png_ptr->row_number = 0;
01014       png_memset_check(png_ptr, png_ptr->prev_row, 0,
01015          png_ptr->rowbytes + 1);
01016       do
01017       {
01018          png_ptr->pass++;
01019          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
01020              (png_ptr->pass == 3 && png_ptr->width < 3) ||
01021              (png_ptr->pass == 5 && png_ptr->width < 2))
01022            png_ptr->pass++;
01023 
01024          if (png_ptr->pass > 7)
01025             png_ptr->pass--;
01026          if (png_ptr->pass >= 7)
01027             break;
01028 
01029          png_ptr->iwidth = (png_ptr->width +
01030             png_pass_inc[png_ptr->pass] - 1 -
01031             png_pass_start[png_ptr->pass]) /
01032             png_pass_inc[png_ptr->pass];
01033 
01034          png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
01035             png_ptr->iwidth) + 1;
01036 
01037          if (png_ptr->transformations & PNG_INTERLACE)
01038             break;
01039 
01040          png_ptr->num_rows = (png_ptr->height +
01041             png_pass_yinc[png_ptr->pass] - 1 -
01042             png_pass_ystart[png_ptr->pass]) /
01043             png_pass_yinc[png_ptr->pass];
01044 
01045       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
01046    }
01047 }
01048 
01049 #if defined(PNG_READ_tEXt_SUPPORTED)
01050 void /* PRIVATE */
01051 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01052    length)
01053 {
01054    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01055       {
01056          png_error(png_ptr, "Out of place tEXt");
01057          /* to quiet some compiler warnings */
01058          if(info_ptr == NULL) return;
01059       }
01060 
01061 #ifdef PNG_MAX_MALLOC_64K
01062    png_ptr->skip_length = 0;  /* This may not be necessary */
01063 
01064    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
01065    {
01066       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
01067       png_ptr->skip_length = length - (png_uint_32)65535L;
01068       length = (png_uint_32)65535L;
01069    }
01070 #endif
01071 
01072    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
01073          (png_uint_32)(length+1));
01074    png_ptr->current_text[length] = '\0';
01075    png_ptr->current_text_ptr = png_ptr->current_text;
01076    png_ptr->current_text_size = (png_size_t)length;
01077    png_ptr->current_text_left = (png_size_t)length;
01078    png_ptr->process_mode = PNG_READ_tEXt_MODE;
01079 }
01080 
01081 void /* PRIVATE */
01082 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
01083 {
01084    if (png_ptr->buffer_size && png_ptr->current_text_left)
01085    {
01086       png_size_t text_size;
01087 
01088       if (png_ptr->buffer_size < png_ptr->current_text_left)
01089          text_size = png_ptr->buffer_size;
01090       else
01091          text_size = png_ptr->current_text_left;
01092       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01093       png_ptr->current_text_left -= text_size;
01094       png_ptr->current_text_ptr += text_size;
01095    }
01096    if (!(png_ptr->current_text_left))
01097    {
01098       png_textp text_ptr;
01099       png_charp text;
01100       png_charp key;
01101       int ret;
01102 
01103       if (png_ptr->buffer_size < 4)
01104       {
01105          png_push_save_buffer(png_ptr);
01106          return;
01107       }
01108 
01109       png_push_crc_finish(png_ptr);
01110 
01111 #if defined(PNG_MAX_MALLOC_64K)
01112       if (png_ptr->skip_length)
01113          return;
01114 #endif
01115 
01116       key = png_ptr->current_text;
01117 
01118       for (text = key; *text; text++)
01119          /* empty loop */ ;
01120 
01121       if (text != key + png_ptr->current_text_size)
01122          text++;
01123 
01124       text_ptr = (png_textp)png_malloc(png_ptr,
01125          (png_uint_32)png_sizeof(png_text));
01126       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
01127       text_ptr->key = key;
01128 #ifdef PNG_iTXt_SUPPORTED
01129       text_ptr->lang = NULL;
01130       text_ptr->lang_key = NULL;
01131 #endif
01132       text_ptr->text = text;
01133 
01134       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01135 
01136       png_free(png_ptr, key);
01137       png_free(png_ptr, text_ptr);
01138       png_ptr->current_text = NULL;
01139 
01140       if (ret)
01141         png_warning(png_ptr, "Insufficient memory to store text chunk.");
01142    }
01143 }
01144 #endif
01145 
01146 #if defined(PNG_READ_zTXt_SUPPORTED)
01147 void /* PRIVATE */
01148 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01149    length)
01150 {
01151    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01152       {
01153          png_error(png_ptr, "Out of place zTXt");
01154          /* to quiet some compiler warnings */
01155          if(info_ptr == NULL) return;
01156       }
01157 
01158 #ifdef PNG_MAX_MALLOC_64K
01159    /* We can't handle zTXt chunks > 64K, since we don't have enough space
01160     * to be able to store the uncompressed data.  Actually, the threshold
01161     * is probably around 32K, but it isn't as definite as 64K is.
01162     */
01163    if (length > (png_uint_32)65535L)
01164    {
01165       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
01166       png_push_crc_skip(png_ptr, length);
01167       return;
01168    }
01169 #endif
01170 
01171    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
01172        (png_uint_32)(length+1));
01173    png_ptr->current_text[length] = '\0';
01174    png_ptr->current_text_ptr = png_ptr->current_text;
01175    png_ptr->current_text_size = (png_size_t)length;
01176    png_ptr->current_text_left = (png_size_t)length;
01177    png_ptr->process_mode = PNG_READ_zTXt_MODE;
01178 }
01179 
01180 void /* PRIVATE */
01181 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
01182 {
01183    if (png_ptr->buffer_size && png_ptr->current_text_left)
01184    {
01185       png_size_t text_size;
01186 
01187       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
01188          text_size = png_ptr->buffer_size;
01189       else
01190          text_size = png_ptr->current_text_left;
01191       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01192       png_ptr->current_text_left -= text_size;
01193       png_ptr->current_text_ptr += text_size;
01194    }
01195    if (!(png_ptr->current_text_left))
01196    {
01197       png_textp text_ptr;
01198       png_charp text;
01199       png_charp key;
01200       int ret;
01201       png_size_t text_size, key_size;
01202 
01203       if (png_ptr->buffer_size < 4)
01204       {
01205          png_push_save_buffer(png_ptr);
01206          return;
01207       }
01208 
01209       png_push_crc_finish(png_ptr);
01210 
01211       key = png_ptr->current_text;
01212 
01213       for (text = key; *text; text++)
01214          /* empty loop */ ;
01215 
01216       /* zTXt can't have zero text */
01217       if (text == key + png_ptr->current_text_size)
01218       {
01219          png_ptr->current_text = NULL;
01220          png_free(png_ptr, key);
01221          return;
01222       }
01223 
01224       text++;
01225 
01226       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
01227       {
01228          png_ptr->current_text = NULL;
01229          png_free(png_ptr, key);
01230          return;
01231       }
01232 
01233       text++;
01234 
01235       png_ptr->zstream.next_in = (png_bytep )text;
01236       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
01237          (text - key));
01238       png_ptr->zstream.next_out = png_ptr->zbuf;
01239       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
01240 
01241       key_size = text - key;
01242       text_size = 0;
01243       text = NULL;
01244       ret = Z_STREAM_END;
01245 
01246       while (png_ptr->zstream.avail_in)
01247       {
01248          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
01249          if (ret != Z_OK && ret != Z_STREAM_END)
01250          {
01251             inflateReset(&png_ptr->zstream);
01252             png_ptr->zstream.avail_in = 0;
01253             png_ptr->current_text = NULL;
01254             png_free(png_ptr, key);
01255             png_free(png_ptr, text);
01256             return;
01257          }
01258          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
01259          {
01260             if (text == NULL)
01261             {
01262                text = (png_charp)png_malloc(png_ptr,
01263                   (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
01264                      + key_size + 1));
01265                png_memcpy(text + key_size, png_ptr->zbuf,
01266                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
01267                png_memcpy(text, key, key_size);
01268                text_size = key_size + png_ptr->zbuf_size -
01269                   png_ptr->zstream.avail_out;
01270                *(text + text_size) = '\0';
01271             }
01272             else
01273             {
01274                png_charp tmp;
01275 
01276                tmp = text;
01277                text = (png_charp)png_malloc(png_ptr, text_size +
01278                   (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
01279                    + 1));
01280                png_memcpy(text, tmp, text_size);
01281                png_free(png_ptr, tmp);
01282                png_memcpy(text + text_size, png_ptr->zbuf,
01283                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
01284                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
01285                *(text + text_size) = '\0';
01286             }
01287             if (ret != Z_STREAM_END)
01288             {
01289                png_ptr->zstream.next_out = png_ptr->zbuf;
01290                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
01291             }
01292          }
01293          else
01294          {
01295             break;
01296          }
01297 
01298          if (ret == Z_STREAM_END)
01299             break;
01300       }
01301 
01302       inflateReset(&png_ptr->zstream);
01303       png_ptr->zstream.avail_in = 0;
01304 
01305       if (ret != Z_STREAM_END)
01306       {
01307          png_ptr->current_text = NULL;
01308          png_free(png_ptr, key);
01309          png_free(png_ptr, text);
01310          return;
01311       }
01312 
01313       png_ptr->current_text = NULL;
01314       png_free(png_ptr, key);
01315       key = text;
01316       text += key_size;
01317 
01318       text_ptr = (png_textp)png_malloc(png_ptr,
01319           (png_uint_32)png_sizeof(png_text));
01320       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
01321       text_ptr->key = key;
01322 #ifdef PNG_iTXt_SUPPORTED
01323       text_ptr->lang = NULL;
01324       text_ptr->lang_key = NULL;
01325 #endif
01326       text_ptr->text = text;
01327 
01328       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01329 
01330       png_free(png_ptr, key);
01331       png_free(png_ptr, text_ptr);
01332 
01333       if (ret)
01334         png_warning(png_ptr, "Insufficient memory to store text chunk.");
01335    }
01336 }
01337 #endif
01338 
01339 #if defined(PNG_READ_iTXt_SUPPORTED)
01340 void /* PRIVATE */
01341 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01342    length)
01343 {
01344    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01345       {
01346          png_error(png_ptr, "Out of place iTXt");
01347          /* to quiet some compiler warnings */
01348          if(info_ptr == NULL) return;
01349       }
01350 
01351 #ifdef PNG_MAX_MALLOC_64K
01352    png_ptr->skip_length = 0;  /* This may not be necessary */
01353 
01354    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
01355    {
01356       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
01357       png_ptr->skip_length = length - (png_uint_32)65535L;
01358       length = (png_uint_32)65535L;
01359    }
01360 #endif
01361 
01362    png_ptr->current_text = (png_charp)png_malloc(png_ptr,
01363          (png_uint_32)(length+1));
01364    png_ptr->current_text[length] = '\0';
01365    png_ptr->current_text_ptr = png_ptr->current_text;
01366    png_ptr->current_text_size = (png_size_t)length;
01367    png_ptr->current_text_left = (png_size_t)length;
01368    png_ptr->process_mode = PNG_READ_iTXt_MODE;
01369 }
01370 
01371 void /* PRIVATE */
01372 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
01373 {
01374 
01375    if (png_ptr->buffer_size && png_ptr->current_text_left)
01376    {
01377       png_size_t text_size;
01378 
01379       if (png_ptr->buffer_size < png_ptr->current_text_left)
01380          text_size = png_ptr->buffer_size;
01381       else
01382          text_size = png_ptr->current_text_left;
01383       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01384       png_ptr->current_text_left -= text_size;
01385       png_ptr->current_text_ptr += text_size;
01386    }
01387    if (!(png_ptr->current_text_left))
01388    {
01389       png_textp text_ptr;
01390       png_charp key;
01391       int comp_flag;
01392       png_charp lang;
01393       png_charp lang_key;
01394       png_charp text;
01395       int ret;
01396 
01397       if (png_ptr->buffer_size < 4)
01398       {
01399          png_push_save_buffer(png_ptr);
01400          return;
01401       }
01402 
01403       png_push_crc_finish(png_ptr);
01404 
01405 #if defined(PNG_MAX_MALLOC_64K)
01406       if (png_ptr->skip_length)
01407          return;
01408 #endif
01409 
01410       key = png_ptr->current_text;
01411 
01412       for (lang = key; *lang; lang++)
01413          /* empty loop */ ;
01414 
01415       if (lang != key + png_ptr->current_text_size)
01416          lang++;
01417 
01418       comp_flag = *lang++;
01419       lang++;     /* skip comp_type, always zero */
01420 
01421       for (lang_key = lang; *lang_key; lang_key++)
01422          /* empty loop */ ;
01423       lang_key++;        /* skip NUL separator */
01424 
01425       for (text = lang_key; *text; text++)
01426          /* empty loop */ ;
01427 
01428       if (text != key + png_ptr->current_text_size)
01429          text++;
01430 
01431       text_ptr = (png_textp)png_malloc(png_ptr,
01432          (png_uint_32)png_sizeof(png_text));
01433       text_ptr->compression = comp_flag + 2;
01434       text_ptr->key = key;
01435       text_ptr->lang = lang;
01436       text_ptr->lang_key = lang_key;
01437       text_ptr->text = text;
01438       text_ptr->text_length = 0;
01439       text_ptr->itxt_length = png_strlen(text);
01440 
01441       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01442 
01443       png_ptr->current_text = NULL;
01444 
01445       png_free(png_ptr, text_ptr);
01446       if (ret)
01447         png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
01448    }
01449 }
01450 #endif
01451 
01452 /* This function is called when we haven't found a handler for this
01453  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
01454  * name or a critical chunk), the chunk is (currently) silently ignored.
01455  */
01456 void /* PRIVATE */
01457 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
01458    length)
01459 {
01460    png_uint_32 skip=0;
01461    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
01462 
01463    if (!(png_ptr->chunk_name[0] & 0x20))
01464    {
01465 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
01466       if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
01467            PNG_HANDLE_CHUNK_ALWAYS
01468 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
01469            && png_ptr->read_user_chunk_fn == NULL
01470 #endif
01471          )
01472 #endif
01473          png_chunk_error(png_ptr, "unknown critical chunk");
01474 
01475       /* to quiet compiler warnings about unused info_ptr */
01476       if (info_ptr == NULL)
01477          return;
01478    }
01479 
01480 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
01481    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
01482    {
01483        png_unknown_chunk chunk;
01484 
01485 #ifdef PNG_MAX_MALLOC_64K
01486        if (length > (png_uint_32)65535L)
01487        {
01488            png_warning(png_ptr, "unknown chunk too large to fit in memory");
01489            skip = length - (png_uint_32)65535L;
01490            length = (png_uint_32)65535L;
01491        }
01492 #endif
01493 
01494        png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
01495        chunk.data = (png_bytep)png_malloc(png_ptr, length);
01496        png_crc_read(png_ptr, chunk.data, length);
01497        chunk.size = length;
01498 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
01499        if(png_ptr->read_user_chunk_fn != NULL)
01500        {
01501           /* callback to user unknown chunk handler */
01502           if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
01503           {
01504              if (!(png_ptr->chunk_name[0] & 0x20))
01505                 if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
01506                      PNG_HANDLE_CHUNK_ALWAYS)
01507                    png_chunk_error(png_ptr, "unknown critical chunk");
01508           }
01509              png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
01510        }
01511        else
01512 #endif
01513           png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
01514        png_free(png_ptr, chunk.data);
01515    }
01516    else
01517 #endif
01518       skip=length;
01519    png_push_crc_skip(png_ptr, skip);
01520 }
01521 
01522 void /* PRIVATE */
01523 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
01524 {
01525    if (png_ptr->info_fn != NULL)
01526       (*(png_ptr->info_fn))(png_ptr, info_ptr);
01527 }
01528 
01529 void /* PRIVATE */
01530 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
01531 {
01532    if (png_ptr->end_fn != NULL)
01533       (*(png_ptr->end_fn))(png_ptr, info_ptr);
01534 }
01535 
01536 void /* PRIVATE */
01537 png_push_have_row(png_structp png_ptr, png_bytep row)
01538 {
01539    if (png_ptr->row_fn != NULL)
01540       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
01541          (int)png_ptr->pass);
01542 }
01543 
01544 void PNGAPI
01545 png_progressive_combine_row (png_structp png_ptr,
01546    png_bytep old_row, png_bytep new_row)
01547 {
01548 #ifdef PNG_USE_LOCAL_ARRAYS
01549    const int FARDATA png_pass_dsp_mask[7] =
01550       {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
01551 #endif
01552    if (new_row != NULL)    /* new_row must == png_ptr->row_buf here. */
01553       png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
01554 }
01555 
01556 void PNGAPI
01557 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
01558    png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
01559    png_progressive_end_ptr end_fn)
01560 {
01561    png_ptr->info_fn = info_fn;
01562    png_ptr->row_fn = row_fn;
01563    png_ptr->end_fn = end_fn;
01564 
01565    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
01566 }
01567 
01568 png_voidp PNGAPI
01569 png_get_progressive_ptr(png_structp png_ptr)
01570 {
01571    return png_ptr->io_ptr;
01572 }
01573 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */