pngpread.c

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

Generated on Tue Jul 5 14:13:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1