LCOV - code coverage report
Current view: directory - media/libpng - pngread.c (source / functions) Found Hit Coverage
Test: app.info Lines: 128 68 53.1 %
Date: 2012-06-02 Functions: 6 4 66.7 %

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

Generated by: LCOV version 1.7