fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

pngread.c

Go to the documentation of this file.
00001 
00002 /* pngread.c - read a PNG file
00003  *
00004  * Last changed in libpng 1.2.37 [June 4, 2009]
00005  * Copyright (c) 1998-2009 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  * This file contains routines that an application calls directly to
00014  * read a PNG file or stream.
00015  */
00016 
00017 #define PNG_INTERNAL
00018 #include "png.h"
00019 #if defined(PNG_READ_SUPPORTED)
00020 
00021 /* Create a PNG structure for reading, and allocate any memory needed. */
00022 png_structp PNGAPI
00023 png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
00024    png_error_ptr error_fn, png_error_ptr warn_fn)
00025 {
00026 
00027 #ifdef PNG_USER_MEM_SUPPORTED
00028    return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
00029       warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
00030 }
00031 
00032 /* Alternate create PNG structure for reading, and allocate any memory needed. */
00033 png_structp PNGAPI
00034 png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
00035    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
00036    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
00037 {
00038 #endif /* PNG_USER_MEM_SUPPORTED */
00039 
00040 #ifdef PNG_SETJMP_SUPPORTED
00041    volatile
00042 #endif
00043    png_structp png_ptr;
00044 
00045 #ifdef PNG_SETJMP_SUPPORTED
00046 #ifdef USE_FAR_KEYWORD
00047    jmp_buf jmpbuf;
00048 #endif
00049 #endif
00050 
00051    int i;
00052 
00053    png_debug(1, "in png_create_read_struct");
00054 #ifdef PNG_USER_MEM_SUPPORTED
00055    png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
00056       (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
00057 #else
00058    png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
00059 #endif
00060    if (png_ptr == NULL)
00061       return (NULL);
00062 
00063    /* Added at libpng-1.2.6 */
00064 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
00065    png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
00066    png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
00067 #endif
00068 
00069 #ifdef PNG_SETJMP_SUPPORTED
00070 #ifdef USE_FAR_KEYWORD
00071    if (setjmp(jmpbuf))
00072 #else
00073    if (setjmp(png_ptr->jmpbuf))
00074 #endif
00075    {
00076       png_free(png_ptr, png_ptr->zbuf);
00077       png_ptr->zbuf = NULL;
00078 #ifdef PNG_USER_MEM_SUPPORTED
00079       png_destroy_struct_2((png_voidp)png_ptr,
00080          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
00081 #else
00082       png_destroy_struct((png_voidp)png_ptr);
00083 #endif
00084       return (NULL);
00085    }
00086 #ifdef USE_FAR_KEYWORD
00087    png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
00088 #endif
00089 #endif
00090 
00091 #ifdef PNG_USER_MEM_SUPPORTED
00092    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
00093 #endif
00094 
00095    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
00096 
00097    if (user_png_ver)
00098    {
00099      i = 0;
00100      do
00101      {
00102        if (user_png_ver[i] != png_libpng_ver[i])
00103           png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
00104      } while (png_libpng_ver[i++]);
00105    }
00106    else
00107         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
00108 
00109 
00110    if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
00111    {
00112      /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
00113       * we must recompile any applications that use any older library version.
00114       * For versions after libpng 1.0, we will be compatible, so we need
00115       * only check the first digit.
00116       */
00117      if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
00118          (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
00119          (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
00120      {
00121 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00122         char msg[80];
00123         if (user_png_ver)
00124         {
00125           png_snprintf(msg, 80,
00126              "Application was compiled with png.h from libpng-%.20s",
00127              user_png_ver);
00128           png_warning(png_ptr, msg);
00129         }
00130         png_snprintf(msg, 80,
00131              "Application  is  running with png.c from libpng-%.20s",
00132            png_libpng_ver);
00133         png_warning(png_ptr, msg);
00134 #endif
00135 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00136         png_ptr->flags = 0;
00137 #endif
00138         png_error(png_ptr,
00139            "Incompatible libpng version in application and library");
00140      }
00141    }
00142 
00143    /* Initialize zbuf - compression buffer */
00144    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
00145    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
00146      (png_uint_32)png_ptr->zbuf_size);
00147    png_ptr->zstream.zalloc = png_zalloc;
00148    png_ptr->zstream.zfree = png_zfree;
00149    png_ptr->zstream.opaque = (voidpf)png_ptr;
00150 
00151    switch (inflateInit(&png_ptr->zstream))
00152    {
00153      case Z_OK: /* Do nothing */ break;
00154      case Z_MEM_ERROR:
00155      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
00156      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
00157      default: png_error(png_ptr, "Unknown zlib error");
00158    }
00159 
00160    png_ptr->zstream.next_out = png_ptr->zbuf;
00161    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00162 
00163    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
00164 
00165 #ifdef PNG_SETJMP_SUPPORTED
00166 /* Applications that neglect to set up their own setjmp() and then encounter
00167    a png_error() will longjmp here.  Since the jmpbuf is then meaningless we
00168    abort instead of returning. */
00169 #ifdef USE_FAR_KEYWORD
00170    if (setjmp(jmpbuf))
00171       PNG_ABORT();
00172    png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
00173 #else
00174    if (setjmp(png_ptr->jmpbuf))
00175       PNG_ABORT();
00176 #endif
00177 #endif
00178    return (png_ptr);
00179 }
00180 
00181 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
00182 /* Initialize PNG structure for reading, and allocate any memory needed.
00183    This interface is deprecated in favour of the png_create_read_struct(),
00184    and it will disappear as of libpng-1.3.0. */
00185 #undef png_read_init
00186 void PNGAPI
00187 png_read_init(png_structp png_ptr)
00188 {
00189    /* We only come here via pre-1.0.7-compiled applications */
00190    png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
00191 }
00192 
00193 void PNGAPI
00194 png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
00195    png_size_t png_struct_size, png_size_t png_info_size)
00196 {
00197    /* We only come here via pre-1.0.12-compiled applications */
00198    if (png_ptr == NULL)
00199       return;
00200 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
00201    if (png_sizeof(png_struct) > png_struct_size ||
00202       png_sizeof(png_info) > png_info_size)
00203    {
00204       char msg[80];
00205       png_ptr->warning_fn = NULL;
00206       if (user_png_ver)
00207       {
00208         png_snprintf(msg, 80,
00209            "Application was compiled with png.h from libpng-%.20s",
00210            user_png_ver);
00211         png_warning(png_ptr, msg);
00212       }
00213       png_snprintf(msg, 80,
00214          "Application  is  running with png.c from libpng-%.20s",
00215          png_libpng_ver);
00216       png_warning(png_ptr, msg);
00217    }
00218 #endif
00219    if (png_sizeof(png_struct) > png_struct_size)
00220      {
00221        png_ptr->error_fn = NULL;
00222 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00223        png_ptr->flags = 0;
00224 #endif
00225        png_error(png_ptr,
00226        "The png struct allocated by the application for reading is too small.");
00227      }
00228    if (png_sizeof(png_info) > png_info_size)
00229      {
00230        png_ptr->error_fn = NULL;
00231 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
00232        png_ptr->flags = 0;
00233 #endif
00234        png_error(png_ptr,
00235          "The info struct allocated by application for reading is too small.");
00236      }
00237    png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
00238 }
00239 #endif /* PNG_1_0_X || PNG_1_2_X */
00240 
00241 void PNGAPI
00242 png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
00243    png_size_t png_struct_size)
00244 {
00245 #ifdef PNG_SETJMP_SUPPORTED
00246    jmp_buf tmp_jmp;  /* to save current jump buffer */
00247 #endif
00248 
00249    int i = 0;
00250 
00251    png_structp png_ptr=*ptr_ptr;
00252 
00253    if (png_ptr == NULL)
00254       return;
00255 
00256    do
00257    {
00258      if (user_png_ver[i] != png_libpng_ver[i])
00259      {
00260 #ifdef PNG_LEGACY_SUPPORTED
00261        png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
00262 #else
00263        png_ptr->warning_fn = NULL;
00264        png_warning(png_ptr,
00265         "Application uses deprecated png_read_init() and should be recompiled.");
00266        break;
00267 #endif
00268      }
00269    } while (png_libpng_ver[i++]);
00270 
00271    png_debug(1, "in png_read_init_3");
00272 
00273 #ifdef PNG_SETJMP_SUPPORTED
00274    /* Save jump buffer and error functions */
00275    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
00276 #endif
00277 
00278    if (png_sizeof(png_struct) > png_struct_size)
00279    {
00280       png_destroy_struct(png_ptr);
00281       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
00282       png_ptr = *ptr_ptr;
00283    }
00284 
00285    /* Reset all variables to 0 */
00286    png_memset(png_ptr, 0, png_sizeof(png_struct));
00287 
00288 #ifdef PNG_SETJMP_SUPPORTED
00289    /* Restore jump buffer */
00290    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
00291 #endif
00292 
00293    /* Added at libpng-1.2.6 */
00294 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
00295    png_ptr->user_width_max=PNG_USER_WIDTH_MAX;
00296    png_ptr->user_height_max=PNG_USER_HEIGHT_MAX;
00297 #endif
00298 
00299    /* Initialize zbuf - compression buffer */
00300    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
00301    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
00302      (png_uint_32)png_ptr->zbuf_size);
00303    png_ptr->zstream.zalloc = png_zalloc;
00304    png_ptr->zstream.zfree = png_zfree;
00305    png_ptr->zstream.opaque = (voidpf)png_ptr;
00306 
00307    switch (inflateInit(&png_ptr->zstream))
00308    {
00309      case Z_OK: /* Do nothing */ break;
00310      case Z_MEM_ERROR:
00311      case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
00312      case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
00313      default: png_error(png_ptr, "Unknown zlib error");
00314    }
00315 
00316    png_ptr->zstream.next_out = png_ptr->zbuf;
00317    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
00318 
00319    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
00320 }
00321 
00322 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00323 /* Read the information before the actual image data.  This has been
00324  * changed in v0.90 to allow reading a file that already has the magic
00325  * bytes read from the stream.  You can tell libpng how many bytes have
00326  * been read from the beginning of the stream (up to the maximum of 8)
00327  * via png_set_sig_bytes(), and we will only check the remaining bytes
00328  * here.  The application can then have access to the signature bytes we
00329  * read if it is determined that this isn't a valid PNG file.
00330  */
00331 void PNGAPI
00332 png_read_info(png_structp png_ptr, png_infop info_ptr)
00333 {
00334    if (png_ptr == NULL || info_ptr == NULL)
00335       return;
00336    png_debug(1, "in png_read_info");
00337    /* If we haven't checked all of the PNG signature bytes, do so now. */
00338    if (png_ptr->sig_bytes < 8)
00339    {
00340       png_size_t num_checked = png_ptr->sig_bytes,
00341                  num_to_check = 8 - num_checked;
00342 
00343       png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
00344       png_ptr->sig_bytes = 8;
00345 
00346       if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
00347       {
00348          if (num_checked < 4 &&
00349              png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
00350             png_error(png_ptr, "Not a PNG file");
00351          else
00352             png_error(png_ptr, "PNG file corrupted by ASCII conversion");
00353       }
00354       if (num_checked < 3)
00355          png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
00356    }
00357 
00358    for (;;)
00359    {
00360 #ifdef PNG_USE_LOCAL_ARRAYS
00361       PNG_CONST PNG_IHDR;
00362       PNG_CONST PNG_IDAT;
00363       PNG_CONST PNG_IEND;
00364       PNG_CONST PNG_PLTE;
00365 #if defined(PNG_READ_bKGD_SUPPORTED)
00366       PNG_CONST PNG_bKGD;
00367 #endif
00368 #if defined(PNG_READ_cHRM_SUPPORTED)
00369       PNG_CONST PNG_cHRM;
00370 #endif
00371 #if defined(PNG_READ_gAMA_SUPPORTED)
00372       PNG_CONST PNG_gAMA;
00373 #endif
00374 #if defined(PNG_READ_hIST_SUPPORTED)
00375       PNG_CONST PNG_hIST;
00376 #endif
00377 #if defined(PNG_READ_iCCP_SUPPORTED)
00378       PNG_CONST PNG_iCCP;
00379 #endif
00380 #if defined(PNG_READ_iTXt_SUPPORTED)
00381       PNG_CONST PNG_iTXt;
00382 #endif
00383 #if defined(PNG_READ_oFFs_SUPPORTED)
00384       PNG_CONST PNG_oFFs;
00385 #endif
00386 #if defined(PNG_READ_pCAL_SUPPORTED)
00387       PNG_CONST PNG_pCAL;
00388 #endif
00389 #if defined(PNG_READ_pHYs_SUPPORTED)
00390       PNG_CONST PNG_pHYs;
00391 #endif
00392 #if defined(PNG_READ_sBIT_SUPPORTED)
00393       PNG_CONST PNG_sBIT;
00394 #endif
00395 #if defined(PNG_READ_sCAL_SUPPORTED)
00396       PNG_CONST PNG_sCAL;
00397 #endif
00398 #if defined(PNG_READ_sPLT_SUPPORTED)
00399       PNG_CONST PNG_sPLT;
00400 #endif
00401 #if defined(PNG_READ_sRGB_SUPPORTED)
00402       PNG_CONST PNG_sRGB;
00403 #endif
00404 #if defined(PNG_READ_tEXt_SUPPORTED)
00405       PNG_CONST PNG_tEXt;
00406 #endif
00407 #if defined(PNG_READ_tIME_SUPPORTED)
00408       PNG_CONST PNG_tIME;
00409 #endif
00410 #if defined(PNG_READ_tRNS_SUPPORTED)
00411       PNG_CONST PNG_tRNS;
00412 #endif
00413 #if defined(PNG_READ_zTXt_SUPPORTED)
00414       PNG_CONST PNG_zTXt;
00415 #endif
00416 #endif /* PNG_USE_LOCAL_ARRAYS */
00417       png_uint_32 length = png_read_chunk_header(png_ptr);
00418       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
00419 
00420       /* This should be a binary subdivision search or a hash for
00421        * matching the chunk name rather than a linear search.
00422        */
00423       if (!png_memcmp(chunk_name, png_IDAT, 4))
00424         if (png_ptr->mode & PNG_AFTER_IDAT)
00425           png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
00426 
00427       if (!png_memcmp(chunk_name, png_IHDR, 4))
00428          png_handle_IHDR(png_ptr, info_ptr, length);
00429       else if (!png_memcmp(chunk_name, png_IEND, 4))
00430          png_handle_IEND(png_ptr, info_ptr, length);
00431 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00432       else if (png_handle_as_unknown(png_ptr, chunk_name))
00433       {
00434          if (!png_memcmp(chunk_name, png_IDAT, 4))
00435             png_ptr->mode |= PNG_HAVE_IDAT;
00436          png_handle_unknown(png_ptr, info_ptr, length);
00437          if (!png_memcmp(chunk_name, png_PLTE, 4))
00438             png_ptr->mode |= PNG_HAVE_PLTE;
00439          else if (!png_memcmp(chunk_name, png_IDAT, 4))
00440          {
00441             if (!(png_ptr->mode & PNG_HAVE_IHDR))
00442                png_error(png_ptr, "Missing IHDR before IDAT");
00443             else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00444                      !(png_ptr->mode & PNG_HAVE_PLTE))
00445                png_error(png_ptr, "Missing PLTE before IDAT");
00446             break;
00447          }
00448       }
00449 #endif
00450       else if (!png_memcmp(chunk_name, png_PLTE, 4))
00451          png_handle_PLTE(png_ptr, info_ptr, length);
00452       else if (!png_memcmp(chunk_name, png_IDAT, 4))
00453       {
00454          if (!(png_ptr->mode & PNG_HAVE_IHDR))
00455             png_error(png_ptr, "Missing IHDR before IDAT");
00456          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
00457                   !(png_ptr->mode & PNG_HAVE_PLTE))
00458             png_error(png_ptr, "Missing PLTE before IDAT");
00459 
00460          png_ptr->idat_size = length;
00461          png_ptr->mode |= PNG_HAVE_IDAT;
00462          break;
00463       }
00464 #if defined(PNG_READ_bKGD_SUPPORTED)
00465       else if (!png_memcmp(chunk_name, png_bKGD, 4))
00466          png_handle_bKGD(png_ptr, info_ptr, length);
00467 #endif
00468 #if defined(PNG_READ_cHRM_SUPPORTED)
00469       else if (!png_memcmp(chunk_name, png_cHRM, 4))
00470          png_handle_cHRM(png_ptr, info_ptr, length);
00471 #endif
00472 #if defined(PNG_READ_gAMA_SUPPORTED)
00473       else if (!png_memcmp(chunk_name, png_gAMA, 4))
00474          png_handle_gAMA(png_ptr, info_ptr, length);
00475 #endif
00476 #if defined(PNG_READ_hIST_SUPPORTED)
00477       else if (!png_memcmp(chunk_name, png_hIST, 4))
00478          png_handle_hIST(png_ptr, info_ptr, length);
00479 #endif
00480 #if defined(PNG_READ_oFFs_SUPPORTED)
00481       else if (!png_memcmp(chunk_name, png_oFFs, 4))
00482          png_handle_oFFs(png_ptr, info_ptr, length);
00483 #endif
00484 #if defined(PNG_READ_pCAL_SUPPORTED)
00485       else if (!png_memcmp(chunk_name, png_pCAL, 4))
00486          png_handle_pCAL(png_ptr, info_ptr, length);
00487 #endif
00488 #if defined(PNG_READ_sCAL_SUPPORTED)
00489       else if (!png_memcmp(chunk_name, png_sCAL, 4))
00490          png_handle_sCAL(png_ptr, info_ptr, length);
00491 #endif
00492 #if defined(PNG_READ_pHYs_SUPPORTED)
00493       else if (!png_memcmp(chunk_name, png_pHYs, 4))
00494          png_handle_pHYs(png_ptr, info_ptr, length);
00495 #endif
00496 #if defined(PNG_READ_sBIT_SUPPORTED)
00497       else if (!png_memcmp(chunk_name, png_sBIT, 4))
00498          png_handle_sBIT(png_ptr, info_ptr, length);
00499 #endif
00500 #if defined(PNG_READ_sRGB_SUPPORTED)
00501       else if (!png_memcmp(chunk_name, png_sRGB, 4))
00502          png_handle_sRGB(png_ptr, info_ptr, length);
00503 #endif
00504 #if defined(PNG_READ_iCCP_SUPPORTED)
00505       else if (!png_memcmp(chunk_name, png_iCCP, 4))
00506          png_handle_iCCP(png_ptr, info_ptr, length);
00507 #endif
00508 #if defined(PNG_READ_sPLT_SUPPORTED)
00509       else if (!png_memcmp(chunk_name, png_sPLT, 4))
00510          png_handle_sPLT(png_ptr, info_ptr, length);
00511 #endif
00512 #if defined(PNG_READ_tEXt_SUPPORTED)
00513       else if (!png_memcmp(chunk_name, png_tEXt, 4))
00514          png_handle_tEXt(png_ptr, info_ptr, length);
00515 #endif
00516 #if defined(PNG_READ_tIME_SUPPORTED)
00517       else if (!png_memcmp(chunk_name, png_tIME, 4))
00518          png_handle_tIME(png_ptr, info_ptr, length);
00519 #endif
00520 #if defined(PNG_READ_tRNS_SUPPORTED)
00521       else if (!png_memcmp(chunk_name, png_tRNS, 4))
00522          png_handle_tRNS(png_ptr, info_ptr, length);
00523 #endif
00524 #if defined(PNG_READ_zTXt_SUPPORTED)
00525       else if (!png_memcmp(chunk_name, png_zTXt, 4))
00526          png_handle_zTXt(png_ptr, info_ptr, length);
00527 #endif
00528 #if defined(PNG_READ_iTXt_SUPPORTED)
00529       else if (!png_memcmp(chunk_name, png_iTXt, 4))
00530          png_handle_iTXt(png_ptr, info_ptr, length);
00531 #endif
00532       else
00533          png_handle_unknown(png_ptr, info_ptr, length);
00534    }
00535 }
00536 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
00537 
00538 /* Optional call to update the users info_ptr structure */
00539 void PNGAPI
00540 png_read_update_info(png_structp png_ptr, png_infop info_ptr)
00541 {
00542    png_debug(1, "in png_read_update_info");
00543    if (png_ptr == NULL)
00544       return;
00545    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
00546       png_read_start_row(png_ptr);
00547    else
00548       png_warning(png_ptr,
00549       "Ignoring extra png_read_update_info() call; row buffer not reallocated");
00550    png_read_transform_info(png_ptr, info_ptr);
00551 }
00552 
00553 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00554 /* Initialize palette, background, etc, after transformations
00555  * are set, but before any reading takes place.  This allows
00556  * the user to obtain a gamma-corrected palette, for example.
00557  * If the user doesn't call this, we will do it ourselves.
00558  */
00559 void PNGAPI
00560 png_start_read_image(png_structp png_ptr)
00561 {
00562    png_debug(1, "in png_start_read_image");
00563    if (png_ptr == NULL)
00564       return;
00565    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
00566       png_read_start_row(png_ptr);
00567 }
00568 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
00569 
00570 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00571 void PNGAPI
00572 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
00573 {
00574 #ifdef PNG_USE_LOCAL_ARRAYS
00575    PNG_CONST PNG_IDAT;
00576    PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
00577       0xff};
00578    PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
00579 #endif
00580    int ret;
00581    if (png_ptr == NULL)
00582       return;
00583    png_debug2(1, "in png_read_row (row %lu, pass %d)",
00584       png_ptr->row_number, png_ptr->pass);
00585    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
00586       png_read_start_row(png_ptr);
00587    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
00588    {
00589    /* Check for transforms that have been set but were defined out */
00590 #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
00591    if (png_ptr->transformations & PNG_INVERT_MONO)
00592       png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
00593 #endif
00594 #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
00595    if (png_ptr->transformations & PNG_FILLER)
00596       png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
00597 #endif
00598 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
00599    if (png_ptr->transformations & PNG_PACKSWAP)
00600       png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
00601 #endif
00602 #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
00603    if (png_ptr->transformations & PNG_PACK)
00604       png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
00605 #endif
00606 #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
00607    if (png_ptr->transformations & PNG_SHIFT)
00608       png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
00609 #endif
00610 #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
00611    if (png_ptr->transformations & PNG_BGR)
00612       png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
00613 #endif
00614 #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
00615    if (png_ptr->transformations & PNG_SWAP_BYTES)
00616       png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
00617 #endif
00618    }
00619 
00620 #if defined(PNG_READ_INTERLACING_SUPPORTED)
00621    /* If interlaced and we do not need a new row, combine row and return */
00622    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
00623    {
00624       switch (png_ptr->pass)
00625       {
00626          case 0:
00627             if (png_ptr->row_number & 0x07)
00628             {
00629                if (dsp_row != NULL)
00630                   png_combine_row(png_ptr, dsp_row,
00631                      png_pass_dsp_mask[png_ptr->pass]);
00632                png_read_finish_row(png_ptr);
00633                return;
00634             }
00635             break;
00636          case 1:
00637             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
00638             {
00639                if (dsp_row != NULL)
00640                   png_combine_row(png_ptr, dsp_row,
00641                      png_pass_dsp_mask[png_ptr->pass]);
00642                png_read_finish_row(png_ptr);
00643                return;
00644             }
00645             break;
00646          case 2:
00647             if ((png_ptr->row_number & 0x07) != 4)
00648             {
00649                if (dsp_row != NULL && (png_ptr->row_number & 4))
00650                   png_combine_row(png_ptr, dsp_row,
00651                      png_pass_dsp_mask[png_ptr->pass]);
00652                png_read_finish_row(png_ptr);
00653                return;
00654             }
00655             break;
00656          case 3:
00657             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
00658             {
00659                if (dsp_row != NULL)
00660                   png_combine_row(png_ptr, dsp_row,
00661                      png_pass_dsp_mask[png_ptr->pass]);
00662                png_read_finish_row(png_ptr);
00663                return;
00664             }
00665             break;
00666          case 4:
00667             if ((png_ptr->row_number & 3) != 2)
00668             {
00669                if (dsp_row != NULL && (png_ptr->row_number & 2))
00670                   png_combine_row(png_ptr, dsp_row,
00671                      png_pass_dsp_mask[png_ptr->pass]);
00672                png_read_finish_row(png_ptr);
00673                return;
00674             }
00675             break;
00676          case 5:
00677             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
00678             {
00679                if (dsp_row != NULL)
00680                   png_combine_row(png_ptr, dsp_row,
00681                      png_pass_dsp_mask[png_ptr->pass]);
00682                png_read_finish_row(png_ptr);
00683                return;
00684             }
00685             break;
00686          case 6:
00687             if (!(png_ptr->row_number & 1))
00688             {
00689                png_read_finish_row(png_ptr);
00690                return;
00691             }
00692             break;
00693       }
00694    }
00695 #endif
00696 
00697    if (!(png_ptr->mode & PNG_HAVE_IDAT))
00698       png_error(png_ptr, "Invalid attempt to read row data");
00699 
00700    png_ptr->zstream.next_out = png_ptr->row_buf;
00701    png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
00702    do
00703    {
00704       if (!(png_ptr->zstream.avail_in))
00705       {
00706          while (!png_ptr->idat_size)
00707          {
00708             png_crc_finish(png_ptr, 0);
00709 
00710             png_ptr->idat_size = png_read_chunk_header(png_ptr);
00711             if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
00712                png_error(png_ptr, "Not enough image data");
00713          }
00714          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
00715          png_ptr->zstream.next_in = png_ptr->zbuf;
00716          if (png_ptr->zbuf_size > png_ptr->idat_size)
00717             png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
00718          png_crc_read(png_ptr, png_ptr->zbuf,
00719             (png_size_t)png_ptr->zstream.avail_in);
00720          png_ptr->idat_size -= png_ptr->zstream.avail_in;
00721       }
00722       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
00723       if (ret == Z_STREAM_END)
00724       {
00725          if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
00726             png_ptr->idat_size)
00727             png_error(png_ptr, "Extra compressed data");
00728          png_ptr->mode |= PNG_AFTER_IDAT;
00729          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
00730          break;
00731       }
00732       if (ret != Z_OK)
00733          png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
00734                    "Decompression error");
00735 
00736    } while (png_ptr->zstream.avail_out);
00737 
00738    png_ptr->row_info.color_type = png_ptr->color_type;
00739    png_ptr->row_info.width = png_ptr->iwidth;
00740    png_ptr->row_info.channels = png_ptr->channels;
00741    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
00742    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
00743    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
00744        png_ptr->row_info.width);
00745 
00746    if (png_ptr->row_buf[0])
00747    png_read_filter_row(png_ptr, &(png_ptr->row_info),
00748       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
00749       (int)(png_ptr->row_buf[0]));
00750 
00751    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
00752       png_ptr->rowbytes + 1);
00753 
00754 #if defined(PNG_MNG_FEATURES_SUPPORTED)
00755    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
00756       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
00757    {
00758       /* Intrapixel differencing */
00759       png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
00760    }
00761 #endif
00762 
00763 
00764    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
00765       png_do_read_transformations(png_ptr);
00766 
00767 #if defined(PNG_READ_INTERLACING_SUPPORTED)
00768    /* Blow up interlaced rows to full size */
00769    if (png_ptr->interlaced &&
00770       (png_ptr->transformations & PNG_INTERLACE))
00771    {
00772       if (png_ptr->pass < 6)
00773          /* Old interface (pre-1.0.9):
00774           * png_do_read_interlace(&(png_ptr->row_info),
00775           *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
00776           */
00777          png_do_read_interlace(png_ptr);
00778 
00779       if (dsp_row != NULL)
00780          png_combine_row(png_ptr, dsp_row,
00781             png_pass_dsp_mask[png_ptr->pass]);
00782       if (row != NULL)
00783          png_combine_row(png_ptr, row,
00784             png_pass_mask[png_ptr->pass]);
00785    }
00786    else
00787 #endif
00788    {
00789       if (row != NULL)
00790          png_combine_row(png_ptr, row, 0xff);
00791       if (dsp_row != NULL)
00792          png_combine_row(png_ptr, dsp_row, 0xff);
00793    }
00794    png_read_finish_row(png_ptr);
00795 
00796    if (png_ptr->read_row_fn != NULL)
00797       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
00798 }
00799 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
00800 
00801 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00802 /* Read one or more rows of image data.  If the image is interlaced,
00803  * and png_set_interlace_handling() has been called, the rows need to
00804  * contain the contents of the rows from the previous pass.  If the
00805  * image has alpha or transparency, and png_handle_alpha()[*] has been
00806  * called, the rows contents must be initialized to the contents of the
00807  * screen.
00808  *
00809  * "row" holds the actual image, and pixels are placed in it
00810  * as they arrive.  If the image is displayed after each pass, it will
00811  * appear to "sparkle" in.  "display_row" can be used to display a
00812  * "chunky" progressive image, with finer detail added as it becomes
00813  * available.  If you do not want this "chunky" display, you may pass
00814  * NULL for display_row.  If you do not want the sparkle display, and
00815  * you have not called png_handle_alpha(), you may pass NULL for rows.
00816  * If you have called png_handle_alpha(), and the image has either an
00817  * alpha channel or a transparency chunk, you must provide a buffer for
00818  * rows.  In this case, you do not have to provide a display_row buffer
00819  * also, but you may.  If the image is not interlaced, or if you have
00820  * not called png_set_interlace_handling(), the display_row buffer will
00821  * be ignored, so pass NULL to it.
00822  *
00823  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
00824  */
00825 
00826 void PNGAPI
00827 png_read_rows(png_structp png_ptr, png_bytepp row,
00828    png_bytepp display_row, png_uint_32 num_rows)
00829 {
00830    png_uint_32 i;
00831    png_bytepp rp;
00832    png_bytepp dp;
00833 
00834    png_debug(1, "in png_read_rows");
00835    if (png_ptr == NULL)
00836       return;
00837    rp = row;
00838    dp = display_row;
00839    if (rp != NULL && dp != NULL)
00840       for (i = 0; i < num_rows; i++)
00841       {
00842          png_bytep rptr = *rp++;
00843          png_bytep dptr = *dp++;
00844 
00845          png_read_row(png_ptr, rptr, dptr);
00846       }
00847    else if (rp != NULL)
00848       for (i = 0; i < num_rows; i++)
00849       {
00850          png_bytep rptr = *rp;
00851          png_read_row(png_ptr, rptr, png_bytep_NULL);
00852          rp++;
00853       }
00854    else if (dp != NULL)
00855       for (i = 0; i < num_rows; i++)
00856       {
00857          png_bytep dptr = *dp;
00858          png_read_row(png_ptr, png_bytep_NULL, dptr);
00859          dp++;
00860       }
00861 }
00862 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
00863 
00864 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00865 /* Read the entire image.  If the image has an alpha channel or a tRNS
00866  * chunk, and you have called png_handle_alpha()[*], you will need to
00867  * initialize the image to the current image that PNG will be overlaying.
00868  * We set the num_rows again here, in case it was incorrectly set in
00869  * png_read_start_row() by a call to png_read_update_info() or
00870  * png_start_read_image() if png_set_interlace_handling() wasn't called
00871  * prior to either of these functions like it should have been.  You can
00872  * only call this function once.  If you desire to have an image for
00873  * each pass of a interlaced image, use png_read_rows() instead.
00874  *
00875  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
00876  */
00877 void PNGAPI
00878 png_read_image(png_structp png_ptr, png_bytepp image)
00879 {
00880    png_uint_32 i, image_height;
00881    int pass, j;
00882    png_bytepp rp;
00883 
00884    png_debug(1, "in png_read_image");
00885    if (png_ptr == NULL)
00886       return;
00887 
00888 #ifdef PNG_READ_INTERLACING_SUPPORTED
00889    pass = png_set_interlace_handling(png_ptr);
00890 #else
00891    if (png_ptr->interlaced)
00892       png_error(png_ptr,
00893         "Cannot read interlaced image -- interlace handler disabled.");
00894    pass = 1;
00895 #endif
00896 
00897 
00898    image_height=png_ptr->height;
00899    png_ptr->num_rows = image_height; /* Make sure this is set correctly */
00900 
00901    for (j = 0; j < pass; j++)
00902    {
00903       rp = image;
00904       for (i = 0; i < image_height; i++)
00905       {
00906          png_read_row(png_ptr, *rp, png_bytep_NULL);
00907          rp++;
00908       }
00909    }
00910 }
00911 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
00912 
00913 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
00914 /* Read the end of the PNG file.  Will not read past the end of the
00915  * file, will verify the end is accurate, and will read any comments
00916  * or time information at the end of the file, if info is not NULL.
00917  */
00918 void PNGAPI
00919 png_read_end(png_structp png_ptr, png_infop info_ptr)
00920 {
00921    png_debug(1, "in png_read_end");
00922    if (png_ptr == NULL)
00923       return;
00924    png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
00925 
00926    do
00927    {
00928 #ifdef PNG_USE_LOCAL_ARRAYS
00929       PNG_CONST PNG_IHDR;
00930       PNG_CONST PNG_IDAT;
00931       PNG_CONST PNG_IEND;
00932       PNG_CONST PNG_PLTE;
00933 #if defined(PNG_READ_bKGD_SUPPORTED)
00934       PNG_CONST PNG_bKGD;
00935 #endif
00936 #if defined(PNG_READ_cHRM_SUPPORTED)
00937       PNG_CONST PNG_cHRM;
00938 #endif
00939 #if defined(PNG_READ_gAMA_SUPPORTED)
00940       PNG_CONST PNG_gAMA;
00941 #endif
00942 #if defined(PNG_READ_hIST_SUPPORTED)
00943       PNG_CONST PNG_hIST;
00944 #endif
00945 #if defined(PNG_READ_iCCP_SUPPORTED)
00946       PNG_CONST PNG_iCCP;
00947 #endif
00948 #if defined(PNG_READ_iTXt_SUPPORTED)
00949       PNG_CONST PNG_iTXt;
00950 #endif
00951 #if defined(PNG_READ_oFFs_SUPPORTED)
00952       PNG_CONST PNG_oFFs;
00953 #endif
00954 #if defined(PNG_READ_pCAL_SUPPORTED)
00955       PNG_CONST PNG_pCAL;
00956 #endif
00957 #if defined(PNG_READ_pHYs_SUPPORTED)
00958       PNG_CONST PNG_pHYs;
00959 #endif
00960 #if defined(PNG_READ_sBIT_SUPPORTED)
00961       PNG_CONST PNG_sBIT;
00962 #endif
00963 #if defined(PNG_READ_sCAL_SUPPORTED)
00964       PNG_CONST PNG_sCAL;
00965 #endif
00966 #if defined(PNG_READ_sPLT_SUPPORTED)
00967       PNG_CONST PNG_sPLT;
00968 #endif
00969 #if defined(PNG_READ_sRGB_SUPPORTED)
00970       PNG_CONST PNG_sRGB;
00971 #endif
00972 #if defined(PNG_READ_tEXt_SUPPORTED)
00973       PNG_CONST PNG_tEXt;
00974 #endif
00975 #if defined(PNG_READ_tIME_SUPPORTED)
00976       PNG_CONST PNG_tIME;
00977 #endif
00978 #if defined(PNG_READ_tRNS_SUPPORTED)
00979       PNG_CONST PNG_tRNS;
00980 #endif
00981 #if defined(PNG_READ_zTXt_SUPPORTED)
00982       PNG_CONST PNG_zTXt;
00983 #endif
00984 #endif /* PNG_USE_LOCAL_ARRAYS */
00985       png_uint_32 length = png_read_chunk_header(png_ptr);
00986       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
00987 
00988       if (!png_memcmp(chunk_name, png_IHDR, 4))
00989          png_handle_IHDR(png_ptr, info_ptr, length);
00990       else if (!png_memcmp(chunk_name, png_IEND, 4))
00991          png_handle_IEND(png_ptr, info_ptr, length);
00992 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
00993       else if (png_handle_as_unknown(png_ptr, chunk_name))
00994       {
00995          if (!png_memcmp(chunk_name, png_IDAT, 4))
00996          {
00997             if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
00998                png_error(png_ptr, "Too many IDAT's found");
00999          }
01000          png_handle_unknown(png_ptr, info_ptr, length);
01001          if (!png_memcmp(chunk_name, png_PLTE, 4))
01002             png_ptr->mode |= PNG_HAVE_PLTE;
01003       }
01004 #endif
01005       else if (!png_memcmp(chunk_name, png_IDAT, 4))
01006       {
01007          /* Zero length IDATs are legal after the last IDAT has been
01008           * read, but not after other chunks have been read.
01009           */
01010          if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
01011             png_error(png_ptr, "Too many IDAT's found");
01012          png_crc_finish(png_ptr, length);
01013       }
01014       else if (!png_memcmp(chunk_name, png_PLTE, 4))
01015          png_handle_PLTE(png_ptr, info_ptr, length);
01016 #if defined(PNG_READ_bKGD_SUPPORTED)
01017       else if (!png_memcmp(chunk_name, png_bKGD, 4))
01018          png_handle_bKGD(png_ptr, info_ptr, length);
01019 #endif
01020 #if defined(PNG_READ_cHRM_SUPPORTED)
01021       else if (!png_memcmp(chunk_name, png_cHRM, 4))
01022          png_handle_cHRM(png_ptr, info_ptr, length);
01023 #endif
01024 #if defined(PNG_READ_gAMA_SUPPORTED)
01025       else if (!png_memcmp(chunk_name, png_gAMA, 4))
01026          png_handle_gAMA(png_ptr, info_ptr, length);
01027 #endif
01028 #if defined(PNG_READ_hIST_SUPPORTED)
01029       else if (!png_memcmp(chunk_name, png_hIST, 4))
01030          png_handle_hIST(png_ptr, info_ptr, length);
01031 #endif
01032 #if defined(PNG_READ_oFFs_SUPPORTED)
01033       else if (!png_memcmp(chunk_name, png_oFFs, 4))
01034          png_handle_oFFs(png_ptr, info_ptr, length);
01035 #endif
01036 #if defined(PNG_READ_pCAL_SUPPORTED)
01037       else if (!png_memcmp(chunk_name, png_pCAL, 4))
01038          png_handle_pCAL(png_ptr, info_ptr, length);
01039 #endif
01040 #if defined(PNG_READ_sCAL_SUPPORTED)
01041       else if (!png_memcmp(chunk_name, png_sCAL, 4))
01042          png_handle_sCAL(png_ptr, info_ptr, length);
01043 #endif
01044 #if defined(PNG_READ_pHYs_SUPPORTED)
01045       else if (!png_memcmp(chunk_name, png_pHYs, 4))
01046          png_handle_pHYs(png_ptr, info_ptr, length);
01047 #endif
01048 #if defined(PNG_READ_sBIT_SUPPORTED)
01049       else if (!png_memcmp(chunk_name, png_sBIT, 4))
01050          png_handle_sBIT(png_ptr, info_ptr, length);
01051 #endif
01052 #if defined(PNG_READ_sRGB_SUPPORTED)
01053       else if (!png_memcmp(chunk_name, png_sRGB, 4))
01054          png_handle_sRGB(png_ptr, info_ptr, length);
01055 #endif
01056 #if defined(PNG_READ_iCCP_SUPPORTED)
01057       else if (!png_memcmp(chunk_name, png_iCCP, 4))
01058          png_handle_iCCP(png_ptr, info_ptr, length);
01059 #endif
01060 #if defined(PNG_READ_sPLT_SUPPORTED)
01061       else if (!png_memcmp(chunk_name, png_sPLT, 4))
01062          png_handle_sPLT(png_ptr, info_ptr, length);
01063 #endif
01064 #if defined(PNG_READ_tEXt_SUPPORTED)
01065       else if (!png_memcmp(chunk_name, png_tEXt, 4))
01066          png_handle_tEXt(png_ptr, info_ptr, length);
01067 #endif
01068 #if defined(PNG_READ_tIME_SUPPORTED)
01069       else if (!png_memcmp(chunk_name, png_tIME, 4))
01070          png_handle_tIME(png_ptr, info_ptr, length);
01071 #endif
01072 #if defined(PNG_READ_tRNS_SUPPORTED)
01073       else if (!png_memcmp(chunk_name, png_tRNS, 4))
01074          png_handle_tRNS(png_ptr, info_ptr, length);
01075 #endif
01076 #if defined(PNG_READ_zTXt_SUPPORTED)
01077       else if (!png_memcmp(chunk_name, png_zTXt, 4))
01078          png_handle_zTXt(png_ptr, info_ptr, length);
01079 #endif
01080 #if defined(PNG_READ_iTXt_SUPPORTED)
01081       else if (!png_memcmp(chunk_name, png_iTXt, 4))
01082          png_handle_iTXt(png_ptr, info_ptr, length);
01083 #endif
01084       else
01085          png_handle_unknown(png_ptr, info_ptr, length);
01086    } while (!(png_ptr->mode & PNG_HAVE_IEND));
01087 }
01088 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
01089 
01090 /* Free all memory used by the read */
01091 void PNGAPI
01092 png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
01093    png_infopp end_info_ptr_ptr)
01094 {
01095    png_structp png_ptr = NULL;
01096    png_infop info_ptr = NULL, end_info_ptr = NULL;
01097 #ifdef PNG_USER_MEM_SUPPORTED
01098    png_free_ptr free_fn = NULL;
01099    png_voidp mem_ptr = NULL;
01100 #endif
01101 
01102    png_debug(1, "in png_destroy_read_struct");
01103    if (png_ptr_ptr != NULL)
01104       png_ptr = *png_ptr_ptr;
01105    if (png_ptr == NULL)
01106       return;
01107 
01108 #ifdef PNG_USER_MEM_SUPPORTED
01109    free_fn = png_ptr->free_fn;
01110    mem_ptr = png_ptr->mem_ptr;
01111 #endif
01112 
01113    if (info_ptr_ptr != NULL)
01114       info_ptr = *info_ptr_ptr;
01115 
01116    if (end_info_ptr_ptr != NULL)
01117       end_info_ptr = *end_info_ptr_ptr;
01118 
01119    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
01120 
01121    if (info_ptr != NULL)
01122    {
01123 #if defined(PNG_TEXT_SUPPORTED)
01124       png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
01125 #endif
01126 
01127 #ifdef PNG_USER_MEM_SUPPORTED
01128       png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
01129           (png_voidp)mem_ptr);
01130 #else
01131       png_destroy_struct((png_voidp)info_ptr);
01132 #endif
01133       *info_ptr_ptr = NULL;
01134    }
01135 
01136    if (end_info_ptr != NULL)
01137    {
01138 #if defined(PNG_READ_TEXT_SUPPORTED)
01139       png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
01140 #endif
01141 #ifdef PNG_USER_MEM_SUPPORTED
01142       png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
01143          (png_voidp)mem_ptr);
01144 #else
01145       png_destroy_struct((png_voidp)end_info_ptr);
01146 #endif
01147       *end_info_ptr_ptr = NULL;
01148    }
01149 
01150    if (png_ptr != NULL)
01151    {
01152 #ifdef PNG_USER_MEM_SUPPORTED
01153       png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
01154           (png_voidp)mem_ptr);
01155 #else
01156       png_destroy_struct((png_voidp)png_ptr);
01157 #endif
01158       *png_ptr_ptr = NULL;
01159    }
01160 }
01161 
01162 /* Free all memory used by the read (old method) */
01163 void /* PRIVATE */
01164 png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
01165 {
01166 #ifdef PNG_SETJMP_SUPPORTED
01167    jmp_buf tmp_jmp;
01168 #endif
01169    png_error_ptr error_fn;
01170    png_error_ptr warning_fn;
01171    png_voidp error_ptr;
01172 #ifdef PNG_USER_MEM_SUPPORTED
01173    png_free_ptr free_fn;
01174 #endif
01175 
01176    png_debug(1, "in png_read_destroy");
01177    if (info_ptr != NULL)
01178       png_info_destroy(png_ptr, info_ptr);
01179 
01180    if (end_info_ptr != NULL)
01181       png_info_destroy(png_ptr, end_info_ptr);
01182 
01183    png_free(png_ptr, png_ptr->zbuf);
01184    png_free(png_ptr, png_ptr->big_row_buf);
01185    png_free(png_ptr, png_ptr->prev_row);
01186    png_free(png_ptr, png_ptr->chunkdata);
01187 #if defined(PNG_READ_DITHER_SUPPORTED)
01188    png_free(png_ptr, png_ptr->palette_lookup);
01189    png_free(png_ptr, png_ptr->dither_index);
01190 #endif
01191 #if defined(PNG_READ_GAMMA_SUPPORTED)
01192    png_free(png_ptr, png_ptr->gamma_table);
01193 #endif
01194 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01195    png_free(png_ptr, png_ptr->gamma_from_1);
01196    png_free(png_ptr, png_ptr->gamma_to_1);
01197 #endif
01198 #ifdef PNG_FREE_ME_SUPPORTED
01199    if (png_ptr->free_me & PNG_FREE_PLTE)
01200       png_zfree(png_ptr, png_ptr->palette);
01201    png_ptr->free_me &= ~PNG_FREE_PLTE;
01202 #else
01203    if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
01204       png_zfree(png_ptr, png_ptr->palette);
01205    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
01206 #endif
01207 #if defined(PNG_tRNS_SUPPORTED) || \
01208     defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
01209 #ifdef PNG_FREE_ME_SUPPORTED
01210    if (png_ptr->free_me & PNG_FREE_TRNS)
01211       png_free(png_ptr, png_ptr->trans);
01212    png_ptr->free_me &= ~PNG_FREE_TRNS;
01213 #else
01214    if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
01215       png_free(png_ptr, png_ptr->trans);
01216    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
01217 #endif
01218 #endif
01219 #if defined(PNG_READ_hIST_SUPPORTED)
01220 #ifdef PNG_FREE_ME_SUPPORTED
01221    if (png_ptr->free_me & PNG_FREE_HIST)
01222       png_free(png_ptr, png_ptr->hist);
01223    png_ptr->free_me &= ~PNG_FREE_HIST;
01224 #else
01225    if (png_ptr->flags & PNG_FLAG_FREE_HIST)
01226       png_free(png_ptr, png_ptr->hist);
01227    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
01228 #endif
01229 #endif
01230 #if defined(PNG_READ_GAMMA_SUPPORTED)
01231    if (png_ptr->gamma_16_table != NULL)
01232    {
01233       int i;
01234       int istop = (1 << (8 - png_ptr->gamma_shift));
01235       for (i = 0; i < istop; i++)
01236       {
01237          png_free(png_ptr, png_ptr->gamma_16_table[i]);
01238       }
01239    png_free(png_ptr, png_ptr->gamma_16_table);
01240    }
01241 #if defined(PNG_READ_BACKGROUND_SUPPORTED)
01242    if (png_ptr->gamma_16_from_1 != NULL)
01243    {
01244       int i;
01245       int istop = (1 << (8 - png_ptr->gamma_shift));
01246       for (i = 0; i < istop; i++)
01247       {
01248          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
01249       }
01250    png_free(png_ptr, png_ptr->gamma_16_from_1);
01251    }
01252    if (png_ptr->gamma_16_to_1 != NULL)
01253    {
01254       int i;
01255       int istop = (1 << (8 - png_ptr->gamma_shift));
01256       for (i = 0; i < istop; i++)
01257       {
01258          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
01259       }
01260    png_free(png_ptr, png_ptr->gamma_16_to_1);
01261    }
01262 #endif
01263 #endif
01264 #if defined(PNG_TIME_RFC1123_SUPPORTED)
01265    png_free(png_ptr, png_ptr->time_buffer);
01266 #endif
01267 
01268    inflateEnd(&png_ptr->zstream);
01269 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
01270    png_free(png_ptr, png_ptr->save_buffer);
01271 #endif
01272 
01273 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
01274 #ifdef PNG_TEXT_SUPPORTED
01275    png_free(png_ptr, png_ptr->current_text);
01276 #endif /* PNG_TEXT_SUPPORTED */
01277 #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
01278 
01279    /* Save the important info out of the png_struct, in case it is
01280     * being used again.
01281     */
01282 #ifdef PNG_SETJMP_SUPPORTED
01283    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
01284 #endif
01285 
01286    error_fn = png_ptr->error_fn;
01287    warning_fn = png_ptr->warning_fn;
01288    error_ptr = png_ptr->error_ptr;
01289 #ifdef PNG_USER_MEM_SUPPORTED
01290    free_fn = png_ptr->free_fn;
01291 #endif
01292 
01293    png_memset(png_ptr, 0, png_sizeof(png_struct));
01294 
01295    png_ptr->error_fn = error_fn;
01296    png_ptr->warning_fn = warning_fn;
01297    png_ptr->error_ptr = error_ptr;
01298 #ifdef PNG_USER_MEM_SUPPORTED
01299    png_ptr->free_fn = free_fn;
01300 #endif
01301 
01302 #ifdef PNG_SETJMP_SUPPORTED
01303    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
01304 #endif
01305 
01306 }
01307 
01308 void PNGAPI
01309 png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
01310 {
01311    if (png_ptr == NULL)
01312       return;
01313    png_ptr->read_row_fn = read_row_fn;
01314 }
01315 
01316 
01317 #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
01318 #if defined(PNG_INFO_IMAGE_SUPPORTED)
01319 void PNGAPI
01320 png_read_png(png_structp png_ptr, png_infop info_ptr,
01321                            int transforms,
01322                            voidp params)
01323 {
01324    int row;
01325 
01326    if (png_ptr == NULL)
01327       return;
01328 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
01329    /* Invert the alpha channel from opacity to transparency
01330     */
01331    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
01332        png_set_invert_alpha(png_ptr);
01333 #endif
01334 
01335    /* png_read_info() gives us all of the information from the
01336     * PNG file before the first IDAT (image data chunk).
01337     */
01338    png_read_info(png_ptr, info_ptr);
01339    if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
01340       png_error(png_ptr, "Image is too high to process with png_read_png()");
01341 
01342    /* -------------- image transformations start here ------------------- */
01343 
01344 #if defined(PNG_READ_16_TO_8_SUPPORTED)
01345    /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
01346     */
01347    if (transforms & PNG_TRANSFORM_STRIP_16)
01348       png_set_strip_16(png_ptr);
01349 #endif
01350 
01351 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
01352    /* Strip alpha bytes from the input data without combining with
01353     * the background (not recommended).
01354     */
01355    if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
01356       png_set_strip_alpha(png_ptr);
01357 #endif
01358 
01359 #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
01360    /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
01361     * byte into separate bytes (useful for paletted and grayscale images).
01362     */
01363    if (transforms & PNG_TRANSFORM_PACKING)
01364       png_set_packing(png_ptr);
01365 #endif
01366 
01367 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
01368    /* Change the order of packed pixels to least significant bit first
01369     * (not useful if you are using png_set_packing).
01370     */
01371    if (transforms & PNG_TRANSFORM_PACKSWAP)
01372       png_set_packswap(png_ptr);
01373 #endif
01374 
01375 #if defined(PNG_READ_EXPAND_SUPPORTED)
01376    /* Expand paletted colors into true RGB triplets
01377     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
01378     * Expand paletted or RGB images with transparency to full alpha
01379     * channels so the data will be available as RGBA quartets.
01380     */
01381    if (transforms & PNG_TRANSFORM_EXPAND)
01382       if ((png_ptr->bit_depth < 8) ||
01383           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
01384           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
01385          png_set_expand(png_ptr);
01386 #endif
01387 
01388    /* We don't handle background color or gamma transformation or dithering.
01389     */
01390 
01391 #if defined(PNG_READ_INVERT_SUPPORTED)
01392    /* Invert monochrome files to have 0 as white and 1 as black
01393     */
01394    if (transforms & PNG_TRANSFORM_INVERT_MONO)
01395       png_set_invert_mono(png_ptr);
01396 #endif
01397 
01398 #if defined(PNG_READ_SHIFT_SUPPORTED)
01399    /* If you want to shift the pixel values from the range [0,255] or
01400     * [0,65535] to the original [0,7] or [0,31], or whatever range the
01401     * colors were originally in:
01402     */
01403    if ((transforms & PNG_TRANSFORM_SHIFT)
01404        && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
01405    {
01406       png_color_8p sig_bit;
01407 
01408       png_get_sBIT(png_ptr, info_ptr, &sig_bit);
01409       png_set_shift(png_ptr, sig_bit);
01410    }
01411 #endif
01412 
01413 #if defined(PNG_READ_BGR_SUPPORTED)
01414    /* Flip the RGB pixels to BGR (or RGBA to BGRA)
01415     */
01416    if (transforms & PNG_TRANSFORM_BGR)
01417       png_set_bgr(png_ptr);
01418 #endif
01419 
01420 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
01421    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
01422     */
01423    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
01424        png_set_swap_alpha(png_ptr);
01425 #endif
01426 
01427 #if defined(PNG_READ_SWAP_SUPPORTED)
01428    /* Swap bytes of 16 bit files to least significant byte first
01429     */
01430    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
01431       png_set_swap(png_ptr);
01432 #endif
01433 
01434    /* We don't handle adding filler bytes */
01435 
01436    /* Optional call to gamma correct and add the background to the palette
01437     * and update info structure.  REQUIRED if you are expecting libpng to
01438     * update the palette for you (i.e., you selected such a transform above).
01439     */
01440    png_read_update_info(png_ptr, info_ptr);
01441 
01442    /* -------------- image transformations end here ------------------- */
01443 
01444 #ifdef PNG_FREE_ME_SUPPORTED
01445    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
01446 #endif
01447    if (info_ptr->row_pointers == NULL)
01448    {
01449       info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
01450          info_ptr->height * png_sizeof(png_bytep));
01451       png_memset(info_ptr->row_pointers, 0, info_ptr->height
01452          * png_sizeof(png_bytep));
01453 #ifdef PNG_FREE_ME_SUPPORTED
01454       info_ptr->free_me |= PNG_FREE_ROWS;
01455 #endif
01456       for (row = 0; row < (int)info_ptr->height; row++)
01457          info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
01458             png_get_rowbytes(png_ptr, info_ptr));
01459    }
01460 
01461    png_read_image(png_ptr, info_ptr->row_pointers);
01462    info_ptr->valid |= PNG_INFO_IDAT;
01463 
01464    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
01465    png_read_end(png_ptr, info_ptr);
01466 
01467    transforms = transforms; /* Quiet compiler warnings */
01468    params = params;
01469 
01470 }
01471 #endif /* PNG_INFO_IMAGE_SUPPORTED */
01472 #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
01473 #endif /* PNG_READ_SUPPORTED */