ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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.5.9 [February 18, 2012]
00005  * Copyright (c) 1998-2011 Glenn Randers-Pehrson
00006  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
00007  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
00008  *
00009  * This code is released under the libpng license.
00010  * For conditions of distribution and use, see the disclaimer
00011  * and license in png.h
00012  */
00013 
00014 #include "pngpriv.h"
00015 
00016 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
00017 
00018 /* Push model modes */
00019 #define PNG_READ_SIG_MODE   0
00020 #define PNG_READ_CHUNK_MODE 1
00021 #define PNG_READ_IDAT_MODE  2
00022 #define PNG_SKIP_MODE       3
00023 #define PNG_READ_tEXt_MODE  4
00024 #define PNG_READ_zTXt_MODE  5
00025 #define PNG_READ_DONE_MODE  6
00026 #define PNG_READ_iTXt_MODE  7
00027 #define PNG_ERROR_MODE      8
00028 
00029 void PNGAPI
00030 png_process_data(png_structp png_ptr, png_infop info_ptr,
00031     png_bytep buffer, png_size_t buffer_size)
00032 {
00033    if (png_ptr == NULL || info_ptr == NULL)
00034       return;
00035 
00036    png_push_restore_buffer(png_ptr, buffer, buffer_size);
00037 
00038    while (png_ptr->buffer_size)
00039    {
00040       png_process_some_data(png_ptr, info_ptr);
00041    }
00042 }
00043 
00044 png_size_t PNGAPI
00045 png_process_data_pause(png_structp png_ptr, int save)
00046 {
00047    if (png_ptr != NULL)
00048    {
00049       /* It's easiest for the caller if we do the save, then the caller doesn't
00050        * have to supply the same data again:
00051        */
00052       if (save)
00053          png_push_save_buffer(png_ptr);
00054       else
00055       {
00056          /* This includes any pending saved bytes: */
00057          png_size_t remaining = png_ptr->buffer_size;
00058          png_ptr->buffer_size = 0;
00059 
00060          /* So subtract the saved buffer size, unless all the data
00061           * is actually 'saved', in which case we just return 0
00062           */
00063          if (png_ptr->save_buffer_size < remaining)
00064             return remaining - png_ptr->save_buffer_size;
00065       }
00066    }
00067 
00068    return 0;
00069 }
00070 
00071 png_uint_32 PNGAPI
00072 png_process_data_skip(png_structp png_ptr)
00073 {
00074    png_uint_32 remaining = 0;
00075 
00076    if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
00077       png_ptr->skip_length > 0)
00078    {
00079       /* At the end of png_process_data the buffer size must be 0 (see the loop
00080        * above) so we can detect a broken call here:
00081        */
00082       if (png_ptr->buffer_size != 0)
00083          png_error(png_ptr,
00084             "png_process_data_skip called inside png_process_data");
00085 
00086       /* If is impossible for there to be a saved buffer at this point -
00087        * otherwise we could not be in SKIP mode.  This will also happen if
00088        * png_process_skip is called inside png_process_data (but only very
00089        * rarely.)
00090        */
00091       if (png_ptr->save_buffer_size != 0)
00092          png_error(png_ptr, "png_process_data_skip called with saved data");
00093 
00094       remaining = png_ptr->skip_length;
00095       png_ptr->skip_length = 0;
00096       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00097    }
00098 
00099    return remaining;
00100 }
00101 
00102 /* What we do with the incoming data depends on what we were previously
00103  * doing before we ran out of data...
00104  */
00105 void /* PRIVATE */
00106 png_process_some_data(png_structp png_ptr, png_infop info_ptr)
00107 {
00108    if (png_ptr == NULL)
00109       return;
00110 
00111    switch (png_ptr->process_mode)
00112    {
00113       case PNG_READ_SIG_MODE:
00114       {
00115          png_push_read_sig(png_ptr, info_ptr);
00116          break;
00117       }
00118 
00119       case PNG_READ_CHUNK_MODE:
00120       {
00121          png_push_read_chunk(png_ptr, info_ptr);
00122          break;
00123       }
00124 
00125       case PNG_READ_IDAT_MODE:
00126       {
00127          png_push_read_IDAT(png_ptr);
00128          break;
00129       }
00130 
00131 #ifdef PNG_READ_tEXt_SUPPORTED
00132       case PNG_READ_tEXt_MODE:
00133       {
00134          png_push_read_tEXt(png_ptr, info_ptr);
00135          break;
00136       }
00137 
00138 #endif
00139 #ifdef PNG_READ_zTXt_SUPPORTED
00140       case PNG_READ_zTXt_MODE:
00141       {
00142          png_push_read_zTXt(png_ptr, info_ptr);
00143          break;
00144       }
00145 
00146 #endif
00147 #ifdef PNG_READ_iTXt_SUPPORTED
00148       case PNG_READ_iTXt_MODE:
00149       {
00150          png_push_read_iTXt(png_ptr, info_ptr);
00151          break;
00152       }
00153 
00154 #endif
00155       case PNG_SKIP_MODE:
00156       {
00157          png_push_crc_finish(png_ptr);
00158          break;
00159       }
00160 
00161       default:
00162       {
00163          png_ptr->buffer_size = 0;
00164          break;
00165       }
00166    }
00167 }
00168 
00169 /* Read any remaining signature bytes from the stream and compare them with
00170  * the correct PNG signature.  It is possible that this routine is called
00171  * with bytes already read from the signature, either because they have been
00172  * checked by the calling application, or because of multiple calls to this
00173  * routine.
00174  */
00175 void /* PRIVATE */
00176 png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
00177 {
00178    png_size_t num_checked = png_ptr->sig_bytes,
00179              num_to_check = 8 - num_checked;
00180 
00181    if (png_ptr->buffer_size < num_to_check)
00182    {
00183       num_to_check = png_ptr->buffer_size;
00184    }
00185 
00186    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
00187        num_to_check);
00188    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
00189 
00190    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
00191    {
00192       if (num_checked < 4 &&
00193           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
00194          png_error(png_ptr, "Not a PNG file");
00195 
00196       else
00197          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
00198    }
00199    else
00200    {
00201       if (png_ptr->sig_bytes >= 8)
00202       {
00203          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00204       }
00205    }
00206 }
00207 
00208 void /* PRIVATE */
00209 png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
00210 {
00211    png_uint_32 chunk_name;
00212 
00213    /* First we make sure we have enough data for the 4 byte chunk name
00214     * and the 4 byte chunk length before proceeding with decoding the
00215     * chunk data.  To fully decode each of these chunks, we also make
00216     * sure we have enough data in the buffer for the 4 byte CRC at the
00217     * end of every chunk (except IDAT, which is handled separately).
00218     */
00219    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
00220    {
00221       png_byte chunk_length[4];
00222       png_byte chunk_tag[4];
00223 
00224       if (png_ptr->buffer_size < 8)
00225       {
00226          png_push_save_buffer(png_ptr);
00227          return;
00228       }
00229 
00230       png_push_fill_buffer(png_ptr, chunk_length, 4);
00231       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
00232       png_reset_crc(png_ptr);
00233       png_crc_read(png_ptr, chunk_tag, 4);
00234       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
00235       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
00236       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
00237    }
00238 
00239    chunk_name = png_ptr->chunk_name;
00240 
00241    if (chunk_name == png_IDAT)
00242    {
00243       /* This is here above the if/else case statement below because if the
00244        * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
00245        * completely skipped.
00246        *
00247        * TODO: there must be a better way of doing this.
00248        */
00249       if (png_ptr->mode & PNG_AFTER_IDAT)
00250          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
00251    }
00252 
00253    if (chunk_name == png_IHDR)
00254    {
00255       if (png_ptr->push_length != 13)
00256          png_error(png_ptr, "Invalid IHDR length");
00257 
00258       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00259       {
00260          png_push_save_buffer(png_ptr);
00261          return;
00262       }
00263 
00264       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
00265    }
00266 
00267    else if (chunk_name == png_IEND)
00268    {
00269       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00270       {
00271          png_push_save_buffer(png_ptr);
00272          return;
00273       }
00274 
00275       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
00276 
00277       png_ptr->process_mode = PNG_READ_DONE_MODE;
00278       png_push_have_end(png_ptr, info_ptr);
00279    }
00280 
00281 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00282    else if (png_chunk_unknown_handling(png_ptr, chunk_name))
00283    {
00284       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00285       {
00286          png_push_save_buffer(png_ptr);
00287          return;
00288       }
00289 
00290       if (chunk_name == png_IDAT)
00291          png_ptr->mode |= PNG_HAVE_IDAT;
00292 
00293       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
00294 
00295       if (chunk_name == png_PLTE)
00296          png_ptr->mode |= PNG_HAVE_PLTE;
00297 
00298       else if (chunk_name == png_IDAT)
00299       {
00300          if (!(png_ptr->mode & PNG_HAVE_IHDR))
00301             png_error(png_ptr, "Missing IHDR before IDAT");
00302 
00303          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00304              !(png_ptr->mode & PNG_HAVE_PLTE))
00305             png_error(png_ptr, "Missing PLTE before IDAT");
00306       }
00307    }
00308 
00309 #endif
00310    else if (chunk_name == png_PLTE)
00311    {
00312       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00313       {
00314          png_push_save_buffer(png_ptr);
00315          return;
00316       }
00317       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
00318    }
00319 
00320    else if (chunk_name == png_IDAT)
00321    {
00322       /* If we reach an IDAT chunk, this means we have read all of the
00323        * header chunks, and we can start reading the image (or if this
00324        * is called after the image has been read - we have an error).
00325        */
00326 
00327       if (!(png_ptr->mode & PNG_HAVE_IHDR))
00328          png_error(png_ptr, "Missing IHDR before IDAT");
00329 
00330       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00331           !(png_ptr->mode & PNG_HAVE_PLTE))
00332          png_error(png_ptr, "Missing PLTE before IDAT");
00333 
00334       if (png_ptr->mode & PNG_HAVE_IDAT)
00335       {
00336          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
00337             if (png_ptr->push_length == 0)
00338                return;
00339 
00340          if (png_ptr->mode & PNG_AFTER_IDAT)
00341             png_benign_error(png_ptr, "Too many IDATs found");
00342       }
00343 
00344       png_ptr->idat_size = png_ptr->push_length;
00345       png_ptr->mode |= PNG_HAVE_IDAT;
00346       png_ptr->process_mode = PNG_READ_IDAT_MODE;
00347       png_push_have_info(png_ptr, info_ptr);
00348       png_ptr->zstream.avail_out =
00349           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
00350           png_ptr->iwidth) + 1;
00351       png_ptr->zstream.next_out = png_ptr->row_buf;
00352       return;
00353    }
00354 
00355 #ifdef PNG_READ_gAMA_SUPPORTED
00356    else if (png_ptr->chunk_name == png_gAMA)
00357    {
00358       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00359       {
00360          png_push_save_buffer(png_ptr);
00361          return;
00362       }
00363 
00364       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
00365    }
00366 
00367 #endif
00368 #ifdef PNG_READ_sBIT_SUPPORTED
00369    else if (png_ptr->chunk_name == png_sBIT)
00370    {
00371       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00372       {
00373          png_push_save_buffer(png_ptr);
00374          return;
00375       }
00376 
00377       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
00378    }
00379 
00380 #endif
00381 #ifdef PNG_READ_cHRM_SUPPORTED
00382    else if (png_ptr->chunk_name == png_cHRM)
00383    {
00384       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00385       {
00386          png_push_save_buffer(png_ptr);
00387          return;
00388       }
00389 
00390       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
00391    }
00392 
00393 #endif
00394 #ifdef PNG_READ_sRGB_SUPPORTED
00395    else if (chunk_name == png_sRGB)
00396    {
00397       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00398       {
00399          png_push_save_buffer(png_ptr);
00400          return;
00401       }
00402 
00403       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
00404    }
00405 
00406 #endif
00407 #ifdef PNG_READ_iCCP_SUPPORTED
00408    else if (png_ptr->chunk_name == png_iCCP)
00409    {
00410       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00411       {
00412          png_push_save_buffer(png_ptr);
00413          return;
00414       }
00415 
00416       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
00417    }
00418 
00419 #endif
00420 #ifdef PNG_READ_sPLT_SUPPORTED
00421    else if (chunk_name == png_sPLT)
00422    {
00423       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00424       {
00425          png_push_save_buffer(png_ptr);
00426          return;
00427       }
00428 
00429       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
00430    }
00431 
00432 #endif
00433 #ifdef PNG_READ_tRNS_SUPPORTED
00434    else if (chunk_name == png_tRNS)
00435    {
00436       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00437       {
00438          png_push_save_buffer(png_ptr);
00439          return;
00440       }
00441 
00442       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
00443    }
00444 
00445 #endif
00446 #ifdef PNG_READ_bKGD_SUPPORTED
00447    else if (chunk_name == png_bKGD)
00448    {
00449       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00450       {
00451          png_push_save_buffer(png_ptr);
00452          return;
00453       }
00454 
00455       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
00456    }
00457 
00458 #endif
00459 #ifdef PNG_READ_hIST_SUPPORTED
00460    else if (chunk_name == png_hIST)
00461    {
00462       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00463       {
00464          png_push_save_buffer(png_ptr);
00465          return;
00466       }
00467 
00468       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
00469    }
00470 
00471 #endif
00472 #ifdef PNG_READ_pHYs_SUPPORTED
00473    else if (chunk_name == png_pHYs)
00474    {
00475       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00476       {
00477          png_push_save_buffer(png_ptr);
00478          return;
00479       }
00480 
00481       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
00482    }
00483 
00484 #endif
00485 #ifdef PNG_READ_oFFs_SUPPORTED
00486    else if (chunk_name == png_oFFs)
00487    {
00488       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00489       {
00490          png_push_save_buffer(png_ptr);
00491          return;
00492       }
00493 
00494       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
00495    }
00496 #endif
00497 
00498 #ifdef PNG_READ_pCAL_SUPPORTED
00499    else if (chunk_name == png_pCAL)
00500    {
00501       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00502       {
00503          png_push_save_buffer(png_ptr);
00504          return;
00505       }
00506 
00507       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
00508    }
00509 
00510 #endif
00511 #ifdef PNG_READ_sCAL_SUPPORTED
00512    else if (chunk_name == png_sCAL)
00513    {
00514       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00515       {
00516          png_push_save_buffer(png_ptr);
00517          return;
00518       }
00519 
00520       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
00521    }
00522 
00523 #endif
00524 #ifdef PNG_READ_tIME_SUPPORTED
00525    else if (chunk_name == png_tIME)
00526    {
00527       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00528       {
00529          png_push_save_buffer(png_ptr);
00530          return;
00531       }
00532 
00533       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
00534    }
00535 
00536 #endif
00537 #ifdef PNG_READ_tEXt_SUPPORTED
00538    else if (chunk_name == png_tEXt)
00539    {
00540       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00541       {
00542          png_push_save_buffer(png_ptr);
00543          return;
00544       }
00545 
00546       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
00547    }
00548 
00549 #endif
00550 #ifdef PNG_READ_zTXt_SUPPORTED
00551    else if (chunk_name == png_zTXt)
00552    {
00553       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00554       {
00555          png_push_save_buffer(png_ptr);
00556          return;
00557       }
00558 
00559       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
00560    }
00561 
00562 #endif
00563 #ifdef PNG_READ_iTXt_SUPPORTED
00564    else if (chunk_name == png_iTXt)
00565    {
00566       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00567       {
00568          png_push_save_buffer(png_ptr);
00569          return;
00570       }
00571 
00572       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
00573    }
00574 
00575 #endif
00576    else
00577    {
00578       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
00579       {
00580          png_push_save_buffer(png_ptr);
00581          return;
00582       }
00583       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
00584    }
00585 
00586    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
00587 }
00588 
00589 void /* PRIVATE */
00590 png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
00591 {
00592    png_ptr->process_mode = PNG_SKIP_MODE;
00593    png_ptr->skip_length = skip;
00594 }
00595 
00596 void /* PRIVATE */
00597 png_push_crc_finish(png_structp png_ptr)
00598 {
00599    if (png_ptr->skip_length && png_ptr->save_buffer_size)
00600    {
00601       png_size_t save_size = png_ptr->save_buffer_size;
00602       png_uint_32 skip_length = png_ptr->skip_length;
00603 
00604       /* We want the smaller of 'skip_length' and 'save_buffer_size', but
00605        * they are of different types and we don't know which variable has the
00606        * fewest bits.  Carefully select the smaller and cast it to the type of
00607        * the larger - this cannot overflow.  Do not cast in the following test
00608        * - it will break on either 16 or 64 bit platforms.
00609        */
00610       if (skip_length < save_size)
00611          save_size = (png_size_t)skip_length;
00612 
00613       else
00614          skip_length = (png_uint_32)save_size;
00615 
00616       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
00617 
00618       png_ptr->skip_length -= skip_length;
00619       png_ptr->buffer_size -= save_size;
00620       png_ptr->save_buffer_size -= save_size;
00621       png_ptr->save_buffer_ptr += save_size;
00622    }
00623    if (png_ptr->skip_length && png_ptr->current_buffer_size)
00624    {
00625       png_size_t save_size = png_ptr->current_buffer_size;
00626       png_uint_32 skip_length = png_ptr->skip_length;
00627 
00628       /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
00629        * the same problem exists as above and the same solution.
00630        */
00631       if (skip_length < save_size)
00632          save_size = (png_size_t)skip_length;
00633 
00634       else
00635          skip_length = (png_uint_32)save_size;
00636 
00637       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
00638 
00639       png_ptr->skip_length -= skip_length;
00640       png_ptr->buffer_size -= save_size;
00641       png_ptr->current_buffer_size -= save_size;
00642       png_ptr->current_buffer_ptr += save_size;
00643    }
00644    if (!png_ptr->skip_length)
00645    {
00646       if (png_ptr->buffer_size < 4)
00647       {
00648          png_push_save_buffer(png_ptr);
00649          return;
00650       }
00651 
00652       png_crc_finish(png_ptr, 0);
00653       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00654    }
00655 }
00656 
00657 void PNGCBAPI
00658 png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
00659 {
00660    png_bytep ptr;
00661 
00662    if (png_ptr == NULL)
00663       return;
00664 
00665    ptr = buffer;
00666    if (png_ptr->save_buffer_size)
00667    {
00668       png_size_t save_size;
00669 
00670       if (length < png_ptr->save_buffer_size)
00671          save_size = length;
00672 
00673       else
00674          save_size = png_ptr->save_buffer_size;
00675 
00676       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
00677       length -= save_size;
00678       ptr += save_size;
00679       png_ptr->buffer_size -= save_size;
00680       png_ptr->save_buffer_size -= save_size;
00681       png_ptr->save_buffer_ptr += save_size;
00682    }
00683    if (length && png_ptr->current_buffer_size)
00684    {
00685       png_size_t save_size;
00686 
00687       if (length < png_ptr->current_buffer_size)
00688          save_size = length;
00689 
00690       else
00691          save_size = png_ptr->current_buffer_size;
00692 
00693       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
00694       png_ptr->buffer_size -= save_size;
00695       png_ptr->current_buffer_size -= save_size;
00696       png_ptr->current_buffer_ptr += save_size;
00697    }
00698 }
00699 
00700 void /* PRIVATE */
00701 png_push_save_buffer(png_structp png_ptr)
00702 {
00703    if (png_ptr->save_buffer_size)
00704    {
00705       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
00706       {
00707          png_size_t i, istop;
00708          png_bytep sp;
00709          png_bytep dp;
00710 
00711          istop = png_ptr->save_buffer_size;
00712          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
00713              i < istop; i++, sp++, dp++)
00714          {
00715             *dp = *sp;
00716          }
00717       }
00718    }
00719    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
00720        png_ptr->save_buffer_max)
00721    {
00722       png_size_t new_max;
00723       png_bytep old_buffer;
00724 
00725       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
00726           (png_ptr->current_buffer_size + 256))
00727       {
00728          png_error(png_ptr, "Potential overflow of save_buffer");
00729       }
00730 
00731       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
00732       old_buffer = png_ptr->save_buffer;
00733       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
00734 
00735       if (png_ptr->save_buffer == NULL)
00736       {
00737          png_free(png_ptr, old_buffer);
00738          png_error(png_ptr, "Insufficient memory for save_buffer");
00739       }
00740 
00741       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
00742       png_free(png_ptr, old_buffer);
00743       png_ptr->save_buffer_max = new_max;
00744    }
00745    if (png_ptr->current_buffer_size)
00746    {
00747       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
00748          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
00749       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
00750       png_ptr->current_buffer_size = 0;
00751    }
00752    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
00753    png_ptr->buffer_size = 0;
00754 }
00755 
00756 void /* PRIVATE */
00757 png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
00758    png_size_t buffer_length)
00759 {
00760    png_ptr->current_buffer = buffer;
00761    png_ptr->current_buffer_size = buffer_length;
00762    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
00763    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
00764 }
00765 
00766 void /* PRIVATE */
00767 png_push_read_IDAT(png_structp png_ptr)
00768 {
00769    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
00770    {
00771       png_byte chunk_length[4];
00772       png_byte chunk_tag[4];
00773 
00774       /* TODO: this code can be commoned up with the same code in push_read */
00775       if (png_ptr->buffer_size < 8)
00776       {
00777          png_push_save_buffer(png_ptr);
00778          return;
00779       }
00780 
00781       png_push_fill_buffer(png_ptr, chunk_length, 4);
00782       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
00783       png_reset_crc(png_ptr);
00784       png_crc_read(png_ptr, chunk_tag, 4);
00785       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
00786       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
00787 
00788       if (png_ptr->chunk_name != png_IDAT)
00789       {
00790          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
00791 
00792          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
00793             png_error(png_ptr, "Not enough compressed data");
00794 
00795          return;
00796       }
00797 
00798       png_ptr->idat_size = png_ptr->push_length;
00799    }
00800 
00801    if (png_ptr->idat_size && png_ptr->save_buffer_size)
00802    {
00803       png_size_t save_size = png_ptr->save_buffer_size;
00804       png_uint_32 idat_size = png_ptr->idat_size;
00805 
00806       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
00807        * are of different types and we don't know which variable has the fewest
00808        * bits.  Carefully select the smaller and cast it to the type of the
00809        * larger - this cannot overflow.  Do not cast in the following test - it
00810        * will break on either 16 or 64 bit platforms.
00811        */
00812       if (idat_size < save_size)
00813          save_size = (png_size_t)idat_size;
00814 
00815       else
00816          idat_size = (png_uint_32)save_size;
00817 
00818       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
00819 
00820       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
00821 
00822       png_ptr->idat_size -= idat_size;
00823       png_ptr->buffer_size -= save_size;
00824       png_ptr->save_buffer_size -= save_size;
00825       png_ptr->save_buffer_ptr += save_size;
00826    }
00827 
00828    if (png_ptr->idat_size && png_ptr->current_buffer_size)
00829    {
00830       png_size_t save_size = png_ptr->current_buffer_size;
00831       png_uint_32 idat_size = png_ptr->idat_size;
00832 
00833       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
00834        * are of different types and we don't know which variable has the fewest
00835        * bits.  Carefully select the smaller and cast it to the type of the
00836        * larger - this cannot overflow.
00837        */
00838       if (idat_size < save_size)
00839          save_size = (png_size_t)idat_size;
00840 
00841       else
00842          idat_size = (png_uint_32)save_size;
00843 
00844       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
00845 
00846       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
00847 
00848       png_ptr->idat_size -= idat_size;
00849       png_ptr->buffer_size -= save_size;
00850       png_ptr->current_buffer_size -= save_size;
00851       png_ptr->current_buffer_ptr += save_size;
00852    }
00853    if (!png_ptr->idat_size)
00854    {
00855       if (png_ptr->buffer_size < 4)
00856       {
00857          png_push_save_buffer(png_ptr);
00858          return;
00859       }
00860 
00861       png_crc_finish(png_ptr, 0);
00862       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
00863       png_ptr->mode |= PNG_AFTER_IDAT;
00864    }
00865 }
00866 
00867 void /* PRIVATE */
00868 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
00869    png_size_t buffer_length)
00870 {
00871    /* The caller checks for a non-zero buffer length. */
00872    if (!(buffer_length > 0) || buffer == NULL)
00873       png_error(png_ptr, "No IDAT data (internal error)");
00874 
00875    /* This routine must process all the data it has been given
00876     * before returning, calling the row callback as required to
00877     * handle the uncompressed results.
00878     */
00879    png_ptr->zstream.next_in = buffer;
00880    png_ptr->zstream.avail_in = (uInt)buffer_length;
00881 
00882    /* Keep going until the decompressed data is all processed
00883     * or the stream marked as finished.
00884     */
00885    while (png_ptr->zstream.avail_in > 0 &&
00886           !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
00887    {
00888       int ret;
00889 
00890       /* We have data for zlib, but we must check that zlib
00891        * has someplace to put the results.  It doesn't matter
00892        * if we don't expect any results -- it may be the input
00893        * data is just the LZ end code.
00894        */
00895       if (!(png_ptr->zstream.avail_out > 0))
00896       {
00897          png_ptr->zstream.avail_out =
00898              (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
00899              png_ptr->iwidth) + 1;
00900 
00901          png_ptr->zstream.next_out = png_ptr->row_buf;
00902       }
00903 
00904       /* Using Z_SYNC_FLUSH here means that an unterminated
00905        * LZ stream (a stream with a missing end code) can still
00906        * be handled, otherwise (Z_NO_FLUSH) a future zlib
00907        * implementation might defer output and therefore
00908        * change the current behavior (see comments in inflate.c
00909        * for why this doesn't happen at present with zlib 1.2.5).
00910        */
00911       ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
00912 
00913       /* Check for any failure before proceeding. */
00914       if (ret != Z_OK && ret != Z_STREAM_END)
00915       {
00916          /* Terminate the decompression. */
00917          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00918 
00919          /* This may be a truncated stream (missing or
00920           * damaged end code).  Treat that as a warning.
00921           */
00922          if (png_ptr->row_number >= png_ptr->num_rows ||
00923              png_ptr->pass > 6)
00924             png_warning(png_ptr, "Truncated compressed data in IDAT");
00925 
00926          else
00927             png_error(png_ptr, "Decompression error in IDAT");
00928 
00929          /* Skip the check on unprocessed input */
00930          return;
00931       }
00932 
00933       /* Did inflate output any data? */
00934       if (png_ptr->zstream.next_out != png_ptr->row_buf)
00935       {
00936          /* Is this unexpected data after the last row?
00937           * If it is, artificially terminate the LZ output
00938           * here.
00939           */
00940          if (png_ptr->row_number >= png_ptr->num_rows ||
00941              png_ptr->pass > 6)
00942          {
00943             /* Extra data. */
00944             png_warning(png_ptr, "Extra compressed data in IDAT");
00945             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00946 
00947             /* Do no more processing; skip the unprocessed
00948              * input check below.
00949              */
00950             return;
00951          }
00952 
00953          /* Do we have a complete row? */
00954          if (png_ptr->zstream.avail_out == 0)
00955             png_push_process_row(png_ptr);
00956       }
00957 
00958       /* And check for the end of the stream. */
00959       if (ret == Z_STREAM_END)
00960          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00961    }
00962 
00963    /* All the data should have been processed, if anything
00964     * is left at this point we have bytes of IDAT data
00965     * after the zlib end code.
00966     */
00967    if (png_ptr->zstream.avail_in > 0)
00968       png_warning(png_ptr, "Extra compression data in IDAT");
00969 }
00970 
00971 void /* PRIVATE */
00972 png_push_process_row(png_structp png_ptr)
00973 {
00974    /* 1.5.6: row_info moved out of png_struct to a local here. */
00975    png_row_info row_info;
00976 
00977    row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
00978    row_info.color_type = png_ptr->color_type;
00979    row_info.bit_depth = png_ptr->bit_depth;
00980    row_info.channels = png_ptr->channels;
00981    row_info.pixel_depth = png_ptr->pixel_depth;
00982    row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
00983 
00984    if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
00985    {
00986       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
00987          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
00988             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
00989       else
00990          png_error(png_ptr, "bad adaptive filter value");
00991    }
00992 
00993    /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
00994     * 1.5.6, while the buffer really is this big in current versions of libpng
00995     * it may not be in the future, so this was changed just to copy the
00996     * interlaced row count:
00997     */
00998    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
00999 
01000 #ifdef PNG_READ_TRANSFORMS_SUPPORTED
01001    if (png_ptr->transformations)
01002       png_do_read_transformations(png_ptr, &row_info);
01003 #endif
01004 
01005    /* The transformed pixel depth should match the depth now in row_info. */
01006    if (png_ptr->transformed_pixel_depth == 0)
01007    {
01008       png_ptr->transformed_pixel_depth = row_info.pixel_depth;
01009       if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
01010          png_error(png_ptr, "progressive row overflow");
01011    }
01012 
01013    else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
01014       png_error(png_ptr, "internal progressive row size calculation error");
01015 
01016 
01017 #ifdef PNG_READ_INTERLACING_SUPPORTED
01018    /* Blow up interlaced rows to full size */
01019    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
01020    {
01021       if (png_ptr->pass < 6)
01022          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
01023             png_ptr->transformations);
01024 
01025     switch (png_ptr->pass)
01026     {
01027          case 0:
01028          {
01029             int i;
01030             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
01031             {
01032                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01033                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
01034             }
01035 
01036             if (png_ptr->pass == 2) /* Pass 1 might be empty */
01037             {
01038                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
01039                {
01040                   png_push_have_row(png_ptr, NULL);
01041                   png_read_push_finish_row(png_ptr);
01042                }
01043             }
01044 
01045             if (png_ptr->pass == 4 && png_ptr->height <= 4)
01046             {
01047                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
01048                {
01049                   png_push_have_row(png_ptr, NULL);
01050                   png_read_push_finish_row(png_ptr);
01051                }
01052             }
01053 
01054             if (png_ptr->pass == 6 && png_ptr->height <= 4)
01055             {
01056                 png_push_have_row(png_ptr, NULL);
01057                 png_read_push_finish_row(png_ptr);
01058             }
01059 
01060             break;
01061          }
01062 
01063          case 1:
01064          {
01065             int i;
01066             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
01067             {
01068                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01069                png_read_push_finish_row(png_ptr);
01070             }
01071 
01072             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
01073             {
01074                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
01075                {
01076                   png_push_have_row(png_ptr, NULL);
01077                   png_read_push_finish_row(png_ptr);
01078                }
01079             }
01080 
01081             break;
01082          }
01083 
01084          case 2:
01085          {
01086             int i;
01087 
01088             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
01089             {
01090                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01091                png_read_push_finish_row(png_ptr);
01092             }
01093 
01094             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
01095             {
01096                png_push_have_row(png_ptr, NULL);
01097                png_read_push_finish_row(png_ptr);
01098             }
01099 
01100             if (png_ptr->pass == 4) /* Pass 3 might be empty */
01101             {
01102                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
01103                {
01104                   png_push_have_row(png_ptr, NULL);
01105                   png_read_push_finish_row(png_ptr);
01106                }
01107             }
01108 
01109             break;
01110          }
01111 
01112          case 3:
01113          {
01114             int i;
01115 
01116             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
01117             {
01118                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01119                png_read_push_finish_row(png_ptr);
01120             }
01121 
01122             if (png_ptr->pass == 4) /* Skip top two generated rows */
01123             {
01124                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
01125                {
01126                   png_push_have_row(png_ptr, NULL);
01127                   png_read_push_finish_row(png_ptr);
01128                }
01129             }
01130 
01131             break;
01132          }
01133 
01134          case 4:
01135          {
01136             int i;
01137 
01138             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
01139             {
01140                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01141                png_read_push_finish_row(png_ptr);
01142             }
01143 
01144             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
01145             {
01146                png_push_have_row(png_ptr, NULL);
01147                png_read_push_finish_row(png_ptr);
01148             }
01149 
01150             if (png_ptr->pass == 6) /* Pass 5 might be empty */
01151             {
01152                png_push_have_row(png_ptr, NULL);
01153                png_read_push_finish_row(png_ptr);
01154             }
01155 
01156             break;
01157          }
01158 
01159          case 5:
01160          {
01161             int i;
01162 
01163             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
01164             {
01165                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01166                png_read_push_finish_row(png_ptr);
01167             }
01168 
01169             if (png_ptr->pass == 6) /* Skip top generated row */
01170             {
01171                png_push_have_row(png_ptr, NULL);
01172                png_read_push_finish_row(png_ptr);
01173             }
01174 
01175             break;
01176          }
01177 
01178          default:
01179          case 6:
01180          {
01181             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01182             png_read_push_finish_row(png_ptr);
01183 
01184             if (png_ptr->pass != 6)
01185                break;
01186 
01187             png_push_have_row(png_ptr, NULL);
01188             png_read_push_finish_row(png_ptr);
01189          }
01190       }
01191    }
01192    else
01193 #endif
01194    {
01195       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
01196       png_read_push_finish_row(png_ptr);
01197    }
01198 }
01199 
01200 void /* PRIVATE */
01201 png_read_push_finish_row(png_structp png_ptr)
01202 {
01203 #ifdef PNG_READ_INTERLACING_SUPPORTED
01204    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
01205 
01206    /* Start of interlace block */
01207    static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
01208 
01209    /* Offset to next interlace block */
01210    static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
01211 
01212    /* Start of interlace block in the y direction */
01213    static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
01214 
01215    /* Offset to next interlace block in the y direction */
01216    static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
01217 
01218    /* Height of interlace block.  This is not currently used - if you need
01219     * it, uncomment it here and in png.h
01220    static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
01221    */
01222 #endif
01223 
01224    png_ptr->row_number++;
01225    if (png_ptr->row_number < png_ptr->num_rows)
01226       return;
01227 
01228 #ifdef PNG_READ_INTERLACING_SUPPORTED
01229    if (png_ptr->interlaced)
01230    {
01231       png_ptr->row_number = 0;
01232       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
01233 
01234       do
01235       {
01236          png_ptr->pass++;
01237          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
01238              (png_ptr->pass == 3 && png_ptr->width < 3) ||
01239              (png_ptr->pass == 5 && png_ptr->width < 2))
01240             png_ptr->pass++;
01241 
01242          if (png_ptr->pass > 7)
01243             png_ptr->pass--;
01244 
01245          if (png_ptr->pass >= 7)
01246             break;
01247 
01248          png_ptr->iwidth = (png_ptr->width +
01249              png_pass_inc[png_ptr->pass] - 1 -
01250              png_pass_start[png_ptr->pass]) /
01251              png_pass_inc[png_ptr->pass];
01252 
01253          if (png_ptr->transformations & PNG_INTERLACE)
01254             break;
01255 
01256          png_ptr->num_rows = (png_ptr->height +
01257              png_pass_yinc[png_ptr->pass] - 1 -
01258              png_pass_ystart[png_ptr->pass]) /
01259              png_pass_yinc[png_ptr->pass];
01260 
01261       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
01262    }
01263 #endif /* PNG_READ_INTERLACING_SUPPORTED */
01264 }
01265 
01266 #ifdef PNG_READ_tEXt_SUPPORTED
01267 void /* PRIVATE */
01268 png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01269     length)
01270 {
01271    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01272       {
01273          PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
01274          png_error(png_ptr, "Out of place tEXt");
01275          /* NOT REACHED */
01276       }
01277 
01278 #ifdef PNG_MAX_MALLOC_64K
01279    png_ptr->skip_length = 0;  /* This may not be necessary */
01280 
01281    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
01282    {
01283       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
01284       png_ptr->skip_length = length - (png_uint_32)65535L;
01285       length = (png_uint_32)65535L;
01286    }
01287 #endif
01288 
01289    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
01290    png_ptr->current_text[length] = '\0';
01291    png_ptr->current_text_ptr = png_ptr->current_text;
01292    png_ptr->current_text_size = (png_size_t)length;
01293    png_ptr->current_text_left = (png_size_t)length;
01294    png_ptr->process_mode = PNG_READ_tEXt_MODE;
01295 }
01296 
01297 void /* PRIVATE */
01298 png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
01299 {
01300    if (png_ptr->buffer_size && png_ptr->current_text_left)
01301    {
01302       png_size_t text_size;
01303 
01304       if (png_ptr->buffer_size < png_ptr->current_text_left)
01305          text_size = png_ptr->buffer_size;
01306 
01307       else
01308          text_size = png_ptr->current_text_left;
01309 
01310       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01311       png_ptr->current_text_left -= text_size;
01312       png_ptr->current_text_ptr += text_size;
01313    }
01314    if (!(png_ptr->current_text_left))
01315    {
01316       png_textp text_ptr;
01317       png_charp text;
01318       png_charp key;
01319       int ret;
01320 
01321       if (png_ptr->buffer_size < 4)
01322       {
01323          png_push_save_buffer(png_ptr);
01324          return;
01325       }
01326 
01327       png_push_crc_finish(png_ptr);
01328 
01329 #ifdef PNG_MAX_MALLOC_64K
01330       if (png_ptr->skip_length)
01331          return;
01332 #endif
01333 
01334       key = png_ptr->current_text;
01335 
01336       for (text = key; *text; text++)
01337          /* Empty loop */ ;
01338 
01339       if (text < key + png_ptr->current_text_size)
01340          text++;
01341 
01342       text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
01343       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
01344       text_ptr->key = key;
01345       text_ptr->itxt_length = 0;
01346       text_ptr->lang = NULL;
01347       text_ptr->lang_key = NULL;
01348       text_ptr->text = text;
01349 
01350       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01351 
01352       png_free(png_ptr, key);
01353       png_free(png_ptr, text_ptr);
01354       png_ptr->current_text = NULL;
01355 
01356       if (ret)
01357          png_warning(png_ptr, "Insufficient memory to store text chunk");
01358    }
01359 }
01360 #endif
01361 
01362 #ifdef PNG_READ_zTXt_SUPPORTED
01363 void /* PRIVATE */
01364 png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01365    length)
01366 {
01367    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01368    {
01369       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
01370       png_error(png_ptr, "Out of place zTXt");
01371       /* NOT REACHED */
01372    }
01373 
01374 #ifdef PNG_MAX_MALLOC_64K
01375    /* We can't handle zTXt chunks > 64K, since we don't have enough space
01376     * to be able to store the uncompressed data.  Actually, the threshold
01377     * is probably around 32K, but it isn't as definite as 64K is.
01378     */
01379    if (length > (png_uint_32)65535L)
01380    {
01381       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
01382       png_push_crc_skip(png_ptr, length);
01383       return;
01384    }
01385 #endif
01386 
01387    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
01388    png_ptr->current_text[length] = '\0';
01389    png_ptr->current_text_ptr = png_ptr->current_text;
01390    png_ptr->current_text_size = (png_size_t)length;
01391    png_ptr->current_text_left = (png_size_t)length;
01392    png_ptr->process_mode = PNG_READ_zTXt_MODE;
01393 }
01394 
01395 void /* PRIVATE */
01396 png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
01397 {
01398    if (png_ptr->buffer_size && png_ptr->current_text_left)
01399    {
01400       png_size_t text_size;
01401 
01402       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
01403          text_size = png_ptr->buffer_size;
01404 
01405       else
01406          text_size = png_ptr->current_text_left;
01407 
01408       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01409       png_ptr->current_text_left -= text_size;
01410       png_ptr->current_text_ptr += text_size;
01411    }
01412    if (!(png_ptr->current_text_left))
01413    {
01414       png_textp text_ptr;
01415       png_charp text;
01416       png_charp key;
01417       int ret;
01418       png_size_t text_size, key_size;
01419 
01420       if (png_ptr->buffer_size < 4)
01421       {
01422          png_push_save_buffer(png_ptr);
01423          return;
01424       }
01425 
01426       png_push_crc_finish(png_ptr);
01427 
01428       key = png_ptr->current_text;
01429 
01430       for (text = key; *text; text++)
01431          /* Empty loop */ ;
01432 
01433       /* zTXt can't have zero text */
01434       if (text >= key + png_ptr->current_text_size)
01435       {
01436          png_ptr->current_text = NULL;
01437          png_free(png_ptr, key);
01438          return;
01439       }
01440 
01441       text++;
01442 
01443       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
01444       {
01445          png_ptr->current_text = NULL;
01446          png_free(png_ptr, key);
01447          return;
01448       }
01449 
01450       text++;
01451 
01452       png_ptr->zstream.next_in = (png_bytep)text;
01453       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
01454           (text - key));
01455       png_ptr->zstream.next_out = png_ptr->zbuf;
01456       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
01457 
01458       key_size = text - key;
01459       text_size = 0;
01460       text = NULL;
01461       ret = Z_STREAM_END;
01462 
01463       while (png_ptr->zstream.avail_in)
01464       {
01465          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
01466          if (ret != Z_OK && ret != Z_STREAM_END)
01467          {
01468             inflateReset(&png_ptr->zstream);
01469             png_ptr->zstream.avail_in = 0;
01470             png_ptr->current_text = NULL;
01471             png_free(png_ptr, key);
01472             png_free(png_ptr, text);
01473             return;
01474          }
01475 
01476          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
01477          {
01478             if (text == NULL)
01479             {
01480                text = (png_charp)png_malloc(png_ptr,
01481                    (png_ptr->zbuf_size
01482                    - png_ptr->zstream.avail_out + key_size + 1));
01483 
01484                png_memcpy(text + key_size, png_ptr->zbuf,
01485                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
01486 
01487                png_memcpy(text, key, key_size);
01488 
01489                text_size = key_size + png_ptr->zbuf_size -
01490                    png_ptr->zstream.avail_out;
01491 
01492                *(text + text_size) = '\0';
01493             }
01494 
01495             else
01496             {
01497                png_charp tmp;
01498 
01499                tmp = text;
01500                text = (png_charp)png_malloc(png_ptr, text_size +
01501                    (png_ptr->zbuf_size
01502                    - png_ptr->zstream.avail_out + 1));
01503 
01504                png_memcpy(text, tmp, text_size);
01505                png_free(png_ptr, tmp);
01506 
01507                png_memcpy(text + text_size, png_ptr->zbuf,
01508                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
01509 
01510                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
01511                *(text + text_size) = '\0';
01512             }
01513 
01514             if (ret != Z_STREAM_END)
01515             {
01516                png_ptr->zstream.next_out = png_ptr->zbuf;
01517                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
01518             }
01519          }
01520          else
01521          {
01522             break;
01523          }
01524 
01525          if (ret == Z_STREAM_END)
01526             break;
01527       }
01528 
01529       inflateReset(&png_ptr->zstream);
01530       png_ptr->zstream.avail_in = 0;
01531 
01532       if (ret != Z_STREAM_END)
01533       {
01534          png_ptr->current_text = NULL;
01535          png_free(png_ptr, key);
01536          png_free(png_ptr, text);
01537          return;
01538       }
01539 
01540       png_ptr->current_text = NULL;
01541       png_free(png_ptr, key);
01542       key = text;
01543       text += key_size;
01544 
01545       text_ptr = (png_textp)png_malloc(png_ptr,
01546           png_sizeof(png_text));
01547       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
01548       text_ptr->key = key;
01549       text_ptr->itxt_length = 0;
01550       text_ptr->lang = NULL;
01551       text_ptr->lang_key = NULL;
01552       text_ptr->text = text;
01553 
01554       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01555 
01556       png_free(png_ptr, key);
01557       png_free(png_ptr, text_ptr);
01558 
01559       if (ret)
01560          png_warning(png_ptr, "Insufficient memory to store text chunk");
01561    }
01562 }
01563 #endif
01564 
01565 #ifdef PNG_READ_iTXt_SUPPORTED
01566 void /* PRIVATE */
01567 png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
01568     length)
01569 {
01570    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
01571    {
01572       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
01573       png_error(png_ptr, "Out of place iTXt");
01574       /* NOT REACHED */
01575    }
01576 
01577 #ifdef PNG_MAX_MALLOC_64K
01578    png_ptr->skip_length = 0;  /* This may not be necessary */
01579 
01580    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
01581    {
01582       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
01583       png_ptr->skip_length = length - (png_uint_32)65535L;
01584       length = (png_uint_32)65535L;
01585    }
01586 #endif
01587 
01588    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
01589    png_ptr->current_text[length] = '\0';
01590    png_ptr->current_text_ptr = png_ptr->current_text;
01591    png_ptr->current_text_size = (png_size_t)length;
01592    png_ptr->current_text_left = (png_size_t)length;
01593    png_ptr->process_mode = PNG_READ_iTXt_MODE;
01594 }
01595 
01596 void /* PRIVATE */
01597 png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
01598 {
01599 
01600    if (png_ptr->buffer_size && png_ptr->current_text_left)
01601    {
01602       png_size_t text_size;
01603 
01604       if (png_ptr->buffer_size < png_ptr->current_text_left)
01605          text_size = png_ptr->buffer_size;
01606 
01607       else
01608          text_size = png_ptr->current_text_left;
01609 
01610       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
01611       png_ptr->current_text_left -= text_size;
01612       png_ptr->current_text_ptr += text_size;
01613    }
01614 
01615    if (!(png_ptr->current_text_left))
01616    {
01617       png_textp text_ptr;
01618       png_charp key;
01619       int comp_flag;
01620       png_charp lang;
01621       png_charp lang_key;
01622       png_charp text;
01623       int ret;
01624 
01625       if (png_ptr->buffer_size < 4)
01626       {
01627          png_push_save_buffer(png_ptr);
01628          return;
01629       }
01630 
01631       png_push_crc_finish(png_ptr);
01632 
01633 #ifdef PNG_MAX_MALLOC_64K
01634       if (png_ptr->skip_length)
01635          return;
01636 #endif
01637 
01638       key = png_ptr->current_text;
01639 
01640       for (lang = key; *lang; lang++)
01641          /* Empty loop */ ;
01642 
01643       if (lang < key + png_ptr->current_text_size - 3)
01644          lang++;
01645 
01646       comp_flag = *lang++;
01647       lang++;     /* Skip comp_type, always zero */
01648 
01649       for (lang_key = lang; *lang_key; lang_key++)
01650          /* Empty loop */ ;
01651 
01652       lang_key++;        /* Skip NUL separator */
01653 
01654       text=lang_key;
01655 
01656       if (lang_key < key + png_ptr->current_text_size - 1)
01657       {
01658          for (; *text; text++)
01659             /* Empty loop */ ;
01660       }
01661 
01662       if (text < key + png_ptr->current_text_size)
01663          text++;
01664 
01665       text_ptr = (png_textp)png_malloc(png_ptr,
01666           png_sizeof(png_text));
01667 
01668       text_ptr->compression = comp_flag + 2;
01669       text_ptr->key = key;
01670       text_ptr->lang = lang;
01671       text_ptr->lang_key = lang_key;
01672       text_ptr->text = text;
01673       text_ptr->text_length = 0;
01674       text_ptr->itxt_length = png_strlen(text);
01675 
01676       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
01677 
01678       png_ptr->current_text = NULL;
01679 
01680       png_free(png_ptr, text_ptr);
01681       if (ret)
01682          png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
01683    }
01684 }
01685 #endif
01686 
01687 /* This function is called when we haven't found a handler for this
01688  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
01689  * name or a critical chunk), the chunk is (currently) silently ignored.
01690  */
01691 void /* PRIVATE */
01692 png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
01693     length)
01694 {
01695    png_uint_32 skip = 0;
01696    png_uint_32 chunk_name = png_ptr->chunk_name;
01697 
01698    if (PNG_CHUNK_CRITICAL(chunk_name))
01699    {
01700 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
01701       if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
01702           PNG_HANDLE_CHUNK_ALWAYS
01703 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
01704           && png_ptr->read_user_chunk_fn == NULL
01705 #endif
01706           )
01707 #endif
01708          png_chunk_error(png_ptr, "unknown critical chunk");
01709 
01710       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
01711    }
01712 
01713 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
01714    /* TODO: the code below is apparently just using the
01715     * png_struct::unknown_chunk member as a temporarily variable, it should be
01716     * possible to eliminate both it and the temporary buffer.
01717     */
01718    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
01719    {
01720 #ifdef PNG_MAX_MALLOC_64K
01721       if (length > 65535)
01722       {
01723          png_warning(png_ptr, "unknown chunk too large to fit in memory");
01724          skip = length - 65535;
01725          length = 65535;
01726       }
01727 #endif
01728       /* This is just a record for the user; libpng doesn't use the character
01729        * form of the name.
01730        */
01731       PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
01732 
01733       png_ptr->unknown_chunk.size = length;
01734 
01735       if (length == 0)
01736          png_ptr->unknown_chunk.data = NULL;
01737 
01738       else
01739       {
01740          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
01741             png_ptr->unknown_chunk.size);
01742          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
01743             png_ptr->unknown_chunk.size);
01744       }
01745 
01746 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
01747       if (png_ptr->read_user_chunk_fn != NULL)
01748       {
01749          /* Callback to user unknown chunk handler */
01750          int ret;
01751          ret = (*(png_ptr->read_user_chunk_fn))
01752              (png_ptr, &png_ptr->unknown_chunk);
01753 
01754          if (ret < 0)
01755             png_chunk_error(png_ptr, "error in user chunk");
01756 
01757          if (ret == 0)
01758          {
01759             if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
01760                if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
01761                    PNG_HANDLE_CHUNK_ALWAYS)
01762                   png_chunk_error(png_ptr, "unknown critical chunk");
01763             png_set_unknown_chunks(png_ptr, info_ptr,
01764                 &png_ptr->unknown_chunk, 1);
01765          }
01766       }
01767 
01768       else
01769 #endif
01770          png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
01771       png_free(png_ptr, png_ptr->unknown_chunk.data);
01772       png_ptr->unknown_chunk.data = NULL;
01773    }
01774 
01775    else
01776 #endif
01777       skip=length;
01778    png_push_crc_skip(png_ptr, skip);
01779 }
01780 
01781 void /* PRIVATE */
01782 png_push_have_info(png_structp png_ptr, png_infop info_ptr)
01783 {
01784    if (png_ptr->info_fn != NULL)
01785       (*(png_ptr->info_fn))(png_ptr, info_ptr);
01786 }
01787 
01788 void /* PRIVATE */
01789 png_push_have_end(png_structp png_ptr, png_infop info_ptr)
01790 {
01791    if (png_ptr->end_fn != NULL)
01792       (*(png_ptr->end_fn))(png_ptr, info_ptr);
01793 }
01794 
01795 void /* PRIVATE */
01796 png_push_have_row(png_structp png_ptr, png_bytep row)
01797 {
01798    if (png_ptr->row_fn != NULL)
01799       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
01800          (int)png_ptr->pass);
01801 }
01802 
01803 #ifdef PNG_READ_INTERLACING_SUPPORTED
01804 void PNGAPI
01805 png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
01806     png_const_bytep new_row)
01807 {
01808    if (png_ptr == NULL)
01809       return;
01810 
01811    /* new_row is a flag here - if it is NULL then the app callback was called
01812     * from an empty row (see the calls to png_struct::row_fn below), otherwise
01813     * it must be png_ptr->row_buf+1
01814     */
01815    if (new_row != NULL)
01816       png_combine_row(png_ptr, old_row, 1/*display*/);
01817 }
01818 #endif /* PNG_READ_INTERLACING_SUPPORTED */
01819 
01820 void PNGAPI
01821 png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
01822     png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
01823     png_progressive_end_ptr end_fn)
01824 {
01825    if (png_ptr == NULL)
01826       return;
01827 
01828    png_ptr->info_fn = info_fn;
01829    png_ptr->row_fn = row_fn;
01830    png_ptr->end_fn = end_fn;
01831 
01832    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
01833 }
01834 
01835 png_voidp PNGAPI
01836 png_get_progressive_ptr(png_const_structp png_ptr)
01837 {
01838    if (png_ptr == NULL)
01839       return (NULL);
01840 
01841    return png_ptr->io_ptr;
01842 }
01843 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

Generated on Sat May 26 2012 04:18:16 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.