graphics

experiments with opengl3.2/ogles3.3 on linux and win7
git clone http://frotz.net/git/graphics.git
Log | Files | Refs

pngread.c (46934B)


      1 
      2 /* pngread.c - read a PNG file
      3  *
      4  * Last changed in libpng 1.2.48 [March 8, 2012]
      5  * Copyright (c) 1998-2012 Glenn Randers-Pehrson
      6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
      7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      8  *
      9  * This code is released under the libpng license.
     10  * For conditions of distribution and use, see the disclaimer
     11  * and license in png.h
     12  *
     13  * This file contains routines that an application calls directly to
     14  * read a PNG file or stream.
     15  */
     16 
     17 #define PNG_INTERNAL
     18 #define PNG_NO_PEDANTIC_WARNINGS
     19 #include "png.h"
     20 #ifdef PNG_READ_SUPPORTED
     21 
     22 /* Create a PNG structure for reading, and allocate any memory needed. */
     23 png_structp PNGAPI
     24 png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
     25    png_error_ptr error_fn, png_error_ptr warn_fn)
     26 {
     27 
     28 #ifdef PNG_USER_MEM_SUPPORTED
     29    return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
     30       warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
     31 }
     32 
     33 /* Alternate create PNG structure for reading, and allocate any memory
     34  * needed.
     35  */
     36 png_structp PNGAPI
     37 png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
     38    png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
     39    png_malloc_ptr malloc_fn, png_free_ptr free_fn)
     40 {
     41 #endif /* PNG_USER_MEM_SUPPORTED */
     42 
     43 #ifdef PNG_SETJMP_SUPPORTED
     44    volatile
     45 #endif
     46    png_structp png_ptr;
     47 
     48 #ifdef PNG_SETJMP_SUPPORTED
     49 #ifdef USE_FAR_KEYWORD
     50    jmp_buf jmpbuf;
     51 #endif
     52 #endif
     53 
     54    int i;
     55 
     56    png_debug(1, "in png_create_read_struct");
     57 
     58 #ifdef PNG_USER_MEM_SUPPORTED
     59    png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
     60       (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
     61 #else
     62    png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
     63 #endif
     64    if (png_ptr == NULL)
     65       return (NULL);
     66 
     67    /* Added at libpng-1.2.6 */
     68 #ifdef PNG_USER_LIMITS_SUPPORTED
     69    png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
     70    png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
     71    /* Added at libpng-1.2.43 and 1.4.0 */
     72    png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
     73 #endif
     74 
     75 #ifdef PNG_SETJMP_SUPPORTED
     76 #ifdef USE_FAR_KEYWORD
     77    if (setjmp(jmpbuf))
     78 #else
     79    if (setjmp(png_ptr->jmpbuf))
     80 #endif
     81    {
     82       png_free(png_ptr, png_ptr->zbuf);
     83       png_ptr->zbuf = NULL;
     84 #ifdef PNG_USER_MEM_SUPPORTED
     85       png_destroy_struct_2((png_voidp)png_ptr,
     86          (png_free_ptr)free_fn, (png_voidp)mem_ptr);
     87 #else
     88       png_destroy_struct((png_voidp)png_ptr);
     89 #endif
     90       return (NULL);
     91    }
     92 #ifdef USE_FAR_KEYWORD
     93    png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
     94 #endif
     95 #endif /* PNG_SETJMP_SUPPORTED */
     96 
     97 #ifdef PNG_USER_MEM_SUPPORTED
     98    png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
     99 #endif
    100 
    101    png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
    102 
    103    if (user_png_ver)
    104    {
    105       i = 0;
    106       do
    107       {
    108          if (user_png_ver[i] != png_libpng_ver[i])
    109             png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
    110       } while (png_libpng_ver[i++]);
    111     }
    112     else
    113          png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
    114 
    115 
    116     if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
    117     {
    118        /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
    119        * we must recompile any applications that use any older library version.
    120        * For versions after libpng 1.0, we will be compatible, so we need
    121        * only check the first digit.
    122        */
    123       if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
    124           (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
    125           (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
    126       {
    127 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
    128          char msg[80];
    129          if (user_png_ver)
    130          {
    131            png_snprintf(msg, 80,
    132               "Application was compiled with png.h from libpng-%.20s",
    133               user_png_ver);
    134            png_warning(png_ptr, msg);
    135          }
    136          png_snprintf(msg, 80,
    137              "Application  is  running with png.c from libpng-%.20s",
    138              png_libpng_ver);
    139          png_warning(png_ptr, msg);
    140 #endif
    141 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    142          png_ptr->flags = 0;
    143 #endif
    144          png_error(png_ptr,
    145             "Incompatible libpng version in application and library");
    146       }
    147    }
    148 
    149    /* Initialize zbuf - compression buffer */
    150    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
    151    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
    152      (png_uint_32)png_ptr->zbuf_size);
    153    png_ptr->zstream.zalloc = png_zalloc;
    154    png_ptr->zstream.zfree = png_zfree;
    155    png_ptr->zstream.opaque = (voidpf)png_ptr;
    156 
    157       switch (inflateInit(&png_ptr->zstream))
    158       {
    159          case Z_OK: /* Do nothing */ break;
    160          case Z_MEM_ERROR:
    161          case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error");
    162             break;
    163          case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
    164             break;
    165          default: png_error(png_ptr, "Unknown zlib error");
    166       }
    167 
    168 
    169    png_ptr->zstream.next_out = png_ptr->zbuf;
    170    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
    171 
    172    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
    173 
    174 #ifdef PNG_SETJMP_SUPPORTED
    175 /* Applications that neglect to set up their own setjmp() and then
    176    encounter a png_error() will longjmp here.  Since the jmpbuf is
    177    then meaningless we abort instead of returning. */
    178 #ifdef USE_FAR_KEYWORD
    179    if (setjmp(jmpbuf))
    180        PNG_ABORT();
    181    png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf));
    182 #else
    183    if (setjmp(png_ptr->jmpbuf))
    184        PNG_ABORT();
    185 #endif
    186 #endif /* PNG_SETJMP_SUPPORTED */
    187 
    188    return (png_ptr);
    189 }
    190 
    191 #if defined(PNG_1_0_X) || defined(PNG_1_2_X)
    192 /* Initialize PNG structure for reading, and allocate any memory needed.
    193  * This interface is deprecated in favour of the png_create_read_struct(),
    194  * and it will disappear as of libpng-1.3.0.
    195  */
    196 #undef png_read_init
    197 void PNGAPI
    198 png_read_init(png_structp png_ptr)
    199 {
    200    /* We only come here via pre-1.0.7-compiled applications */
    201    png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
    202 }
    203 
    204 void PNGAPI
    205 png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
    206    png_size_t png_struct_size, png_size_t png_info_size)
    207 {
    208    /* We only come here via pre-1.0.12-compiled applications */
    209    if (png_ptr == NULL)
    210       return;
    211 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
    212    if (png_sizeof(png_struct) > png_struct_size ||
    213       png_sizeof(png_info) > png_info_size)
    214    {
    215       char msg[80];
    216       png_ptr->warning_fn = NULL;
    217       if (user_png_ver)
    218       {
    219         png_snprintf(msg, 80,
    220            "Application was compiled with png.h from libpng-%.20s",
    221            user_png_ver);
    222         png_warning(png_ptr, msg);
    223       }
    224       png_snprintf(msg, 80,
    225          "Application  is  running with png.c from libpng-%.20s",
    226          png_libpng_ver);
    227       png_warning(png_ptr, msg);
    228    }
    229 #endif
    230    if (png_sizeof(png_struct) > png_struct_size)
    231    {
    232       png_ptr->error_fn = NULL;
    233 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    234       png_ptr->flags = 0;
    235 #endif
    236       png_error(png_ptr,
    237       "The png struct allocated by the application for reading is"
    238       " too small.");
    239    }
    240    if (png_sizeof(png_info) > png_info_size)
    241    {
    242       png_ptr->error_fn = NULL;
    243 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
    244       png_ptr->flags = 0;
    245 #endif
    246       png_error(png_ptr,
    247         "The info struct allocated by application for reading is"
    248         " too small.");
    249    }
    250    png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
    251 }
    252 #endif /* PNG_1_0_X || PNG_1_2_X */
    253 
    254 void PNGAPI
    255 png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
    256    png_size_t png_struct_size)
    257 {
    258 #ifdef PNG_SETJMP_SUPPORTED
    259    jmp_buf tmp_jmp;  /* to save current jump buffer */
    260 #endif
    261 
    262    int i = 0;
    263 
    264    png_structp png_ptr=*ptr_ptr;
    265 
    266    if (png_ptr == NULL)
    267       return;
    268 
    269    do
    270    {
    271       if (user_png_ver[i] != png_libpng_ver[i])
    272       {
    273 #ifdef PNG_LEGACY_SUPPORTED
    274         png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
    275 #else
    276         png_ptr->warning_fn = NULL;
    277         png_warning(png_ptr,
    278          "Application uses deprecated png_read_init() and should be"
    279          " recompiled.");
    280         break;
    281 #endif
    282       }
    283    } while (png_libpng_ver[i++]);
    284 
    285    png_debug(1, "in png_read_init_3");
    286 
    287 #ifdef PNG_SETJMP_SUPPORTED
    288    /* Save jump buffer and error functions */
    289    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
    290 #endif
    291 
    292    if (png_sizeof(png_struct) > png_struct_size)
    293    {
    294       png_destroy_struct(png_ptr);
    295       *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
    296       png_ptr = *ptr_ptr;
    297    }
    298 
    299    /* Reset all variables to 0 */
    300    png_memset(png_ptr, 0, png_sizeof(png_struct));
    301 
    302 #ifdef PNG_SETJMP_SUPPORTED
    303    /* Restore jump buffer */
    304    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
    305 #endif
    306 
    307    /* Added at libpng-1.2.6 */
    308 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
    309    png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
    310    png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
    311 #endif
    312 
    313    /* Initialize zbuf - compression buffer */
    314    png_ptr->zbuf_size = PNG_ZBUF_SIZE;
    315    png_ptr->zstream.zalloc = png_zalloc;
    316    png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
    317      (png_uint_32)png_ptr->zbuf_size);
    318    png_ptr->zstream.zalloc = png_zalloc;
    319    png_ptr->zstream.zfree = png_zfree;
    320    png_ptr->zstream.opaque = (voidpf)png_ptr;
    321 
    322    switch (inflateInit(&png_ptr->zstream))
    323    {
    324       case Z_OK: /* Do nothing */ break;
    325       case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
    326       case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error");
    327           break;
    328       default: png_error(png_ptr, "Unknown zlib error");
    329    }
    330 
    331    png_ptr->zstream.next_out = png_ptr->zbuf;
    332    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
    333 
    334    png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
    335 }
    336 
    337 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    338 /* Read the information before the actual image data.  This has been
    339  * changed in v0.90 to allow reading a file that already has the magic
    340  * bytes read from the stream.  You can tell libpng how many bytes have
    341  * been read from the beginning of the stream (up to the maximum of 8)
    342  * via png_set_sig_bytes(), and we will only check the remaining bytes
    343  * here.  The application can then have access to the signature bytes we
    344  * read if it is determined that this isn't a valid PNG file.
    345  */
    346 void PNGAPI
    347 png_read_info(png_structp png_ptr, png_infop info_ptr)
    348 {
    349    png_debug(1, "in png_read_info");
    350  
    351    if (png_ptr == NULL || info_ptr == NULL)
    352       return;
    353  
    354    /* If we haven't checked all of the PNG signature bytes, do so now. */
    355    if (png_ptr->sig_bytes < 8)
    356    {
    357       png_size_t num_checked = png_ptr->sig_bytes,
    358                  num_to_check = 8 - num_checked;
    359 
    360       png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
    361       png_ptr->sig_bytes = 8;
    362 
    363       if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
    364       {
    365          if (num_checked < 4 &&
    366              png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
    367             png_error(png_ptr, "Not a PNG file");
    368          else
    369             png_error(png_ptr, "PNG file corrupted by ASCII conversion");
    370       }
    371       if (num_checked < 3)
    372          png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
    373    }
    374 
    375    for (;;)
    376    {
    377 #ifdef PNG_USE_LOCAL_ARRAYS
    378       PNG_CONST PNG_IHDR;
    379       PNG_CONST PNG_IDAT;
    380       PNG_CONST PNG_IEND;
    381       PNG_CONST PNG_PLTE;
    382 #ifdef PNG_READ_bKGD_SUPPORTED
    383       PNG_CONST PNG_bKGD;
    384 #endif
    385 #ifdef PNG_READ_cHRM_SUPPORTED
    386       PNG_CONST PNG_cHRM;
    387 #endif
    388 #ifdef PNG_READ_gAMA_SUPPORTED
    389       PNG_CONST PNG_gAMA;
    390 #endif
    391 #ifdef PNG_READ_hIST_SUPPORTED
    392       PNG_CONST PNG_hIST;
    393 #endif
    394 #ifdef PNG_READ_iCCP_SUPPORTED
    395       PNG_CONST PNG_iCCP;
    396 #endif
    397 #ifdef PNG_READ_iTXt_SUPPORTED
    398       PNG_CONST PNG_iTXt;
    399 #endif
    400 #ifdef PNG_READ_oFFs_SUPPORTED
    401       PNG_CONST PNG_oFFs;
    402 #endif
    403 #ifdef PNG_READ_pCAL_SUPPORTED
    404       PNG_CONST PNG_pCAL;
    405 #endif
    406 #ifdef PNG_READ_pHYs_SUPPORTED
    407       PNG_CONST PNG_pHYs;
    408 #endif
    409 #ifdef PNG_READ_sBIT_SUPPORTED
    410       PNG_CONST PNG_sBIT;
    411 #endif
    412 #ifdef PNG_READ_sCAL_SUPPORTED
    413       PNG_CONST PNG_sCAL;
    414 #endif
    415 #ifdef PNG_READ_sPLT_SUPPORTED
    416       PNG_CONST PNG_sPLT;
    417 #endif
    418 #ifdef PNG_READ_sRGB_SUPPORTED
    419       PNG_CONST PNG_sRGB;
    420 #endif
    421 #ifdef PNG_READ_tEXt_SUPPORTED
    422       PNG_CONST PNG_tEXt;
    423 #endif
    424 #ifdef PNG_READ_tIME_SUPPORTED
    425       PNG_CONST PNG_tIME;
    426 #endif
    427 #ifdef PNG_READ_tRNS_SUPPORTED
    428       PNG_CONST PNG_tRNS;
    429 #endif
    430 #ifdef PNG_READ_zTXt_SUPPORTED
    431       PNG_CONST PNG_zTXt;
    432 #endif
    433 #endif /* PNG_USE_LOCAL_ARRAYS */
    434       png_uint_32 length = png_read_chunk_header(png_ptr);
    435       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
    436 
    437       /* This should be a binary subdivision search or a hash for
    438        * matching the chunk name rather than a linear search.
    439        */
    440       if (!png_memcmp(chunk_name, png_IDAT, 4))
    441         if (png_ptr->mode & PNG_AFTER_IDAT)
    442           png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
    443 
    444       if (!png_memcmp(chunk_name, png_IHDR, 4))
    445          png_handle_IHDR(png_ptr, info_ptr, length);
    446       else if (!png_memcmp(chunk_name, png_IEND, 4))
    447          png_handle_IEND(png_ptr, info_ptr, length);
    448 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    449       else if (png_handle_as_unknown(png_ptr, chunk_name))
    450       {
    451          if (!png_memcmp(chunk_name, png_IDAT, 4))
    452             png_ptr->mode |= PNG_HAVE_IDAT;
    453          png_handle_unknown(png_ptr, info_ptr, length);
    454          if (!png_memcmp(chunk_name, png_PLTE, 4))
    455             png_ptr->mode |= PNG_HAVE_PLTE;
    456          else if (!png_memcmp(chunk_name, png_IDAT, 4))
    457          {
    458             if (!(png_ptr->mode & PNG_HAVE_IHDR))
    459                png_error(png_ptr, "Missing IHDR before IDAT");
    460             else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    461                      !(png_ptr->mode & PNG_HAVE_PLTE))
    462                png_error(png_ptr, "Missing PLTE before IDAT");
    463             break;
    464          }
    465       }
    466 #endif
    467       else if (!png_memcmp(chunk_name, png_PLTE, 4))
    468          png_handle_PLTE(png_ptr, info_ptr, length);
    469       else if (!png_memcmp(chunk_name, png_IDAT, 4))
    470       {
    471          if (!(png_ptr->mode & PNG_HAVE_IHDR))
    472             png_error(png_ptr, "Missing IHDR before IDAT");
    473          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    474                   !(png_ptr->mode & PNG_HAVE_PLTE))
    475             png_error(png_ptr, "Missing PLTE before IDAT");
    476 
    477          png_ptr->idat_size = length;
    478          png_ptr->mode |= PNG_HAVE_IDAT;
    479          break;
    480       }
    481 #ifdef PNG_READ_bKGD_SUPPORTED
    482       else if (!png_memcmp(chunk_name, png_bKGD, 4))
    483          png_handle_bKGD(png_ptr, info_ptr, length);
    484 #endif
    485 #ifdef PNG_READ_cHRM_SUPPORTED
    486       else if (!png_memcmp(chunk_name, png_cHRM, 4))
    487          png_handle_cHRM(png_ptr, info_ptr, length);
    488 #endif
    489 #ifdef PNG_READ_gAMA_SUPPORTED
    490       else if (!png_memcmp(chunk_name, png_gAMA, 4))
    491          png_handle_gAMA(png_ptr, info_ptr, length);
    492 #endif
    493 #ifdef PNG_READ_hIST_SUPPORTED
    494       else if (!png_memcmp(chunk_name, png_hIST, 4))
    495          png_handle_hIST(png_ptr, info_ptr, length);
    496 #endif
    497 #ifdef PNG_READ_oFFs_SUPPORTED
    498       else if (!png_memcmp(chunk_name, png_oFFs, 4))
    499          png_handle_oFFs(png_ptr, info_ptr, length);
    500 #endif
    501 #ifdef PNG_READ_pCAL_SUPPORTED
    502       else if (!png_memcmp(chunk_name, png_pCAL, 4))
    503          png_handle_pCAL(png_ptr, info_ptr, length);
    504 #endif
    505 #ifdef PNG_READ_sCAL_SUPPORTED
    506       else if (!png_memcmp(chunk_name, png_sCAL, 4))
    507          png_handle_sCAL(png_ptr, info_ptr, length);
    508 #endif
    509 #ifdef PNG_READ_pHYs_SUPPORTED
    510       else if (!png_memcmp(chunk_name, png_pHYs, 4))
    511          png_handle_pHYs(png_ptr, info_ptr, length);
    512 #endif
    513 #ifdef PNG_READ_sBIT_SUPPORTED
    514       else if (!png_memcmp(chunk_name, png_sBIT, 4))
    515          png_handle_sBIT(png_ptr, info_ptr, length);
    516 #endif
    517 #ifdef PNG_READ_sRGB_SUPPORTED
    518       else if (!png_memcmp(chunk_name, png_sRGB, 4))
    519          png_handle_sRGB(png_ptr, info_ptr, length);
    520 #endif
    521 #ifdef PNG_READ_iCCP_SUPPORTED
    522       else if (!png_memcmp(chunk_name, png_iCCP, 4))
    523          png_handle_iCCP(png_ptr, info_ptr, length);
    524 #endif
    525 #ifdef PNG_READ_sPLT_SUPPORTED
    526       else if (!png_memcmp(chunk_name, png_sPLT, 4))
    527          png_handle_sPLT(png_ptr, info_ptr, length);
    528 #endif
    529 #ifdef PNG_READ_tEXt_SUPPORTED
    530       else if (!png_memcmp(chunk_name, png_tEXt, 4))
    531          png_handle_tEXt(png_ptr, info_ptr, length);
    532 #endif
    533 #ifdef PNG_READ_tIME_SUPPORTED
    534       else if (!png_memcmp(chunk_name, png_tIME, 4))
    535          png_handle_tIME(png_ptr, info_ptr, length);
    536 #endif
    537 #ifdef PNG_READ_tRNS_SUPPORTED
    538       else if (!png_memcmp(chunk_name, png_tRNS, 4))
    539          png_handle_tRNS(png_ptr, info_ptr, length);
    540 #endif
    541 #ifdef PNG_READ_zTXt_SUPPORTED
    542       else if (!png_memcmp(chunk_name, png_zTXt, 4))
    543          png_handle_zTXt(png_ptr, info_ptr, length);
    544 #endif
    545 #ifdef PNG_READ_iTXt_SUPPORTED
    546       else if (!png_memcmp(chunk_name, png_iTXt, 4))
    547          png_handle_iTXt(png_ptr, info_ptr, length);
    548 #endif
    549       else
    550          png_handle_unknown(png_ptr, info_ptr, length);
    551    }
    552 }
    553 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    554 
    555 /* Optional call to update the users info_ptr structure */
    556 void PNGAPI
    557 png_read_update_info(png_structp png_ptr, png_infop info_ptr)
    558 {
    559    png_debug(1, "in png_read_update_info");
    560  
    561    if (png_ptr == NULL)
    562       return;
    563    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
    564       png_read_start_row(png_ptr);
    565    else
    566       png_warning(png_ptr,
    567       "Ignoring extra png_read_update_info() call; row buffer not reallocated");
    568 
    569    png_read_transform_info(png_ptr, info_ptr);
    570 }
    571 
    572 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    573 /* Initialize palette, background, etc, after transformations
    574  * are set, but before any reading takes place.  This allows
    575  * the user to obtain a gamma-corrected palette, for example.
    576  * If the user doesn't call this, we will do it ourselves.
    577  */
    578 void PNGAPI
    579 png_start_read_image(png_structp png_ptr)
    580 {
    581    png_debug(1, "in png_start_read_image");
    582  
    583    if (png_ptr == NULL)
    584       return;
    585    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
    586       png_read_start_row(png_ptr);
    587 }
    588 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    589 
    590 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    591 void PNGAPI
    592 png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
    593 {
    594    PNG_CONST PNG_IDAT;
    595    PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
    596       0xff};
    597    PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
    598    int ret;
    599  
    600    if (png_ptr == NULL)
    601       return;
    602  
    603    png_debug2(1, "in png_read_row (row %lu, pass %d)",
    604       png_ptr->row_number, png_ptr->pass);
    605 
    606    if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
    607       png_read_start_row(png_ptr);
    608    if (png_ptr->row_number == 0 && png_ptr->pass == 0)
    609    {
    610    /* Check for transforms that have been set but were defined out */
    611 #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
    612    if (png_ptr->transformations & PNG_INVERT_MONO)
    613       png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
    614 #endif
    615 #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
    616    if (png_ptr->transformations & PNG_FILLER)
    617       png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
    618 #endif
    619 #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
    620     !defined(PNG_READ_PACKSWAP_SUPPORTED)
    621    if (png_ptr->transformations & PNG_PACKSWAP)
    622       png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
    623 #endif
    624 #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
    625    if (png_ptr->transformations & PNG_PACK)
    626       png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
    627 #endif
    628 #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
    629    if (png_ptr->transformations & PNG_SHIFT)
    630       png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
    631 #endif
    632 #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
    633    if (png_ptr->transformations & PNG_BGR)
    634       png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
    635 #endif
    636 #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
    637    if (png_ptr->transformations & PNG_SWAP_BYTES)
    638       png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
    639 #endif
    640    }
    641 
    642 #ifdef PNG_READ_INTERLACING_SUPPORTED
    643    /* If interlaced and we do not need a new row, combine row and return */
    644    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    645    {
    646       switch (png_ptr->pass)
    647       {
    648          case 0:
    649             if (png_ptr->row_number & 0x07)
    650             {
    651                if (dsp_row != NULL)
    652                   png_combine_row(png_ptr, dsp_row,
    653                      png_pass_dsp_mask[png_ptr->pass]);
    654                png_read_finish_row(png_ptr);
    655                return;
    656             }
    657             break;
    658          case 1:
    659             if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
    660             {
    661                if (dsp_row != NULL)
    662                   png_combine_row(png_ptr, dsp_row,
    663                      png_pass_dsp_mask[png_ptr->pass]);
    664                png_read_finish_row(png_ptr);
    665                return;
    666             }
    667             break;
    668          case 2:
    669             if ((png_ptr->row_number & 0x07) != 4)
    670             {
    671                if (dsp_row != NULL && (png_ptr->row_number & 4))
    672                   png_combine_row(png_ptr, dsp_row,
    673                      png_pass_dsp_mask[png_ptr->pass]);
    674                png_read_finish_row(png_ptr);
    675                return;
    676             }
    677             break;
    678          case 3:
    679             if ((png_ptr->row_number & 3) || png_ptr->width < 3)
    680             {
    681                if (dsp_row != NULL)
    682                   png_combine_row(png_ptr, dsp_row,
    683                      png_pass_dsp_mask[png_ptr->pass]);
    684                png_read_finish_row(png_ptr);
    685                return;
    686             }
    687             break;
    688          case 4:
    689             if ((png_ptr->row_number & 3) != 2)
    690             {
    691                if (dsp_row != NULL && (png_ptr->row_number & 2))
    692                   png_combine_row(png_ptr, dsp_row,
    693                      png_pass_dsp_mask[png_ptr->pass]);
    694                png_read_finish_row(png_ptr);
    695                return;
    696             }
    697             break;
    698          case 5:
    699             if ((png_ptr->row_number & 1) || png_ptr->width < 2)
    700             {
    701                if (dsp_row != NULL)
    702                   png_combine_row(png_ptr, dsp_row,
    703                      png_pass_dsp_mask[png_ptr->pass]);
    704                png_read_finish_row(png_ptr);
    705                return;
    706             }
    707             break;
    708          case 6:
    709             if (!(png_ptr->row_number & 1))
    710             {
    711                png_read_finish_row(png_ptr);
    712                return;
    713             }
    714             break;
    715       }
    716    }
    717 #endif
    718 
    719    if (!(png_ptr->mode & PNG_HAVE_IDAT))
    720       png_error(png_ptr, "Invalid attempt to read row data");
    721 
    722    png_ptr->zstream.next_out = png_ptr->row_buf;
    723    png_ptr->zstream.avail_out =
    724        (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
    725        png_ptr->iwidth) + 1);
    726    do
    727    {
    728       if (!(png_ptr->zstream.avail_in))
    729       {
    730          while (!png_ptr->idat_size)
    731          {
    732             png_crc_finish(png_ptr, 0);
    733 
    734             png_ptr->idat_size = png_read_chunk_header(png_ptr);
    735             if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
    736                png_error(png_ptr, "Not enough image data");
    737          }
    738          png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
    739          png_ptr->zstream.next_in = png_ptr->zbuf;
    740          if (png_ptr->zbuf_size > png_ptr->idat_size)
    741             png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
    742          png_crc_read(png_ptr, png_ptr->zbuf,
    743             (png_size_t)png_ptr->zstream.avail_in);
    744          png_ptr->idat_size -= png_ptr->zstream.avail_in;
    745       }
    746       ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
    747       if (ret == Z_STREAM_END)
    748       {
    749          if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
    750             png_ptr->idat_size)
    751             png_error(png_ptr, "Extra compressed data");
    752          png_ptr->mode |= PNG_AFTER_IDAT;
    753          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    754          break;
    755       }
    756       if (ret != Z_OK)
    757          png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
    758                    "Decompression error");
    759 
    760    } while (png_ptr->zstream.avail_out);
    761 
    762    png_ptr->row_info.color_type = png_ptr->color_type;
    763    png_ptr->row_info.width = png_ptr->iwidth;
    764    png_ptr->row_info.channels = png_ptr->channels;
    765    png_ptr->row_info.bit_depth = png_ptr->bit_depth;
    766    png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
    767    png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
    768        png_ptr->row_info.width);
    769 
    770    if (png_ptr->row_buf[0])
    771    png_read_filter_row(png_ptr, &(png_ptr->row_info),
    772       png_ptr->row_buf + 1, png_ptr->prev_row + 1,
    773       (int)(png_ptr->row_buf[0]));
    774 
    775    png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
    776       png_ptr->rowbytes + 1);
    777 
    778 #ifdef PNG_MNG_FEATURES_SUPPORTED
    779    if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
    780       (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
    781    {
    782       /* Intrapixel differencing */
    783       png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
    784    }
    785 #endif
    786 
    787 
    788    if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
    789       png_do_read_transformations(png_ptr);
    790 
    791 #ifdef PNG_READ_INTERLACING_SUPPORTED
    792    /* Blow up interlaced rows to full size */
    793    if (png_ptr->interlaced &&
    794       (png_ptr->transformations & PNG_INTERLACE))
    795    {
    796       if (png_ptr->pass < 6)
    797          /* Old interface (pre-1.0.9):
    798           * png_do_read_interlace(&(png_ptr->row_info),
    799           *    png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
    800           */
    801          png_do_read_interlace(png_ptr);
    802 
    803       if (dsp_row != NULL)
    804          png_combine_row(png_ptr, dsp_row,
    805             png_pass_dsp_mask[png_ptr->pass]);
    806       if (row != NULL)
    807          png_combine_row(png_ptr, row,
    808             png_pass_mask[png_ptr->pass]);
    809    }
    810    else
    811 #endif
    812    {
    813       if (row != NULL)
    814          png_combine_row(png_ptr, row, 0xff);
    815       if (dsp_row != NULL)
    816          png_combine_row(png_ptr, dsp_row, 0xff);
    817    }
    818    png_read_finish_row(png_ptr);
    819 
    820    if (png_ptr->read_row_fn != NULL)
    821       (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
    822 }
    823 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    824 
    825 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    826 /* Read one or more rows of image data.  If the image is interlaced,
    827  * and png_set_interlace_handling() has been called, the rows need to
    828  * contain the contents of the rows from the previous pass.  If the
    829  * image has alpha or transparency, and png_handle_alpha()[*] has been
    830  * called, the rows contents must be initialized to the contents of the
    831  * screen.
    832  *
    833  * "row" holds the actual image, and pixels are placed in it
    834  * as they arrive.  If the image is displayed after each pass, it will
    835  * appear to "sparkle" in.  "display_row" can be used to display a
    836  * "chunky" progressive image, with finer detail added as it becomes
    837  * available.  If you do not want this "chunky" display, you may pass
    838  * NULL for display_row.  If you do not want the sparkle display, and
    839  * you have not called png_handle_alpha(), you may pass NULL for rows.
    840  * If you have called png_handle_alpha(), and the image has either an
    841  * alpha channel or a transparency chunk, you must provide a buffer for
    842  * rows.  In this case, you do not have to provide a display_row buffer
    843  * also, but you may.  If the image is not interlaced, or if you have
    844  * not called png_set_interlace_handling(), the display_row buffer will
    845  * be ignored, so pass NULL to it.
    846  *
    847  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
    848  */
    849 
    850 void PNGAPI
    851 png_read_rows(png_structp png_ptr, png_bytepp row,
    852    png_bytepp display_row, png_uint_32 num_rows)
    853 {
    854    png_uint_32 i;
    855    png_bytepp rp;
    856    png_bytepp dp;
    857 
    858    png_debug(1, "in png_read_rows");
    859  
    860    if (png_ptr == NULL)
    861       return;
    862    rp = row;
    863    dp = display_row;
    864    if (rp != NULL && dp != NULL)
    865       for (i = 0; i < num_rows; i++)
    866       {
    867          png_bytep rptr = *rp++;
    868          png_bytep dptr = *dp++;
    869 
    870          png_read_row(png_ptr, rptr, dptr);
    871       }
    872    else if (rp != NULL)
    873       for (i = 0; i < num_rows; i++)
    874       {
    875          png_bytep rptr = *rp;
    876          png_read_row(png_ptr, rptr, png_bytep_NULL);
    877          rp++;
    878       }
    879    else if (dp != NULL)
    880       for (i = 0; i < num_rows; i++)
    881       {
    882          png_bytep dptr = *dp;
    883          png_read_row(png_ptr, png_bytep_NULL, dptr);
    884          dp++;
    885       }
    886 }
    887 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    888 
    889 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    890 /* Read the entire image.  If the image has an alpha channel or a tRNS
    891  * chunk, and you have called png_handle_alpha()[*], you will need to
    892  * initialize the image to the current image that PNG will be overlaying.
    893  * We set the num_rows again here, in case it was incorrectly set in
    894  * png_read_start_row() by a call to png_read_update_info() or
    895  * png_start_read_image() if png_set_interlace_handling() wasn't called
    896  * prior to either of these functions like it should have been.  You can
    897  * only call this function once.  If you desire to have an image for
    898  * each pass of a interlaced image, use png_read_rows() instead.
    899  *
    900  * [*] png_handle_alpha() does not exist yet, as of this version of libpng
    901  */
    902 void PNGAPI
    903 png_read_image(png_structp png_ptr, png_bytepp image)
    904 {
    905    png_uint_32 i, image_height;
    906    int pass, j;
    907    png_bytepp rp;
    908 
    909    png_debug(1, "in png_read_image");
    910  
    911    if (png_ptr == NULL)
    912       return;
    913 
    914 #ifdef PNG_READ_INTERLACING_SUPPORTED
    915    pass = png_set_interlace_handling(png_ptr);
    916 #else
    917    if (png_ptr->interlaced)
    918       png_error(png_ptr,
    919         "Cannot read interlaced image -- interlace handler disabled.");
    920    pass = 1;
    921 #endif
    922 
    923 
    924    image_height=png_ptr->height;
    925    png_ptr->num_rows = image_height; /* Make sure this is set correctly */
    926 
    927    for (j = 0; j < pass; j++)
    928    {
    929       rp = image;
    930       for (i = 0; i < image_height; i++)
    931       {
    932          png_read_row(png_ptr, *rp, png_bytep_NULL);
    933          rp++;
    934       }
    935    }
    936 }
    937 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    938 
    939 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    940 /* Read the end of the PNG file.  Will not read past the end of the
    941  * file, will verify the end is accurate, and will read any comments
    942  * or time information at the end of the file, if info is not NULL.
    943  */
    944 void PNGAPI
    945 png_read_end(png_structp png_ptr, png_infop info_ptr)
    946 {
    947    png_debug(1, "in png_read_end");
    948  
    949    if (png_ptr == NULL)
    950       return;
    951    png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
    952 
    953    do
    954    {
    955 #ifdef PNG_USE_LOCAL_ARRAYS
    956       PNG_CONST PNG_IHDR;
    957       PNG_CONST PNG_IDAT;
    958       PNG_CONST PNG_IEND;
    959       PNG_CONST PNG_PLTE;
    960 #ifdef PNG_READ_bKGD_SUPPORTED
    961       PNG_CONST PNG_bKGD;
    962 #endif
    963 #ifdef PNG_READ_cHRM_SUPPORTED
    964       PNG_CONST PNG_cHRM;
    965 #endif
    966 #ifdef PNG_READ_gAMA_SUPPORTED
    967       PNG_CONST PNG_gAMA;
    968 #endif
    969 #ifdef PNG_READ_hIST_SUPPORTED
    970       PNG_CONST PNG_hIST;
    971 #endif
    972 #ifdef PNG_READ_iCCP_SUPPORTED
    973       PNG_CONST PNG_iCCP;
    974 #endif
    975 #ifdef PNG_READ_iTXt_SUPPORTED
    976       PNG_CONST PNG_iTXt;
    977 #endif
    978 #ifdef PNG_READ_oFFs_SUPPORTED
    979       PNG_CONST PNG_oFFs;
    980 #endif
    981 #ifdef PNG_READ_pCAL_SUPPORTED
    982       PNG_CONST PNG_pCAL;
    983 #endif
    984 #ifdef PNG_READ_pHYs_SUPPORTED
    985       PNG_CONST PNG_pHYs;
    986 #endif
    987 #ifdef PNG_READ_sBIT_SUPPORTED
    988       PNG_CONST PNG_sBIT;
    989 #endif
    990 #ifdef PNG_READ_sCAL_SUPPORTED
    991       PNG_CONST PNG_sCAL;
    992 #endif
    993 #ifdef PNG_READ_sPLT_SUPPORTED
    994       PNG_CONST PNG_sPLT;
    995 #endif
    996 #ifdef PNG_READ_sRGB_SUPPORTED
    997       PNG_CONST PNG_sRGB;
    998 #endif
    999 #ifdef PNG_READ_tEXt_SUPPORTED
   1000       PNG_CONST PNG_tEXt;
   1001 #endif
   1002 #ifdef PNG_READ_tIME_SUPPORTED
   1003       PNG_CONST PNG_tIME;
   1004 #endif
   1005 #ifdef PNG_READ_tRNS_SUPPORTED
   1006       PNG_CONST PNG_tRNS;
   1007 #endif
   1008 #ifdef PNG_READ_zTXt_SUPPORTED
   1009       PNG_CONST PNG_zTXt;
   1010 #endif
   1011 #endif /* PNG_USE_LOCAL_ARRAYS */
   1012       png_uint_32 length = png_read_chunk_header(png_ptr);
   1013       PNG_CONST png_bytep chunk_name = png_ptr->chunk_name;
   1014 
   1015       if (!png_memcmp(chunk_name, png_IHDR, 4))
   1016          png_handle_IHDR(png_ptr, info_ptr, length);
   1017       else if (!png_memcmp(chunk_name, png_IEND, 4))
   1018          png_handle_IEND(png_ptr, info_ptr, length);
   1019 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
   1020       else if (png_handle_as_unknown(png_ptr, chunk_name))
   1021       {
   1022          if (!png_memcmp(chunk_name, png_IDAT, 4))
   1023          {
   1024             if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
   1025                png_error(png_ptr, "Too many IDAT's found");
   1026          }
   1027          png_handle_unknown(png_ptr, info_ptr, length);
   1028          if (!png_memcmp(chunk_name, png_PLTE, 4))
   1029             png_ptr->mode |= PNG_HAVE_PLTE;
   1030       }
   1031 #endif
   1032       else if (!png_memcmp(chunk_name, png_IDAT, 4))
   1033       {
   1034          /* Zero length IDATs are legal after the last IDAT has been
   1035           * read, but not after other chunks have been read.
   1036           */
   1037          if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
   1038             png_error(png_ptr, "Too many IDAT's found");
   1039          png_crc_finish(png_ptr, length);
   1040       }
   1041       else if (!png_memcmp(chunk_name, png_PLTE, 4))
   1042          png_handle_PLTE(png_ptr, info_ptr, length);
   1043 #ifdef PNG_READ_bKGD_SUPPORTED
   1044       else if (!png_memcmp(chunk_name, png_bKGD, 4))
   1045          png_handle_bKGD(png_ptr, info_ptr, length);
   1046 #endif
   1047 #ifdef PNG_READ_cHRM_SUPPORTED
   1048       else if (!png_memcmp(chunk_name, png_cHRM, 4))
   1049          png_handle_cHRM(png_ptr, info_ptr, length);
   1050 #endif
   1051 #ifdef PNG_READ_gAMA_SUPPORTED
   1052       else if (!png_memcmp(chunk_name, png_gAMA, 4))
   1053          png_handle_gAMA(png_ptr, info_ptr, length);
   1054 #endif
   1055 #ifdef PNG_READ_hIST_SUPPORTED
   1056       else if (!png_memcmp(chunk_name, png_hIST, 4))
   1057          png_handle_hIST(png_ptr, info_ptr, length);
   1058 #endif
   1059 #ifdef PNG_READ_oFFs_SUPPORTED
   1060       else if (!png_memcmp(chunk_name, png_oFFs, 4))
   1061          png_handle_oFFs(png_ptr, info_ptr, length);
   1062 #endif
   1063 #ifdef PNG_READ_pCAL_SUPPORTED
   1064       else if (!png_memcmp(chunk_name, png_pCAL, 4))
   1065          png_handle_pCAL(png_ptr, info_ptr, length);
   1066 #endif
   1067 #ifdef PNG_READ_sCAL_SUPPORTED
   1068       else if (!png_memcmp(chunk_name, png_sCAL, 4))
   1069          png_handle_sCAL(png_ptr, info_ptr, length);
   1070 #endif
   1071 #ifdef PNG_READ_pHYs_SUPPORTED
   1072       else if (!png_memcmp(chunk_name, png_pHYs, 4))
   1073          png_handle_pHYs(png_ptr, info_ptr, length);
   1074 #endif
   1075 #ifdef PNG_READ_sBIT_SUPPORTED
   1076       else if (!png_memcmp(chunk_name, png_sBIT, 4))
   1077          png_handle_sBIT(png_ptr, info_ptr, length);
   1078 #endif
   1079 #ifdef PNG_READ_sRGB_SUPPORTED
   1080       else if (!png_memcmp(chunk_name, png_sRGB, 4))
   1081          png_handle_sRGB(png_ptr, info_ptr, length);
   1082 #endif
   1083 #ifdef PNG_READ_iCCP_SUPPORTED
   1084       else if (!png_memcmp(chunk_name, png_iCCP, 4))
   1085          png_handle_iCCP(png_ptr, info_ptr, length);
   1086 #endif
   1087 #ifdef PNG_READ_sPLT_SUPPORTED
   1088       else if (!png_memcmp(chunk_name, png_sPLT, 4))
   1089          png_handle_sPLT(png_ptr, info_ptr, length);
   1090 #endif
   1091 #ifdef PNG_READ_tEXt_SUPPORTED
   1092       else if (!png_memcmp(chunk_name, png_tEXt, 4))
   1093          png_handle_tEXt(png_ptr, info_ptr, length);
   1094 #endif
   1095 #ifdef PNG_READ_tIME_SUPPORTED
   1096       else if (!png_memcmp(chunk_name, png_tIME, 4))
   1097          png_handle_tIME(png_ptr, info_ptr, length);
   1098 #endif
   1099 #ifdef PNG_READ_tRNS_SUPPORTED
   1100       else if (!png_memcmp(chunk_name, png_tRNS, 4))
   1101          png_handle_tRNS(png_ptr, info_ptr, length);
   1102 #endif
   1103 #ifdef PNG_READ_zTXt_SUPPORTED
   1104       else if (!png_memcmp(chunk_name, png_zTXt, 4))
   1105          png_handle_zTXt(png_ptr, info_ptr, length);
   1106 #endif
   1107 #ifdef PNG_READ_iTXt_SUPPORTED
   1108       else if (!png_memcmp(chunk_name, png_iTXt, 4))
   1109          png_handle_iTXt(png_ptr, info_ptr, length);
   1110 #endif
   1111       else
   1112          png_handle_unknown(png_ptr, info_ptr, length);
   1113    } while (!(png_ptr->mode & PNG_HAVE_IEND));
   1114 }
   1115 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
   1116 
   1117 /* Free all memory used by the read */
   1118 void PNGAPI
   1119 png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
   1120    png_infopp end_info_ptr_ptr)
   1121 {
   1122    png_structp png_ptr = NULL;
   1123    png_infop info_ptr = NULL, end_info_ptr = NULL;
   1124 #ifdef PNG_USER_MEM_SUPPORTED
   1125    png_free_ptr free_fn = NULL;
   1126    png_voidp mem_ptr = NULL;
   1127 #endif
   1128 
   1129    png_debug(1, "in png_destroy_read_struct");
   1130  
   1131    if (png_ptr_ptr != NULL)
   1132       png_ptr = *png_ptr_ptr;
   1133    if (png_ptr == NULL)
   1134       return;
   1135 
   1136 #ifdef PNG_USER_MEM_SUPPORTED
   1137    free_fn = png_ptr->free_fn;
   1138    mem_ptr = png_ptr->mem_ptr;
   1139 #endif
   1140 
   1141    if (info_ptr_ptr != NULL)
   1142       info_ptr = *info_ptr_ptr;
   1143 
   1144    if (end_info_ptr_ptr != NULL)
   1145       end_info_ptr = *end_info_ptr_ptr;
   1146 
   1147    png_read_destroy(png_ptr, info_ptr, end_info_ptr);
   1148 
   1149    if (info_ptr != NULL)
   1150    {
   1151 #ifdef PNG_TEXT_SUPPORTED
   1152       png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
   1153 #endif
   1154 
   1155 #ifdef PNG_USER_MEM_SUPPORTED
   1156       png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
   1157           (png_voidp)mem_ptr);
   1158 #else
   1159       png_destroy_struct((png_voidp)info_ptr);
   1160 #endif
   1161       *info_ptr_ptr = NULL;
   1162    }
   1163 
   1164    if (end_info_ptr != NULL)
   1165    {
   1166 #ifdef PNG_READ_TEXT_SUPPORTED
   1167       png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
   1168 #endif
   1169 #ifdef PNG_USER_MEM_SUPPORTED
   1170       png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
   1171          (png_voidp)mem_ptr);
   1172 #else
   1173       png_destroy_struct((png_voidp)end_info_ptr);
   1174 #endif
   1175       *end_info_ptr_ptr = NULL;
   1176    }
   1177 
   1178    if (png_ptr != NULL)
   1179    {
   1180 #ifdef PNG_USER_MEM_SUPPORTED
   1181       png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
   1182           (png_voidp)mem_ptr);
   1183 #else
   1184       png_destroy_struct((png_voidp)png_ptr);
   1185 #endif
   1186       *png_ptr_ptr = NULL;
   1187    }
   1188 }
   1189 
   1190 /* Free all memory used by the read (old method) */
   1191 void /* PRIVATE */
   1192 png_read_destroy(png_structp png_ptr, png_infop info_ptr,
   1193     png_infop end_info_ptr)
   1194 {
   1195 #ifdef PNG_SETJMP_SUPPORTED
   1196    jmp_buf tmp_jmp;
   1197 #endif
   1198    png_error_ptr error_fn;
   1199    png_error_ptr warning_fn;
   1200    png_voidp error_ptr;
   1201 #ifdef PNG_USER_MEM_SUPPORTED
   1202    png_free_ptr free_fn;
   1203 #endif
   1204 
   1205    png_debug(1, "in png_read_destroy");
   1206  
   1207    if (info_ptr != NULL)
   1208       png_info_destroy(png_ptr, info_ptr);
   1209 
   1210    if (end_info_ptr != NULL)
   1211       png_info_destroy(png_ptr, end_info_ptr);
   1212 
   1213    png_free(png_ptr, png_ptr->zbuf);
   1214    png_free(png_ptr, png_ptr->big_row_buf);
   1215    png_free(png_ptr, png_ptr->prev_row);
   1216    png_free(png_ptr, png_ptr->chunkdata);
   1217 #ifdef PNG_READ_DITHER_SUPPORTED
   1218    png_free(png_ptr, png_ptr->palette_lookup);
   1219    png_free(png_ptr, png_ptr->dither_index);
   1220 #endif
   1221 #ifdef PNG_READ_GAMMA_SUPPORTED
   1222    png_free(png_ptr, png_ptr->gamma_table);
   1223 #endif
   1224 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1225    png_free(png_ptr, png_ptr->gamma_from_1);
   1226    png_free(png_ptr, png_ptr->gamma_to_1);
   1227 #endif
   1228 #ifdef PNG_FREE_ME_SUPPORTED
   1229    if (png_ptr->free_me & PNG_FREE_PLTE)
   1230       png_zfree(png_ptr, png_ptr->palette);
   1231    png_ptr->free_me &= ~PNG_FREE_PLTE;
   1232 #else
   1233    if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
   1234       png_zfree(png_ptr, png_ptr->palette);
   1235    png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
   1236 #endif
   1237 #if defined(PNG_tRNS_SUPPORTED) || \
   1238     defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
   1239 #ifdef PNG_FREE_ME_SUPPORTED
   1240    if (png_ptr->free_me & PNG_FREE_TRNS)
   1241       png_free(png_ptr, png_ptr->trans);
   1242    png_ptr->free_me &= ~PNG_FREE_TRNS;
   1243 #else
   1244    if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
   1245       png_free(png_ptr, png_ptr->trans);
   1246    png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
   1247 #endif
   1248 #endif
   1249 #ifdef PNG_READ_hIST_SUPPORTED
   1250 #ifdef PNG_FREE_ME_SUPPORTED
   1251    if (png_ptr->free_me & PNG_FREE_HIST)
   1252       png_free(png_ptr, png_ptr->hist);
   1253    png_ptr->free_me &= ~PNG_FREE_HIST;
   1254 #else
   1255    if (png_ptr->flags & PNG_FLAG_FREE_HIST)
   1256       png_free(png_ptr, png_ptr->hist);
   1257    png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
   1258 #endif
   1259 #endif
   1260 #ifdef PNG_READ_GAMMA_SUPPORTED
   1261    if (png_ptr->gamma_16_table != NULL)
   1262    {
   1263       int i;
   1264       int istop = (1 << (8 - png_ptr->gamma_shift));
   1265       for (i = 0; i < istop; i++)
   1266       {
   1267          png_free(png_ptr, png_ptr->gamma_16_table[i]);
   1268       }
   1269    png_free(png_ptr, png_ptr->gamma_16_table);
   1270    }
   1271 #ifdef PNG_READ_BACKGROUND_SUPPORTED
   1272    if (png_ptr->gamma_16_from_1 != NULL)
   1273    {
   1274       int i;
   1275       int istop = (1 << (8 - png_ptr->gamma_shift));
   1276       for (i = 0; i < istop; i++)
   1277       {
   1278          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
   1279       }
   1280    png_free(png_ptr, png_ptr->gamma_16_from_1);
   1281    }
   1282    if (png_ptr->gamma_16_to_1 != NULL)
   1283    {
   1284       int i;
   1285       int istop = (1 << (8 - png_ptr->gamma_shift));
   1286       for (i = 0; i < istop; i++)
   1287       {
   1288          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
   1289       }
   1290    png_free(png_ptr, png_ptr->gamma_16_to_1);
   1291    }
   1292 #endif
   1293 #endif
   1294 #ifdef PNG_TIME_RFC1123_SUPPORTED
   1295    png_free(png_ptr, png_ptr->time_buffer);
   1296 #endif
   1297 
   1298    inflateEnd(&png_ptr->zstream);
   1299 #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
   1300    png_free(png_ptr, png_ptr->save_buffer);
   1301 #endif
   1302 
   1303    /* Save the important info out of the png_struct, in case it is
   1304     * being used again.
   1305     */
   1306 #ifdef PNG_SETJMP_SUPPORTED
   1307    png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf));
   1308 #endif
   1309 
   1310    error_fn = png_ptr->error_fn;
   1311    warning_fn = png_ptr->warning_fn;
   1312    error_ptr = png_ptr->error_ptr;
   1313 #ifdef PNG_USER_MEM_SUPPORTED
   1314    free_fn = png_ptr->free_fn;
   1315 #endif
   1316 
   1317    png_memset(png_ptr, 0, png_sizeof(png_struct));
   1318 
   1319    png_ptr->error_fn = error_fn;
   1320    png_ptr->warning_fn = warning_fn;
   1321    png_ptr->error_ptr = error_ptr;
   1322 #ifdef PNG_USER_MEM_SUPPORTED
   1323    png_ptr->free_fn = free_fn;
   1324 #endif
   1325 
   1326 #ifdef PNG_SETJMP_SUPPORTED
   1327    png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf));
   1328 #endif
   1329 
   1330 }
   1331 
   1332 void PNGAPI
   1333 png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
   1334 {
   1335    if (png_ptr == NULL)
   1336       return;
   1337    png_ptr->read_row_fn = read_row_fn;
   1338 }
   1339 
   1340 
   1341 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
   1342 #ifdef PNG_INFO_IMAGE_SUPPORTED
   1343 void PNGAPI
   1344 png_read_png(png_structp png_ptr, png_infop info_ptr,
   1345                            int transforms,
   1346                            voidp params)
   1347 {
   1348    int row;
   1349 
   1350    if (png_ptr == NULL)
   1351       return;
   1352 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   1353    /* Invert the alpha channel from opacity to transparency
   1354     */
   1355    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
   1356        png_set_invert_alpha(png_ptr);
   1357 #endif
   1358 
   1359    /* png_read_info() gives us all of the information from the
   1360     * PNG file before the first IDAT (image data chunk).
   1361     */
   1362    png_read_info(png_ptr, info_ptr);
   1363    if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
   1364       png_error(png_ptr, "Image is too high to process with png_read_png()");
   1365 
   1366    /* -------------- image transformations start here ------------------- */
   1367 
   1368 #ifdef PNG_READ_16_TO_8_SUPPORTED
   1369    /* Tell libpng to strip 16 bit/color files down to 8 bits per color.
   1370     */
   1371    if (transforms & PNG_TRANSFORM_STRIP_16)
   1372       png_set_strip_16(png_ptr);
   1373 #endif
   1374 
   1375 #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
   1376    /* Strip alpha bytes from the input data without combining with
   1377     * the background (not recommended).
   1378     */
   1379    if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
   1380       png_set_strip_alpha(png_ptr);
   1381 #endif
   1382 
   1383 #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
   1384    /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
   1385     * byte into separate bytes (useful for paletted and grayscale images).
   1386     */
   1387    if (transforms & PNG_TRANSFORM_PACKING)
   1388       png_set_packing(png_ptr);
   1389 #endif
   1390 
   1391 #ifdef PNG_READ_PACKSWAP_SUPPORTED
   1392    /* Change the order of packed pixels to least significant bit first
   1393     * (not useful if you are using png_set_packing).
   1394     */
   1395    if (transforms & PNG_TRANSFORM_PACKSWAP)
   1396       png_set_packswap(png_ptr);
   1397 #endif
   1398 
   1399 #ifdef PNG_READ_EXPAND_SUPPORTED
   1400    /* Expand paletted colors into true RGB triplets
   1401     * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
   1402     * Expand paletted or RGB images with transparency to full alpha
   1403     * channels so the data will be available as RGBA quartets.
   1404     */
   1405    if (transforms & PNG_TRANSFORM_EXPAND)
   1406       if ((png_ptr->bit_depth < 8) ||
   1407           (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
   1408           (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
   1409          png_set_expand(png_ptr);
   1410 #endif
   1411 
   1412    /* We don't handle background color or gamma transformation or dithering.
   1413     */
   1414 
   1415 #ifdef PNG_READ_INVERT_SUPPORTED
   1416    /* Invert monochrome files to have 0 as white and 1 as black
   1417     */
   1418    if (transforms & PNG_TRANSFORM_INVERT_MONO)
   1419       png_set_invert_mono(png_ptr);
   1420 #endif
   1421 
   1422 #ifdef PNG_READ_SHIFT_SUPPORTED
   1423    /* If you want to shift the pixel values from the range [0,255] or
   1424     * [0,65535] to the original [0,7] or [0,31], or whatever range the
   1425     * colors were originally in:
   1426     */
   1427    if ((transforms & PNG_TRANSFORM_SHIFT)
   1428        && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
   1429    {
   1430       png_color_8p sig_bit;
   1431 
   1432       png_get_sBIT(png_ptr, info_ptr, &sig_bit);
   1433       png_set_shift(png_ptr, sig_bit);
   1434    }
   1435 #endif
   1436 
   1437 #ifdef PNG_READ_BGR_SUPPORTED
   1438    /* Flip the RGB pixels to BGR (or RGBA to BGRA)
   1439     */
   1440    if (transforms & PNG_TRANSFORM_BGR)
   1441       png_set_bgr(png_ptr);
   1442 #endif
   1443 
   1444 #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
   1445    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR)
   1446     */
   1447    if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
   1448        png_set_swap_alpha(png_ptr);
   1449 #endif
   1450 
   1451 #ifdef PNG_READ_SWAP_SUPPORTED
   1452    /* Swap bytes of 16 bit files to least significant byte first
   1453     */
   1454    if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
   1455       png_set_swap(png_ptr);
   1456 #endif
   1457 
   1458 /* Added at libpng-1.2.41 */
   1459 #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
   1460    /* Invert the alpha channel from opacity to transparency
   1461     */
   1462    if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
   1463        png_set_invert_alpha(png_ptr);
   1464 #endif
   1465 
   1466 /* Added at libpng-1.2.41 */
   1467 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
   1468    /* Expand grayscale image to RGB
   1469     */
   1470    if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
   1471        png_set_gray_to_rgb(png_ptr);
   1472 #endif
   1473 
   1474    /* We don't handle adding filler bytes */
   1475 
   1476    /* Optional call to gamma correct and add the background to the palette
   1477     * and update info structure.  REQUIRED if you are expecting libpng to
   1478     * update the palette for you (i.e., you selected such a transform above).
   1479     */
   1480    png_read_update_info(png_ptr, info_ptr);
   1481 
   1482    /* -------------- image transformations end here ------------------- */
   1483 
   1484 #ifdef PNG_FREE_ME_SUPPORTED
   1485    png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
   1486 #endif
   1487    if (info_ptr->row_pointers == NULL)
   1488    {
   1489       info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
   1490          info_ptr->height * png_sizeof(png_bytep));
   1491       png_memset(info_ptr->row_pointers, 0, info_ptr->height
   1492          * png_sizeof(png_bytep));
   1493 
   1494 #ifdef PNG_FREE_ME_SUPPORTED
   1495       info_ptr->free_me |= PNG_FREE_ROWS;
   1496 #endif
   1497 
   1498       for (row = 0; row < (int)info_ptr->height; row++)
   1499          info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
   1500             png_get_rowbytes(png_ptr, info_ptr));
   1501    }
   1502 
   1503    png_read_image(png_ptr, info_ptr->row_pointers);
   1504    info_ptr->valid |= PNG_INFO_IDAT;
   1505 
   1506    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
   1507    png_read_end(png_ptr, info_ptr);
   1508 
   1509    transforms = transforms; /* Quiet compiler warnings */
   1510    params = params;
   1511 
   1512 }
   1513 #endif /* PNG_INFO_IMAGE_SUPPORTED */
   1514 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
   1515 #endif /* PNG_READ_SUPPORTED */