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

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

Generated on Fri May 25 2012 04:17:39 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.