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


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Apr 11 2019 03:30:18