LCOV - code coverage report
Current view: directory - media/libpng - pngpread.c (source / functions) Found Hit Coverage
Test: app.info Lines: 553 228 41.2 %
Date: 2012-06-02 Functions: 23 18 78.3 %

       1                 : 
       2                 : /* pngpread.c - read a png file in push mode
       3                 :  *
       4                 :  * Last changed in libpng 1.5.9 [February 18, 2012]
       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                 : 
      14                 : #include "pngpriv.h"
      15                 : 
      16                 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
      17                 : 
      18                 : /* Push model modes */
      19                 : #define PNG_READ_SIG_MODE   0
      20                 : #define PNG_READ_CHUNK_MODE 1
      21                 : #define PNG_READ_IDAT_MODE  2
      22                 : #define PNG_SKIP_MODE       3
      23                 : #define PNG_READ_tEXt_MODE  4
      24                 : #define PNG_READ_zTXt_MODE  5
      25                 : #define PNG_READ_DONE_MODE  6
      26                 : #define PNG_READ_iTXt_MODE  7
      27                 : #define PNG_ERROR_MODE      8
      28                 : 
      29                 : void PNGAPI
      30              20 : png_process_data(png_structp png_ptr, png_infop info_ptr,
      31                 :     png_bytep buffer, png_size_t buffer_size)
      32                 : {
      33              20 :    if (png_ptr == NULL || info_ptr == NULL)
      34               0 :       return;
      35                 : 
      36              20 :    png_push_restore_buffer(png_ptr, buffer, buffer_size);
      37                 : 
      38              85 :    while (png_ptr->buffer_size)
      39                 :    {
      40              45 :       png_process_some_data(png_ptr, info_ptr);
      41                 :    }
      42                 : }
      43                 : 
      44                 : png_size_t PNGAPI
      45               0 : png_process_data_pause(png_structp png_ptr, int save)
      46                 : {
      47               0 :    if (png_ptr != NULL)
      48                 :    {
      49                 :       /* It's easiest for the caller if we do the save, then the caller doesn't
      50                 :        * have to supply the same data again:
      51                 :        */
      52               0 :       if (save)
      53               0 :          png_push_save_buffer(png_ptr);
      54                 :       else
      55                 :       {
      56                 :          /* This includes any pending saved bytes: */
      57               0 :          png_size_t remaining = png_ptr->buffer_size;
      58               0 :          png_ptr->buffer_size = 0;
      59                 : 
      60                 :          /* So subtract the saved buffer size, unless all the data
      61                 :           * is actually 'saved', in which case we just return 0
      62                 :           */
      63               0 :          if (png_ptr->save_buffer_size < remaining)
      64               0 :             return remaining - png_ptr->save_buffer_size;
      65                 :       }
      66                 :    }
      67                 : 
      68               0 :    return 0;
      69                 : }
      70                 : 
      71                 : png_uint_32 PNGAPI
      72               0 : png_process_data_skip(png_structp png_ptr)
      73                 : {
      74               0 :    png_uint_32 remaining = 0;
      75                 : 
      76               0 :    if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
      77               0 :       png_ptr->skip_length > 0)
      78                 :    {
      79                 :       /* At the end of png_process_data the buffer size must be 0 (see the loop
      80                 :        * above) so we can detect a broken call here:
      81                 :        */
      82               0 :       if (png_ptr->buffer_size != 0)
      83               0 :          png_error(png_ptr,
      84                 :             "png_process_data_skip called inside png_process_data");
      85                 : 
      86                 :       /* If is impossible for there to be a saved buffer at this point -
      87                 :        * otherwise we could not be in SKIP mode.  This will also happen if
      88                 :        * png_process_skip is called inside png_process_data (but only very
      89                 :        * rarely.)
      90                 :        */
      91               0 :       if (png_ptr->save_buffer_size != 0)
      92               0 :          png_error(png_ptr, "png_process_data_skip called with saved data");
      93                 : 
      94               0 :       remaining = png_ptr->skip_length;
      95               0 :       png_ptr->skip_length = 0;
      96               0 :       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
      97                 :    }
      98                 : 
      99               0 :    return remaining;
     100                 : }
     101                 : 
     102                 : /* What we do with the incoming data depends on what we were previously
     103                 :  * doing before we ran out of data...
     104                 :  */
     105                 : void /* PRIVATE */
     106              45 : png_process_some_data(png_structp png_ptr, png_infop info_ptr)
     107                 : {
     108              45 :    if (png_ptr == NULL)
     109               0 :       return;
     110                 : 
     111              45 :    switch (png_ptr->process_mode)
     112                 :    {
     113                 :       case PNG_READ_SIG_MODE:
     114                 :       {
     115               4 :          png_push_read_sig(png_ptr, info_ptr);
     116               4 :          break;
     117                 :       }
     118                 : 
     119                 :       case PNG_READ_CHUNK_MODE:
     120                 :       {
     121              14 :          png_push_read_chunk(png_ptr, info_ptr);
     122              14 :          break;
     123                 :       }
     124                 : 
     125                 :       case PNG_READ_IDAT_MODE:
     126                 :       {
     127              26 :          png_push_read_IDAT(png_ptr);
     128              26 :          break;
     129                 :       }
     130                 : 
     131                 : #ifdef PNG_READ_tEXt_SUPPORTED
     132                 :       case PNG_READ_tEXt_MODE:
     133                 :       {
     134                 :          png_push_read_tEXt(png_ptr, info_ptr);
     135                 :          break;
     136                 :       }
     137                 : 
     138                 : #endif
     139                 : #ifdef PNG_READ_zTXt_SUPPORTED
     140                 :       case PNG_READ_zTXt_MODE:
     141                 :       {
     142                 :          png_push_read_zTXt(png_ptr, info_ptr);
     143                 :          break;
     144                 :       }
     145                 : 
     146                 : #endif
     147                 : #ifdef PNG_READ_iTXt_SUPPORTED
     148                 :       case PNG_READ_iTXt_MODE:
     149                 :       {
     150                 :          png_push_read_iTXt(png_ptr, info_ptr);
     151                 :          break;
     152                 :       }
     153                 : 
     154                 : #endif
     155                 :       case PNG_SKIP_MODE:
     156                 :       {
     157               1 :          png_push_crc_finish(png_ptr);
     158               1 :          break;
     159                 :       }
     160                 : 
     161                 :       default:
     162                 :       {
     163               0 :          png_ptr->buffer_size = 0;
     164               0 :          break;
     165                 :       }
     166                 :    }
     167                 : }
     168                 : 
     169                 : /* Read any remaining signature bytes from the stream and compare them with
     170                 :  * the correct PNG signature.  It is possible that this routine is called
     171                 :  * with bytes already read from the signature, either because they have been
     172                 :  * checked by the calling application, or because of multiple calls to this
     173                 :  * routine.
     174                 :  */
     175                 : void /* PRIVATE */
     176               4 : png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
     177                 : {
     178               4 :    png_size_t num_checked = png_ptr->sig_bytes,
     179               4 :              num_to_check = 8 - num_checked;
     180                 : 
     181               4 :    if (png_ptr->buffer_size < num_to_check)
     182                 :    {
     183               0 :       num_to_check = png_ptr->buffer_size;
     184                 :    }
     185                 : 
     186               4 :    png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
     187                 :        num_to_check);
     188               4 :    png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
     189                 : 
     190               4 :    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
     191                 :    {
     192               0 :       if (num_checked < 4 &&
     193               0 :           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
     194               0 :          png_error(png_ptr, "Not a PNG file");
     195                 : 
     196                 :       else
     197               0 :          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
     198                 :    }
     199                 :    else
     200                 :    {
     201               4 :       if (png_ptr->sig_bytes >= 8)
     202                 :       {
     203               4 :          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
     204                 :       }
     205                 :    }
     206               4 : }
     207                 : 
     208                 : void /* PRIVATE */
     209              14 : png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
     210                 : {
     211                 :    png_uint_32 chunk_name;
     212                 : 
     213                 :    /* First we make sure we have enough data for the 4 byte chunk name
     214                 :     * and the 4 byte chunk length before proceeding with decoding the
     215                 :     * chunk data.  To fully decode each of these chunks, we also make
     216                 :     * sure we have enough data in the buffer for the 4 byte CRC at the
     217                 :     * end of every chunk (except IDAT, which is handled separately).
     218                 :     */
     219              14 :    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
     220                 :    {
     221                 :       png_byte chunk_length[4];
     222                 :       png_byte chunk_tag[4];
     223                 : 
     224              10 :       if (png_ptr->buffer_size < 8)
     225                 :       {
     226               0 :          png_push_save_buffer(png_ptr);
     227               0 :          return;
     228                 :       }
     229                 : 
     230              10 :       png_push_fill_buffer(png_ptr, chunk_length, 4);
     231              10 :       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
     232              10 :       png_reset_crc(png_ptr);
     233              10 :       png_crc_read(png_ptr, chunk_tag, 4);
     234              10 :       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
     235              10 :       png_check_chunk_name(png_ptr, png_ptr->chunk_name);
     236              10 :       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
     237                 :    }
     238                 : 
     239              14 :    chunk_name = png_ptr->chunk_name;
     240                 : 
     241                 : #ifdef PNG_READ_APNG_SUPPORTED
     242              18 :    if (png_ptr->num_frames_read > 0 &&
     243               4 :        png_ptr->num_frames_read < info_ptr->num_frames)
     244                 :    {
     245               0 :       if (chunk_name == png_IDAT)
     246                 :       {
     247                 :          /* Discard trailing IDATs for the first frame */
     248               0 :          if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
     249               0 :             png_error(png_ptr, "out of place IDAT");
     250                 : 
     251               0 :          if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     252                 :          {
     253               0 :             png_push_save_buffer(png_ptr);
     254               0 :             return;
     255                 :          }
     256                 : 
     257               0 :          png_push_crc_skip(png_ptr, png_ptr->push_length);
     258               0 :          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     259               0 :          return;
     260                 :       }
     261               0 :       else if (chunk_name == png_fdAT)
     262                 :       {
     263               0 :          if (png_ptr->buffer_size < 4)
     264                 :          {
     265               0 :             png_push_save_buffer(png_ptr);
     266               0 :             return;
     267                 :          }
     268                 : 
     269               0 :          png_ensure_sequence_number(png_ptr, 4);
     270                 : 
     271               0 :          if (!(png_ptr->mode & PNG_HAVE_fcTL))
     272                 :          {
     273                 :             /* Discard trailing fdATs for frames other than the first */
     274               0 :             if (png_ptr->num_frames_read < 2)
     275               0 :                png_error(png_ptr, "out of place fdAT");
     276                 : 
     277               0 :             if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     278                 :             {
     279               0 :                png_push_save_buffer(png_ptr);
     280               0 :                return;
     281                 :             }
     282                 : 
     283               0 :             png_push_crc_skip(png_ptr, png_ptr->push_length);
     284               0 :             png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     285               0 :             return;
     286                 :          }
     287                 : 
     288                 :          else
     289                 :          {
     290                 :             /* frame data follows */
     291               0 :             png_ptr->idat_size = png_ptr->push_length - 4;
     292               0 :             png_ptr->mode |= PNG_HAVE_IDAT;
     293               0 :             png_ptr->process_mode = PNG_READ_IDAT_MODE;
     294                 : 
     295               0 :             return;
     296                 :          }
     297                 :       }
     298                 : 
     299               0 :       else if (chunk_name == png_fcTL)
     300                 :       {
     301               0 :          if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     302                 :          {
     303               0 :             png_push_save_buffer(png_ptr);
     304               0 :             return;
     305                 :          }
     306                 : 
     307               0 :          png_read_reset(png_ptr);
     308               0 :          png_ptr->mode &= ~PNG_HAVE_fcTL;
     309                 : 
     310               0 :          png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
     311                 : 
     312               0 :          if (!(png_ptr->mode & PNG_HAVE_fcTL))
     313               0 :             png_error(png_ptr, "missing required fcTL chunk");
     314                 : 
     315               0 :          png_read_reinit(png_ptr, info_ptr);
     316               0 :          png_progressive_read_reset(png_ptr);
     317                 : 
     318               0 :          if (png_ptr->frame_info_fn != NULL)
     319               0 :             (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
     320                 : 
     321               0 :          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     322                 : 
     323               0 :          return;
     324                 :       }
     325                 : 
     326                 :       else
     327                 :       {
     328               0 :          if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     329                 :          {
     330               0 :             png_push_save_buffer(png_ptr);
     331               0 :             return;
     332                 :          }
     333                 :          png_warning(png_ptr, "Skipped (ignored) a chunk "
     334                 :                               "between APNG chunks");
     335               0 :          png_push_crc_skip(png_ptr, png_ptr->push_length);
     336               0 :          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     337               0 :          return;
     338                 :       }
     339                 : 
     340                 :       return;
     341                 :    }
     342                 : #endif /* PNG_READ_APNG_SUPPORTED */
     343                 : 
     344              14 :    if (chunk_name == png_IDAT)
     345                 :    {
     346                 :       /* This is here above the if/else case statement below because if the
     347                 :        * unknown handling marks 'IDAT' as unknown then the IDAT handling case is
     348                 :        * completely skipped.
     349                 :        *
     350                 :        * TODO: there must be a better way of doing this.
     351                 :        */
     352               4 :       if (png_ptr->mode & PNG_AFTER_IDAT)
     353               0 :          png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
     354                 :    }
     355                 : 
     356              14 :    if (chunk_name == png_IHDR)
     357                 :    {
     358               4 :       if (png_ptr->push_length != 13)
     359               0 :          png_error(png_ptr, "Invalid IHDR length");
     360                 : 
     361               4 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     362                 :       {
     363               0 :          png_push_save_buffer(png_ptr);
     364               0 :          return;
     365                 :       }
     366                 : 
     367               4 :       png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
     368                 :    }
     369                 : 
     370              10 :    else if (chunk_name == png_IEND)
     371                 :    {
     372               4 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     373                 :       {
     374               0 :          png_push_save_buffer(png_ptr);
     375               0 :          return;
     376                 :       }
     377                 : 
     378               4 :       png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
     379                 : 
     380               4 :       png_ptr->process_mode = PNG_READ_DONE_MODE;
     381               4 :       png_push_have_end(png_ptr, info_ptr);
     382                 :    }
     383                 : 
     384                 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
     385                 :    else if (png_chunk_unknown_handling(png_ptr, chunk_name))
     386                 :    {
     387                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     388                 :       {
     389                 :          png_push_save_buffer(png_ptr);
     390                 :          return;
     391                 :       }
     392                 : 
     393                 :       if (chunk_name == png_IDAT)
     394                 :          png_ptr->mode |= PNG_HAVE_IDAT;
     395                 : 
     396                 :       png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
     397                 : 
     398                 :       if (chunk_name == png_PLTE)
     399                 :          png_ptr->mode |= PNG_HAVE_PLTE;
     400                 : 
     401                 :       else if (chunk_name == png_IDAT)
     402                 :       {
     403                 :          if (!(png_ptr->mode & PNG_HAVE_IHDR))
     404                 :             png_error(png_ptr, "Missing IHDR before IDAT");
     405                 : 
     406                 :          else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
     407                 :              !(png_ptr->mode & PNG_HAVE_PLTE))
     408                 :             png_error(png_ptr, "Missing PLTE before IDAT");
     409                 :       }
     410                 :    }
     411                 : 
     412                 : #endif
     413               6 :    else if (chunk_name == png_PLTE)
     414                 :    {
     415               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     416                 :       {
     417               0 :          png_push_save_buffer(png_ptr);
     418               0 :          return;
     419                 :       }
     420               0 :       png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
     421                 :    }
     422                 : 
     423               6 :    else if (chunk_name == png_IDAT)
     424                 :    {
     425                 :       /* If we reach an IDAT chunk, this means we have read all of the
     426                 :        * header chunks, and we can start reading the image (or if this
     427                 :        * is called after the image has been read - we have an error).
     428                 :        */
     429                 : 
     430               4 :       if (!(png_ptr->mode & PNG_HAVE_IHDR))
     431               0 :          png_error(png_ptr, "Missing IHDR before IDAT");
     432                 : 
     433               4 :       else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
     434               0 :           !(png_ptr->mode & PNG_HAVE_PLTE))
     435               0 :          png_error(png_ptr, "Missing PLTE before IDAT");
     436                 : 
     437               4 :       if (png_ptr->mode & PNG_HAVE_IDAT)
     438                 :       {
     439               0 :          if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
     440               0 :             if (png_ptr->push_length == 0)
     441               0 :                return;
     442                 : 
     443               0 :          if (png_ptr->mode & PNG_AFTER_IDAT)
     444               0 :             png_benign_error(png_ptr, "Too many IDATs found");
     445                 :       }
     446                 : 
     447                 : #ifdef PNG_READ_APNG_SUPPORTED
     448               4 :       png_have_info(png_ptr, info_ptr);
     449                 : #endif
     450                 : 
     451               4 :       png_ptr->idat_size = png_ptr->push_length;
     452               4 :       png_ptr->mode |= PNG_HAVE_IDAT;
     453               4 :       png_ptr->process_mode = PNG_READ_IDAT_MODE;
     454               4 :       png_push_have_info(png_ptr, info_ptr);
     455               4 :       png_ptr->zstream.avail_out =
     456               8 :           (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
     457               8 :           png_ptr->iwidth) + 1;
     458               4 :       png_ptr->zstream.next_out = png_ptr->row_buf;
     459               4 :       return;
     460                 :    }
     461                 : 
     462                 : #ifdef PNG_READ_gAMA_SUPPORTED
     463               2 :    else if (png_ptr->chunk_name == png_gAMA)
     464                 :    {
     465               1 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     466                 :       {
     467               0 :          png_push_save_buffer(png_ptr);
     468               0 :          return;
     469                 :       }
     470                 : 
     471               1 :       png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
     472                 :    }
     473                 : 
     474                 : #endif
     475                 : #ifdef PNG_READ_sBIT_SUPPORTED
     476                 :    else if (png_ptr->chunk_name == png_sBIT)
     477                 :    {
     478                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     479                 :       {
     480                 :          png_push_save_buffer(png_ptr);
     481                 :          return;
     482                 :       }
     483                 : 
     484                 :       png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
     485                 :    }
     486                 : 
     487                 : #endif
     488                 : #ifdef PNG_READ_cHRM_SUPPORTED
     489               1 :    else if (png_ptr->chunk_name == png_cHRM)
     490                 :    {
     491               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     492                 :       {
     493               0 :          png_push_save_buffer(png_ptr);
     494               0 :          return;
     495                 :       }
     496                 : 
     497               0 :       png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
     498                 :    }
     499                 : 
     500                 : #endif
     501                 : #ifdef PNG_READ_sRGB_SUPPORTED
     502               1 :    else if (chunk_name == png_sRGB)
     503                 :    {
     504               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     505                 :       {
     506               0 :          png_push_save_buffer(png_ptr);
     507               0 :          return;
     508                 :       }
     509                 : 
     510               0 :       png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
     511                 :    }
     512                 : 
     513                 : #endif
     514                 : #ifdef PNG_READ_iCCP_SUPPORTED
     515               1 :    else if (png_ptr->chunk_name == png_iCCP)
     516                 :    {
     517               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     518                 :       {
     519               0 :          png_push_save_buffer(png_ptr);
     520               0 :          return;
     521                 :       }
     522                 : 
     523               0 :       png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
     524                 :    }
     525                 : 
     526                 : #endif
     527                 : #ifdef PNG_READ_sPLT_SUPPORTED
     528                 :    else if (chunk_name == png_sPLT)
     529                 :    {
     530                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     531                 :       {
     532                 :          png_push_save_buffer(png_ptr);
     533                 :          return;
     534                 :       }
     535                 : 
     536                 :       png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
     537                 :    }
     538                 : 
     539                 : #endif
     540                 : #ifdef PNG_READ_tRNS_SUPPORTED
     541               1 :    else if (chunk_name == png_tRNS)
     542                 :    {
     543               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     544                 :       {
     545               0 :          png_push_save_buffer(png_ptr);
     546               0 :          return;
     547                 :       }
     548                 : 
     549               0 :       png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
     550                 :    }
     551                 : 
     552                 : #endif
     553                 : #ifdef PNG_READ_bKGD_SUPPORTED
     554                 :    else if (chunk_name == png_bKGD)
     555                 :    {
     556                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     557                 :       {
     558                 :          png_push_save_buffer(png_ptr);
     559                 :          return;
     560                 :       }
     561                 : 
     562                 :       png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
     563                 :    }
     564                 : 
     565                 : #endif
     566                 : #ifdef PNG_READ_hIST_SUPPORTED
     567                 :    else if (chunk_name == png_hIST)
     568                 :    {
     569                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     570                 :       {
     571                 :          png_push_save_buffer(png_ptr);
     572                 :          return;
     573                 :       }
     574                 : 
     575                 :       png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
     576                 :    }
     577                 : 
     578                 : #endif
     579                 : #ifdef PNG_READ_pHYs_SUPPORTED
     580                 :    else if (chunk_name == png_pHYs)
     581                 :    {
     582                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     583                 :       {
     584                 :          png_push_save_buffer(png_ptr);
     585                 :          return;
     586                 :       }
     587                 : 
     588                 :       png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
     589                 :    }
     590                 : 
     591                 : #endif
     592                 : #ifdef PNG_READ_oFFs_SUPPORTED
     593                 :    else if (chunk_name == png_oFFs)
     594                 :    {
     595                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     596                 :       {
     597                 :          png_push_save_buffer(png_ptr);
     598                 :          return;
     599                 :       }
     600                 : 
     601                 :       png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
     602                 :    }
     603                 : #endif
     604                 : 
     605                 : #ifdef PNG_READ_pCAL_SUPPORTED
     606                 :    else if (chunk_name == png_pCAL)
     607                 :    {
     608                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     609                 :       {
     610                 :          png_push_save_buffer(png_ptr);
     611                 :          return;
     612                 :       }
     613                 : 
     614                 :       png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
     615                 :    }
     616                 : 
     617                 : #endif
     618                 : #ifdef PNG_READ_sCAL_SUPPORTED
     619                 :    else if (chunk_name == png_sCAL)
     620                 :    {
     621                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     622                 :       {
     623                 :          png_push_save_buffer(png_ptr);
     624                 :          return;
     625                 :       }
     626                 : 
     627                 :       png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
     628                 :    }
     629                 : 
     630                 : #endif
     631                 : #ifdef PNG_READ_tIME_SUPPORTED
     632                 :    else if (chunk_name == png_tIME)
     633                 :    {
     634                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     635                 :       {
     636                 :          png_push_save_buffer(png_ptr);
     637                 :          return;
     638                 :       }
     639                 : 
     640                 :       png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
     641                 :    }
     642                 : 
     643                 : #endif
     644                 : #ifdef PNG_READ_tEXt_SUPPORTED
     645                 :    else if (chunk_name == png_tEXt)
     646                 :    {
     647                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     648                 :       {
     649                 :          png_push_save_buffer(png_ptr);
     650                 :          return;
     651                 :       }
     652                 : 
     653                 :       png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
     654                 :    }
     655                 : 
     656                 : #endif
     657                 : #ifdef PNG_READ_zTXt_SUPPORTED
     658                 :    else if (chunk_name == png_zTXt)
     659                 :    {
     660                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     661                 :       {
     662                 :          png_push_save_buffer(png_ptr);
     663                 :          return;
     664                 :       }
     665                 : 
     666                 :       png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
     667                 :    }
     668                 : 
     669                 : #endif
     670                 : #ifdef PNG_READ_iTXt_SUPPORTED
     671                 :    else if (chunk_name == png_iTXt)
     672                 :    {
     673                 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     674                 :       {
     675                 :          png_push_save_buffer(png_ptr);
     676                 :          return;
     677                 :       }
     678                 : 
     679                 :       png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
     680                 :    }
     681                 : 
     682                 : #endif
     683                 : 
     684                 : #ifdef PNG_READ_APNG_SUPPORTED
     685               1 :    else if (chunk_name == png_acTL)
     686                 :    {
     687               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     688                 :       {
     689               0 :          png_push_save_buffer(png_ptr);
     690               0 :          return;
     691                 :       }
     692               0 :       png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
     693                 :    }
     694                 : 
     695               1 :    else if (chunk_name == png_fcTL)
     696                 :    {
     697               0 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     698                 :       {
     699               0 :          png_push_save_buffer(png_ptr);
     700               0 :          return;
     701                 :       }
     702               0 :       png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
     703                 :    }
     704                 : #endif /* PNG_READ_APNG_SUPPORTED */
     705                 : 
     706                 :    else
     707                 :    {
     708               1 :       if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     709                 :       {
     710               0 :          png_push_save_buffer(png_ptr);
     711               0 :          return;
     712                 :       }
     713               1 :       png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
     714                 :    }
     715                 : 
     716              10 :    png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     717                 : }
     718                 : 
     719                 : void /* PRIVATE */
     720               1 : png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
     721                 : {
     722               1 :    png_ptr->process_mode = PNG_SKIP_MODE;
     723               1 :    png_ptr->skip_length = skip;
     724               1 : }
     725                 : 
     726                 : void /* PRIVATE */
     727               1 : png_push_crc_finish(png_structp png_ptr)
     728                 : {
     729               1 :    if (png_ptr->skip_length && png_ptr->save_buffer_size)
     730                 :    {
     731               0 :       png_size_t save_size = png_ptr->save_buffer_size;
     732               0 :       png_uint_32 skip_length = png_ptr->skip_length;
     733                 : 
     734                 :       /* We want the smaller of 'skip_length' and 'save_buffer_size', but
     735                 :        * they are of different types and we don't know which variable has the
     736                 :        * fewest bits.  Carefully select the smaller and cast it to the type of
     737                 :        * the larger - this cannot overflow.  Do not cast in the following test
     738                 :        * - it will break on either 16 or 64 bit platforms.
     739                 :        */
     740               0 :       if (skip_length < save_size)
     741               0 :          save_size = (png_size_t)skip_length;
     742                 : 
     743                 :       else
     744               0 :          skip_length = (png_uint_32)save_size;
     745                 : 
     746               0 :       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
     747                 : 
     748               0 :       png_ptr->skip_length -= skip_length;
     749               0 :       png_ptr->buffer_size -= save_size;
     750               0 :       png_ptr->save_buffer_size -= save_size;
     751               0 :       png_ptr->save_buffer_ptr += save_size;
     752                 :    }
     753               1 :    if (png_ptr->skip_length && png_ptr->current_buffer_size)
     754                 :    {
     755               1 :       png_size_t save_size = png_ptr->current_buffer_size;
     756               1 :       png_uint_32 skip_length = png_ptr->skip_length;
     757                 : 
     758                 :       /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
     759                 :        * the same problem exists as above and the same solution.
     760                 :        */
     761               1 :       if (skip_length < save_size)
     762               1 :          save_size = (png_size_t)skip_length;
     763                 : 
     764                 :       else
     765               0 :          skip_length = (png_uint_32)save_size;
     766                 : 
     767               1 :       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
     768                 : 
     769               1 :       png_ptr->skip_length -= skip_length;
     770               1 :       png_ptr->buffer_size -= save_size;
     771               1 :       png_ptr->current_buffer_size -= save_size;
     772               1 :       png_ptr->current_buffer_ptr += save_size;
     773                 :    }
     774               1 :    if (!png_ptr->skip_length)
     775                 :    {
     776               1 :       if (png_ptr->buffer_size < 4)
     777                 :       {
     778               0 :          png_push_save_buffer(png_ptr);
     779               0 :          return;
     780                 :       }
     781                 : 
     782               1 :       png_crc_finish(png_ptr, 0);
     783               1 :       png_ptr->process_mode = PNG_READ_CHUNK_MODE;
     784                 :    }
     785                 : }
     786                 : 
     787                 : void PNGCBAPI
     788              57 : png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
     789                 : {
     790                 :    png_bytep ptr;
     791                 : 
     792              57 :    if (png_ptr == NULL)
     793               0 :       return;
     794                 : 
     795              57 :    ptr = buffer;
     796              57 :    if (png_ptr->save_buffer_size)
     797                 :    {
     798                 :       png_size_t save_size;
     799                 : 
     800               0 :       if (length < png_ptr->save_buffer_size)
     801               0 :          save_size = length;
     802                 : 
     803                 :       else
     804               0 :          save_size = png_ptr->save_buffer_size;
     805                 : 
     806               0 :       png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
     807               0 :       length -= save_size;
     808               0 :       ptr += save_size;
     809               0 :       png_ptr->buffer_size -= save_size;
     810               0 :       png_ptr->save_buffer_size -= save_size;
     811               0 :       png_ptr->save_buffer_ptr += save_size;
     812                 :    }
     813              57 :    if (length && png_ptr->current_buffer_size)
     814                 :    {
     815                 :       png_size_t save_size;
     816                 : 
     817              57 :       if (length < png_ptr->current_buffer_size)
     818              53 :          save_size = length;
     819                 : 
     820                 :       else
     821               4 :          save_size = png_ptr->current_buffer_size;
     822                 : 
     823              57 :       png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
     824              57 :       png_ptr->buffer_size -= save_size;
     825              57 :       png_ptr->current_buffer_size -= save_size;
     826              57 :       png_ptr->current_buffer_ptr += save_size;
     827                 :    }
     828                 : }
     829                 : 
     830                 : void /* PRIVATE */
     831               0 : png_push_save_buffer(png_structp png_ptr)
     832                 : {
     833               0 :    if (png_ptr->save_buffer_size)
     834                 :    {
     835               0 :       if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
     836                 :       {
     837                 :          png_size_t i, istop;
     838                 :          png_bytep sp;
     839                 :          png_bytep dp;
     840                 : 
     841               0 :          istop = png_ptr->save_buffer_size;
     842               0 :          for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
     843               0 :              i < istop; i++, sp++, dp++)
     844                 :          {
     845               0 :             *dp = *sp;
     846                 :          }
     847                 :       }
     848                 :    }
     849               0 :    if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
     850               0 :        png_ptr->save_buffer_max)
     851                 :    {
     852                 :       png_size_t new_max;
     853                 :       png_bytep old_buffer;
     854                 : 
     855               0 :       if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
     856               0 :           (png_ptr->current_buffer_size + 256))
     857                 :       {
     858               0 :          png_error(png_ptr, "Potential overflow of save_buffer");
     859                 :       }
     860                 : 
     861               0 :       new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
     862               0 :       old_buffer = png_ptr->save_buffer;
     863               0 :       png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, new_max);
     864                 : 
     865               0 :       if (png_ptr->save_buffer == NULL)
     866                 :       {
     867               0 :          png_free(png_ptr, old_buffer);
     868               0 :          png_error(png_ptr, "Insufficient memory for save_buffer");
     869                 :       }
     870                 : 
     871               0 :       png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
     872               0 :       png_free(png_ptr, old_buffer);
     873               0 :       png_ptr->save_buffer_max = new_max;
     874                 :    }
     875               0 :    if (png_ptr->current_buffer_size)
     876                 :    {
     877               0 :       png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
     878               0 :          png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
     879               0 :       png_ptr->save_buffer_size += png_ptr->current_buffer_size;
     880               0 :       png_ptr->current_buffer_size = 0;
     881                 :    }
     882               0 :    png_ptr->save_buffer_ptr = png_ptr->save_buffer;
     883               0 :    png_ptr->buffer_size = 0;
     884               0 : }
     885                 : 
     886                 : void /* PRIVATE */
     887              20 : png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
     888                 :    png_size_t buffer_length)
     889                 : {
     890              20 :    png_ptr->current_buffer = buffer;
     891              20 :    png_ptr->current_buffer_size = buffer_length;
     892              20 :    png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
     893              20 :    png_ptr->current_buffer_ptr = png_ptr->current_buffer;
     894              20 : }
     895                 : 
     896                 : void /* PRIVATE */
     897              26 : png_push_read_IDAT(png_structp png_ptr)
     898                 : {
     899              26 :    if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
     900                 :    {
     901                 :       png_byte chunk_length[4];
     902                 :       png_byte chunk_tag[4];
     903                 : 
     904                 :       /* TODO: this code can be commoned up with the same code in push_read */
     905                 : #ifdef PNG_READ_APNG_SUPPORTED
     906               6 :       if (png_ptr->buffer_size < 12)
     907                 : #else
     908                 :       if (png_ptr->buffer_size < 8)
     909                 : #endif
     910                 :       {
     911               0 :          png_push_save_buffer(png_ptr);
     912               0 :          return;
     913                 :       }
     914                 : 
     915               6 :       png_push_fill_buffer(png_ptr, chunk_length, 4);
     916               6 :       png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
     917               6 :       png_reset_crc(png_ptr);
     918               6 :       png_crc_read(png_ptr, chunk_tag, 4);
     919               6 :       png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
     920               6 :       png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
     921                 : 
     922                 : #ifdef PNG_READ_APNG_SUPPORTED
     923               6 :       if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
     924                 :       {
     925               0 :           if (png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)
     926                 :           {
     927               0 :               png_ptr->process_mode = PNG_READ_CHUNK_MODE;
     928               0 :               if (png_ptr->frame_end_fn != NULL)
     929               0 :                  (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
     930               0 :               png_ptr->num_frames_read++;
     931               0 :               return;
     932                 :           }
     933                 :           else
     934                 :           {
     935               0 :               if (png_ptr->chunk_name == png_IEND)
     936               0 :                   png_error(png_ptr, "Not enough image data");
     937               0 :               if (png_ptr->push_length + 4 > png_ptr->buffer_size)
     938                 :               {
     939               0 :                  png_push_save_buffer(png_ptr);
     940               0 :                  return;
     941                 :               }
     942                 :               png_warning(png_ptr, "Skipping (ignoring) a chunk between "
     943                 :                                    "APNG chunks");
     944               0 :               png_crc_finish(png_ptr, png_ptr->push_length);
     945               0 :               png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
     946               0 :               return;
     947                 :           }
     948                 :       }
     949                 :       else
     950                 : #endif
     951                 : #ifdef PNG_READ_APNG_SUPPORTED
     952               6 :       if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0)
     953                 : #else
     954                 :       if (png_ptr->chunk_name != png_IDAT)
     955                 : #endif
     956                 :       {
     957               4 :          png_ptr->process_mode = PNG_READ_CHUNK_MODE;
     958                 : 
     959               4 :          if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
     960               0 :             png_error(png_ptr, "Not enough compressed data");
     961                 : 
     962                 : #ifdef PNG_READ_APNG_SUPPORTED
     963               4 :          if (png_ptr->frame_end_fn != NULL)
     964               0 :             (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read);
     965               4 :          png_ptr->num_frames_read++;
     966                 : #endif
     967                 : 
     968               4 :          return;
     969                 :       }
     970                 : 
     971               2 :       png_ptr->idat_size = png_ptr->push_length;
     972                 : 
     973                 : #ifdef PNG_READ_APNG_SUPPORTED
     974               2 :       if (png_ptr->num_frames_read > 0)
     975                 :       {
     976               0 :          png_ensure_sequence_number(png_ptr, 4);
     977               0 :          png_ptr->idat_size -= 4;
     978                 :       }
     979                 : #endif
     980                 :    }
     981                 : 
     982              22 :    if (png_ptr->idat_size && png_ptr->save_buffer_size)
     983                 :    {
     984               0 :       png_size_t save_size = png_ptr->save_buffer_size;
     985               0 :       png_uint_32 idat_size = png_ptr->idat_size;
     986                 : 
     987                 :       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
     988                 :        * are of different types and we don't know which variable has the fewest
     989                 :        * bits.  Carefully select the smaller and cast it to the type of the
     990                 :        * larger - this cannot overflow.  Do not cast in the following test - it
     991                 :        * will break on either 16 or 64 bit platforms.
     992                 :        */
     993               0 :       if (idat_size < save_size)
     994               0 :          save_size = (png_size_t)idat_size;
     995                 : 
     996                 :       else
     997               0 :          idat_size = (png_uint_32)save_size;
     998                 : 
     999               0 :       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
    1000                 : 
    1001               0 :       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
    1002                 : 
    1003               0 :       png_ptr->idat_size -= idat_size;
    1004               0 :       png_ptr->buffer_size -= save_size;
    1005               0 :       png_ptr->save_buffer_size -= save_size;
    1006               0 :       png_ptr->save_buffer_ptr += save_size;
    1007                 :    }
    1008                 : 
    1009              22 :    if (png_ptr->idat_size && png_ptr->current_buffer_size)
    1010                 :    {
    1011              22 :       png_size_t save_size = png_ptr->current_buffer_size;
    1012              22 :       png_uint_32 idat_size = png_ptr->idat_size;
    1013                 : 
    1014                 :       /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
    1015                 :        * are of different types and we don't know which variable has the fewest
    1016                 :        * bits.  Carefully select the smaller and cast it to the type of the
    1017                 :        * larger - this cannot overflow.
    1018                 :        */
    1019              22 :       if (idat_size < save_size)
    1020               6 :          save_size = (png_size_t)idat_size;
    1021                 : 
    1022                 :       else
    1023              16 :          idat_size = (png_uint_32)save_size;
    1024                 : 
    1025              22 :       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
    1026                 : 
    1027              22 :       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
    1028                 : 
    1029              22 :       png_ptr->idat_size -= idat_size;
    1030              22 :       png_ptr->buffer_size -= save_size;
    1031              22 :       png_ptr->current_buffer_size -= save_size;
    1032              22 :       png_ptr->current_buffer_ptr += save_size;
    1033                 :    }
    1034              22 :    if (!png_ptr->idat_size)
    1035                 :    {
    1036               6 :       if (png_ptr->buffer_size < 4)
    1037                 :       {
    1038               0 :          png_push_save_buffer(png_ptr);
    1039               0 :          return;
    1040                 :       }
    1041                 : 
    1042               6 :       png_crc_finish(png_ptr, 0);
    1043               6 :       png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
    1044               6 :       png_ptr->mode |= PNG_AFTER_IDAT;
    1045                 :    }
    1046                 : }
    1047                 : 
    1048                 : void /* PRIVATE */
    1049              22 : png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    1050                 :    png_size_t buffer_length)
    1051                 : {
    1052                 :    /* The caller checks for a non-zero buffer length. */
    1053              22 :    if (!(buffer_length > 0) || buffer == NULL)
    1054               0 :       png_error(png_ptr, "No IDAT data (internal error)");
    1055                 : 
    1056                 :    /* This routine must process all the data it has been given
    1057                 :     * before returning, calling the row callback as required to
    1058                 :     * handle the uncompressed results.
    1059                 :     */
    1060              22 :    png_ptr->zstream.next_in = buffer;
    1061              22 :    png_ptr->zstream.avail_in = (uInt)buffer_length;
    1062                 : 
    1063                 :    /* Keep going until the decompressed data is all processed
    1064                 :     * or the stream marked as finished.
    1065                 :     */
    1066             470 :    while (png_ptr->zstream.avail_in > 0 &&
    1067             213 :           !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    1068                 :    {
    1069                 :       int ret;
    1070                 : 
    1071                 :       /* We have data for zlib, but we must check that zlib
    1072                 :        * has someplace to put the results.  It doesn't matter
    1073                 :        * if we don't expect any results -- it may be the input
    1074                 :        * data is just the LZ end code.
    1075                 :        */
    1076             213 :       if (!(png_ptr->zstream.avail_out > 0))
    1077                 :       {
    1078             191 :          png_ptr->zstream.avail_out =
    1079             382 :              (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
    1080             382 :              png_ptr->iwidth) + 1;
    1081                 : 
    1082             191 :          png_ptr->zstream.next_out = png_ptr->row_buf;
    1083                 :       }
    1084                 : 
    1085                 :       /* Using Z_SYNC_FLUSH here means that an unterminated
    1086                 :        * LZ stream (a stream with a missing end code) can still
    1087                 :        * be handled, otherwise (Z_NO_FLUSH) a future zlib
    1088                 :        * implementation might defer output and therefore
    1089                 :        * change the current behavior (see comments in inflate.c
    1090                 :        * for why this doesn't happen at present with zlib 1.2.5).
    1091                 :        */
    1092             213 :       ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
    1093                 : 
    1094                 :       /* Check for any failure before proceeding. */
    1095             213 :       if (ret != Z_OK && ret != Z_STREAM_END)
    1096                 :       {
    1097                 :          /* Terminate the decompression. */
    1098               0 :          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    1099                 : 
    1100                 :          /* This may be a truncated stream (missing or
    1101                 :           * damaged end code).  Treat that as a warning.
    1102                 :           */
    1103               0 :          if (png_ptr->row_number >= png_ptr->num_rows ||
    1104               0 :              png_ptr->pass > 6)
    1105                 :             png_warning(png_ptr, "Truncated compressed data in IDAT");
    1106                 : 
    1107                 :          else
    1108               0 :             png_error(png_ptr, "Decompression error in IDAT");
    1109                 : 
    1110                 :          /* Skip the check on unprocessed input */
    1111               0 :          return;
    1112                 :       }
    1113                 : 
    1114                 :       /* Did inflate output any data? */
    1115             213 :       if (png_ptr->zstream.next_out != png_ptr->row_buf)
    1116                 :       {
    1117                 :          /* Is this unexpected data after the last row?
    1118                 :           * If it is, artificially terminate the LZ output
    1119                 :           * here.
    1120                 :           */
    1121             426 :          if (png_ptr->row_number >= png_ptr->num_rows ||
    1122             213 :              png_ptr->pass > 6)
    1123                 :          {
    1124                 :             /* Extra data. */
    1125                 :             png_warning(png_ptr, "Extra compressed data in IDAT");
    1126               0 :             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    1127                 : 
    1128                 :             /* Do no more processing; skip the unprocessed
    1129                 :              * input check below.
    1130                 :              */
    1131               0 :             return;
    1132                 :          }
    1133                 : 
    1134                 :          /* Do we have a complete row? */
    1135             213 :          if (png_ptr->zstream.avail_out == 0)
    1136             195 :             png_push_process_row(png_ptr);
    1137                 :       }
    1138                 : 
    1139                 :       /* And check for the end of the stream. */
    1140             213 :       if (ret == Z_STREAM_END)
    1141               4 :          png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    1142                 :    }
    1143                 : 
    1144                 :    /* All the data should have been processed, if anything
    1145                 :     * is left at this point we have bytes of IDAT data
    1146                 :     * after the zlib end code.
    1147                 :     */
    1148              22 :    if (png_ptr->zstream.avail_in > 0)
    1149                 :       png_warning(png_ptr, "Extra compression data in IDAT");
    1150                 : }
    1151                 : 
    1152                 : void /* PRIVATE */
    1153             195 : png_push_process_row(png_structp png_ptr)
    1154                 : {
    1155                 :    /* 1.5.6: row_info moved out of png_struct to a local here. */
    1156                 :    png_row_info row_info;
    1157                 : 
    1158             195 :    row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
    1159             195 :    row_info.color_type = png_ptr->color_type;
    1160             195 :    row_info.bit_depth = png_ptr->bit_depth;
    1161             195 :    row_info.channels = png_ptr->channels;
    1162             195 :    row_info.pixel_depth = png_ptr->pixel_depth;
    1163             195 :    row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
    1164                 : 
    1165             195 :    if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
    1166                 :    {
    1167             192 :       if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
    1168             384 :          png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
    1169             384 :             png_ptr->prev_row + 1, png_ptr->row_buf[0]);
    1170                 :       else
    1171               0 :          png_error(png_ptr, "bad adaptive filter value");
    1172                 :    }
    1173                 : 
    1174                 :    /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
    1175                 :     * 1.5.6, while the buffer really is this big in current versions of libpng
    1176                 :     * it may not be in the future, so this was changed just to copy the
    1177                 :     * interlaced row count:
    1178                 :     */
    1179             195 :    png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
    1180                 : 
    1181                 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    1182             195 :    if (png_ptr->transformations)
    1183             195 :       png_do_read_transformations(png_ptr, &row_info);
    1184                 : #endif
    1185                 : 
    1186                 :    /* The transformed pixel depth should match the depth now in row_info. */
    1187             195 :    if (png_ptr->transformed_pixel_depth == 0)
    1188                 :    {
    1189               4 :       png_ptr->transformed_pixel_depth = row_info.pixel_depth;
    1190               4 :       if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
    1191               0 :          png_error(png_ptr, "progressive row overflow");
    1192                 :    }
    1193                 : 
    1194             191 :    else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
    1195               0 :       png_error(png_ptr, "internal progressive row size calculation error");
    1196                 : 
    1197                 : 
    1198                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    1199                 :    /* Blow up interlaced rows to full size */
    1200             195 :    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
    1201                 :    {
    1202               0 :       if (png_ptr->pass < 6)
    1203               0 :          png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
    1204                 :             png_ptr->transformations);
    1205                 : 
    1206               0 :     switch (png_ptr->pass)
    1207                 :     {
    1208                 :          case 0:
    1209                 :          {
    1210                 :             int i;
    1211               0 :             for (i = 0; i < 8 && png_ptr->pass == 0; i++)
    1212                 :             {
    1213               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1214               0 :                png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
    1215                 :             }
    1216                 : 
    1217               0 :             if (png_ptr->pass == 2) /* Pass 1 might be empty */
    1218                 :             {
    1219               0 :                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    1220                 :                {
    1221               0 :                   png_push_have_row(png_ptr, NULL);
    1222               0 :                   png_read_push_finish_row(png_ptr);
    1223                 :                }
    1224                 :             }
    1225                 : 
    1226               0 :             if (png_ptr->pass == 4 && png_ptr->height <= 4)
    1227                 :             {
    1228               0 :                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    1229                 :                {
    1230               0 :                   png_push_have_row(png_ptr, NULL);
    1231               0 :                   png_read_push_finish_row(png_ptr);
    1232                 :                }
    1233                 :             }
    1234                 : 
    1235               0 :             if (png_ptr->pass == 6 && png_ptr->height <= 4)
    1236                 :             {
    1237               0 :                 png_push_have_row(png_ptr, NULL);
    1238               0 :                 png_read_push_finish_row(png_ptr);
    1239                 :             }
    1240                 : 
    1241               0 :             break;
    1242                 :          }
    1243                 : 
    1244                 :          case 1:
    1245                 :          {
    1246                 :             int i;
    1247               0 :             for (i = 0; i < 8 && png_ptr->pass == 1; i++)
    1248                 :             {
    1249               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1250               0 :                png_read_push_finish_row(png_ptr);
    1251                 :             }
    1252                 : 
    1253               0 :             if (png_ptr->pass == 2) /* Skip top 4 generated rows */
    1254                 :             {
    1255               0 :                for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    1256                 :                {
    1257               0 :                   png_push_have_row(png_ptr, NULL);
    1258               0 :                   png_read_push_finish_row(png_ptr);
    1259                 :                }
    1260                 :             }
    1261                 : 
    1262               0 :             break;
    1263                 :          }
    1264                 : 
    1265                 :          case 2:
    1266                 :          {
    1267                 :             int i;
    1268                 : 
    1269               0 :             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    1270                 :             {
    1271               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1272               0 :                png_read_push_finish_row(png_ptr);
    1273                 :             }
    1274                 : 
    1275               0 :             for (i = 0; i < 4 && png_ptr->pass == 2; i++)
    1276                 :             {
    1277               0 :                png_push_have_row(png_ptr, NULL);
    1278               0 :                png_read_push_finish_row(png_ptr);
    1279                 :             }
    1280                 : 
    1281               0 :             if (png_ptr->pass == 4) /* Pass 3 might be empty */
    1282                 :             {
    1283               0 :                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    1284                 :                {
    1285               0 :                   png_push_have_row(png_ptr, NULL);
    1286               0 :                   png_read_push_finish_row(png_ptr);
    1287                 :                }
    1288                 :             }
    1289                 : 
    1290               0 :             break;
    1291                 :          }
    1292                 : 
    1293                 :          case 3:
    1294                 :          {
    1295                 :             int i;
    1296                 : 
    1297               0 :             for (i = 0; i < 4 && png_ptr->pass == 3; i++)
    1298                 :             {
    1299               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1300               0 :                png_read_push_finish_row(png_ptr);
    1301                 :             }
    1302                 : 
    1303               0 :             if (png_ptr->pass == 4) /* Skip top two generated rows */
    1304                 :             {
    1305               0 :                for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    1306                 :                {
    1307               0 :                   png_push_have_row(png_ptr, NULL);
    1308               0 :                   png_read_push_finish_row(png_ptr);
    1309                 :                }
    1310                 :             }
    1311                 : 
    1312               0 :             break;
    1313                 :          }
    1314                 : 
    1315                 :          case 4:
    1316                 :          {
    1317                 :             int i;
    1318                 : 
    1319               0 :             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    1320                 :             {
    1321               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1322               0 :                png_read_push_finish_row(png_ptr);
    1323                 :             }
    1324                 : 
    1325               0 :             for (i = 0; i < 2 && png_ptr->pass == 4; i++)
    1326                 :             {
    1327               0 :                png_push_have_row(png_ptr, NULL);
    1328               0 :                png_read_push_finish_row(png_ptr);
    1329                 :             }
    1330                 : 
    1331               0 :             if (png_ptr->pass == 6) /* Pass 5 might be empty */
    1332                 :             {
    1333               0 :                png_push_have_row(png_ptr, NULL);
    1334               0 :                png_read_push_finish_row(png_ptr);
    1335                 :             }
    1336                 : 
    1337               0 :             break;
    1338                 :          }
    1339                 : 
    1340                 :          case 5:
    1341                 :          {
    1342                 :             int i;
    1343                 : 
    1344               0 :             for (i = 0; i < 2 && png_ptr->pass == 5; i++)
    1345                 :             {
    1346               0 :                png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1347               0 :                png_read_push_finish_row(png_ptr);
    1348                 :             }
    1349                 : 
    1350               0 :             if (png_ptr->pass == 6) /* Skip top generated row */
    1351                 :             {
    1352               0 :                png_push_have_row(png_ptr, NULL);
    1353               0 :                png_read_push_finish_row(png_ptr);
    1354                 :             }
    1355                 : 
    1356               0 :             break;
    1357                 :          }
    1358                 : 
    1359                 :          default:
    1360                 :          case 6:
    1361                 :          {
    1362               0 :             png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1363               0 :             png_read_push_finish_row(png_ptr);
    1364                 : 
    1365               0 :             if (png_ptr->pass != 6)
    1366               0 :                break;
    1367                 : 
    1368               0 :             png_push_have_row(png_ptr, NULL);
    1369               0 :             png_read_push_finish_row(png_ptr);
    1370                 :          }
    1371                 :       }
    1372               0 :    }
    1373                 :    else
    1374                 : #endif
    1375                 :    {
    1376             195 :       png_push_have_row(png_ptr, png_ptr->row_buf + 1);
    1377             195 :       png_read_push_finish_row(png_ptr);
    1378                 :    }
    1379             195 : }
    1380                 : 
    1381                 : void /* PRIVATE */
    1382             195 : png_read_push_finish_row(png_structp png_ptr)
    1383                 : {
    1384                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    1385                 :    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    1386                 : 
    1387                 :    /* Start of interlace block */
    1388                 :    static PNG_CONST png_byte FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
    1389                 : 
    1390                 :    /* Offset to next interlace block */
    1391                 :    static PNG_CONST png_byte FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
    1392                 : 
    1393                 :    /* Start of interlace block in the y direction */
    1394                 :    static PNG_CONST png_byte FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
    1395                 : 
    1396                 :    /* Offset to next interlace block in the y direction */
    1397                 :    static PNG_CONST png_byte FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
    1398                 : 
    1399                 :    /* Height of interlace block.  This is not currently used - if you need
    1400                 :     * it, uncomment it here and in png.h
    1401                 :    static PNG_CONST png_byte FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
    1402                 :    */
    1403                 : #endif
    1404                 : 
    1405             195 :    png_ptr->row_number++;
    1406             195 :    if (png_ptr->row_number < png_ptr->num_rows)
    1407             191 :       return;
    1408                 : 
    1409                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    1410               4 :    if (png_ptr->interlaced)
    1411                 :    {
    1412               0 :       png_ptr->row_number = 0;
    1413               0 :       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
    1414                 : 
    1415                 :       do
    1416                 :       {
    1417               0 :          png_ptr->pass++;
    1418               0 :          if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
    1419               0 :              (png_ptr->pass == 3 && png_ptr->width < 3) ||
    1420               0 :              (png_ptr->pass == 5 && png_ptr->width < 2))
    1421               0 :             png_ptr->pass++;
    1422                 : 
    1423               0 :          if (png_ptr->pass > 7)
    1424               0 :             png_ptr->pass--;
    1425                 : 
    1426               0 :          if (png_ptr->pass >= 7)
    1427               0 :             break;
    1428                 : 
    1429               0 :          png_ptr->iwidth = (png_ptr->width +
    1430               0 :              png_pass_inc[png_ptr->pass] - 1 -
    1431               0 :              png_pass_start[png_ptr->pass]) /
    1432               0 :              png_pass_inc[png_ptr->pass];
    1433                 : 
    1434               0 :          if (png_ptr->transformations & PNG_INTERLACE)
    1435               0 :             break;
    1436                 : 
    1437               0 :          png_ptr->num_rows = (png_ptr->height +
    1438               0 :              png_pass_yinc[png_ptr->pass] - 1 -
    1439               0 :              png_pass_ystart[png_ptr->pass]) /
    1440               0 :              png_pass_yinc[png_ptr->pass];
    1441                 : 
    1442               0 :       } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
    1443                 :    }
    1444                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    1445                 : }
    1446                 : 
    1447                 : #ifdef PNG_READ_tEXt_SUPPORTED
    1448                 : void /* PRIVATE */
    1449                 : png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    1450                 :     length)
    1451                 : {
    1452                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
    1453                 :       {
    1454                 :          PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
    1455                 :          png_error(png_ptr, "Out of place tEXt");
    1456                 :          /* NOT REACHED */
    1457                 :       }
    1458                 : 
    1459                 : #ifdef PNG_MAX_MALLOC_64K
    1460                 :    png_ptr->skip_length = 0;  /* This may not be necessary */
    1461                 : 
    1462                 :    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
    1463                 :    {
    1464                 :       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
    1465                 :       png_ptr->skip_length = length - (png_uint_32)65535L;
    1466                 :       length = (png_uint_32)65535L;
    1467                 :    }
    1468                 : #endif
    1469                 : 
    1470                 :    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
    1471                 :    png_ptr->current_text[length] = '\0';
    1472                 :    png_ptr->current_text_ptr = png_ptr->current_text;
    1473                 :    png_ptr->current_text_size = (png_size_t)length;
    1474                 :    png_ptr->current_text_left = (png_size_t)length;
    1475                 :    png_ptr->process_mode = PNG_READ_tEXt_MODE;
    1476                 : }
    1477                 : 
    1478                 : void /* PRIVATE */
    1479                 : png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
    1480                 : {
    1481                 :    if (png_ptr->buffer_size && png_ptr->current_text_left)
    1482                 :    {
    1483                 :       png_size_t text_size;
    1484                 : 
    1485                 :       if (png_ptr->buffer_size < png_ptr->current_text_left)
    1486                 :          text_size = png_ptr->buffer_size;
    1487                 : 
    1488                 :       else
    1489                 :          text_size = png_ptr->current_text_left;
    1490                 : 
    1491                 :       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
    1492                 :       png_ptr->current_text_left -= text_size;
    1493                 :       png_ptr->current_text_ptr += text_size;
    1494                 :    }
    1495                 :    if (!(png_ptr->current_text_left))
    1496                 :    {
    1497                 :       png_textp text_ptr;
    1498                 :       png_charp text;
    1499                 :       png_charp key;
    1500                 :       int ret;
    1501                 : 
    1502                 :       if (png_ptr->buffer_size < 4)
    1503                 :       {
    1504                 :          png_push_save_buffer(png_ptr);
    1505                 :          return;
    1506                 :       }
    1507                 : 
    1508                 :       png_push_crc_finish(png_ptr);
    1509                 : 
    1510                 : #ifdef PNG_MAX_MALLOC_64K
    1511                 :       if (png_ptr->skip_length)
    1512                 :          return;
    1513                 : #endif
    1514                 : 
    1515                 :       key = png_ptr->current_text;
    1516                 : 
    1517                 :       for (text = key; *text; text++)
    1518                 :          /* Empty loop */ ;
    1519                 : 
    1520                 :       if (text < key + png_ptr->current_text_size)
    1521                 :          text++;
    1522                 : 
    1523                 :       text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text));
    1524                 :       text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
    1525                 :       text_ptr->key = key;
    1526                 :       text_ptr->itxt_length = 0;
    1527                 :       text_ptr->lang = NULL;
    1528                 :       text_ptr->lang_key = NULL;
    1529                 :       text_ptr->text = text;
    1530                 : 
    1531                 :       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    1532                 : 
    1533                 :       png_free(png_ptr, key);
    1534                 :       png_free(png_ptr, text_ptr);
    1535                 :       png_ptr->current_text = NULL;
    1536                 : 
    1537                 :       if (ret)
    1538                 :          png_warning(png_ptr, "Insufficient memory to store text chunk");
    1539                 :    }
    1540                 : }
    1541                 : #endif
    1542                 : 
    1543                 : #ifdef PNG_READ_zTXt_SUPPORTED
    1544                 : void /* PRIVATE */
    1545                 : png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    1546                 :    length)
    1547                 : {
    1548                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
    1549                 :    {
    1550                 :       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
    1551                 :       png_error(png_ptr, "Out of place zTXt");
    1552                 :       /* NOT REACHED */
    1553                 :    }
    1554                 : 
    1555                 : #ifdef PNG_MAX_MALLOC_64K
    1556                 :    /* We can't handle zTXt chunks > 64K, since we don't have enough space
    1557                 :     * to be able to store the uncompressed data.  Actually, the threshold
    1558                 :     * is probably around 32K, but it isn't as definite as 64K is.
    1559                 :     */
    1560                 :    if (length > (png_uint_32)65535L)
    1561                 :    {
    1562                 :       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
    1563                 :       png_push_crc_skip(png_ptr, length);
    1564                 :       return;
    1565                 :    }
    1566                 : #endif
    1567                 : 
    1568                 :    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
    1569                 :    png_ptr->current_text[length] = '\0';
    1570                 :    png_ptr->current_text_ptr = png_ptr->current_text;
    1571                 :    png_ptr->current_text_size = (png_size_t)length;
    1572                 :    png_ptr->current_text_left = (png_size_t)length;
    1573                 :    png_ptr->process_mode = PNG_READ_zTXt_MODE;
    1574                 : }
    1575                 : 
    1576                 : void /* PRIVATE */
    1577                 : png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
    1578                 : {
    1579                 :    if (png_ptr->buffer_size && png_ptr->current_text_left)
    1580                 :    {
    1581                 :       png_size_t text_size;
    1582                 : 
    1583                 :       if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
    1584                 :          text_size = png_ptr->buffer_size;
    1585                 : 
    1586                 :       else
    1587                 :          text_size = png_ptr->current_text_left;
    1588                 : 
    1589                 :       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
    1590                 :       png_ptr->current_text_left -= text_size;
    1591                 :       png_ptr->current_text_ptr += text_size;
    1592                 :    }
    1593                 :    if (!(png_ptr->current_text_left))
    1594                 :    {
    1595                 :       png_textp text_ptr;
    1596                 :       png_charp text;
    1597                 :       png_charp key;
    1598                 :       int ret;
    1599                 :       png_size_t text_size, key_size;
    1600                 : 
    1601                 :       if (png_ptr->buffer_size < 4)
    1602                 :       {
    1603                 :          png_push_save_buffer(png_ptr);
    1604                 :          return;
    1605                 :       }
    1606                 : 
    1607                 :       png_push_crc_finish(png_ptr);
    1608                 : 
    1609                 :       key = png_ptr->current_text;
    1610                 : 
    1611                 :       for (text = key; *text; text++)
    1612                 :          /* Empty loop */ ;
    1613                 : 
    1614                 :       /* zTXt can't have zero text */
    1615                 :       if (text >= key + png_ptr->current_text_size)
    1616                 :       {
    1617                 :          png_ptr->current_text = NULL;
    1618                 :          png_free(png_ptr, key);
    1619                 :          return;
    1620                 :       }
    1621                 : 
    1622                 :       text++;
    1623                 : 
    1624                 :       if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
    1625                 :       {
    1626                 :          png_ptr->current_text = NULL;
    1627                 :          png_free(png_ptr, key);
    1628                 :          return;
    1629                 :       }
    1630                 : 
    1631                 :       text++;
    1632                 : 
    1633                 :       png_ptr->zstream.next_in = (png_bytep)text;
    1634                 :       png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
    1635                 :           (text - key));
    1636                 :       png_ptr->zstream.next_out = png_ptr->zbuf;
    1637                 :       png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
    1638                 : 
    1639                 :       key_size = text - key;
    1640                 :       text_size = 0;
    1641                 :       text = NULL;
    1642                 :       ret = Z_STREAM_END;
    1643                 : 
    1644                 :       while (png_ptr->zstream.avail_in)
    1645                 :       {
    1646                 :          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
    1647                 :          if (ret != Z_OK && ret != Z_STREAM_END)
    1648                 :          {
    1649                 :             inflateReset(&png_ptr->zstream);
    1650                 :             png_ptr->zstream.avail_in = 0;
    1651                 :             png_ptr->current_text = NULL;
    1652                 :             png_free(png_ptr, key);
    1653                 :             png_free(png_ptr, text);
    1654                 :             return;
    1655                 :          }
    1656                 : 
    1657                 :          if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
    1658                 :          {
    1659                 :             if (text == NULL)
    1660                 :             {
    1661                 :                text = (png_charp)png_malloc(png_ptr,
    1662                 :                    (png_ptr->zbuf_size
    1663                 :                    - png_ptr->zstream.avail_out + key_size + 1));
    1664                 : 
    1665                 :                png_memcpy(text + key_size, png_ptr->zbuf,
    1666                 :                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
    1667                 : 
    1668                 :                png_memcpy(text, key, key_size);
    1669                 : 
    1670                 :                text_size = key_size + png_ptr->zbuf_size -
    1671                 :                    png_ptr->zstream.avail_out;
    1672                 : 
    1673                 :                *(text + text_size) = '\0';
    1674                 :             }
    1675                 : 
    1676                 :             else
    1677                 :             {
    1678                 :                png_charp tmp;
    1679                 : 
    1680                 :                tmp = text;
    1681                 :                text = (png_charp)png_malloc(png_ptr, text_size +
    1682                 :                    (png_ptr->zbuf_size
    1683                 :                    - png_ptr->zstream.avail_out + 1));
    1684                 : 
    1685                 :                png_memcpy(text, tmp, text_size);
    1686                 :                png_free(png_ptr, tmp);
    1687                 : 
    1688                 :                png_memcpy(text + text_size, png_ptr->zbuf,
    1689                 :                    png_ptr->zbuf_size - png_ptr->zstream.avail_out);
    1690                 : 
    1691                 :                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
    1692                 :                *(text + text_size) = '\0';
    1693                 :             }
    1694                 : 
    1695                 :             if (ret != Z_STREAM_END)
    1696                 :             {
    1697                 :                png_ptr->zstream.next_out = png_ptr->zbuf;
    1698                 :                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
    1699                 :             }
    1700                 :          }
    1701                 :          else
    1702                 :          {
    1703                 :             break;
    1704                 :          }
    1705                 : 
    1706                 :          if (ret == Z_STREAM_END)
    1707                 :             break;
    1708                 :       }
    1709                 : 
    1710                 :       inflateReset(&png_ptr->zstream);
    1711                 :       png_ptr->zstream.avail_in = 0;
    1712                 : 
    1713                 :       if (ret != Z_STREAM_END)
    1714                 :       {
    1715                 :          png_ptr->current_text = NULL;
    1716                 :          png_free(png_ptr, key);
    1717                 :          png_free(png_ptr, text);
    1718                 :          return;
    1719                 :       }
    1720                 : 
    1721                 :       png_ptr->current_text = NULL;
    1722                 :       png_free(png_ptr, key);
    1723                 :       key = text;
    1724                 :       text += key_size;
    1725                 : 
    1726                 :       text_ptr = (png_textp)png_malloc(png_ptr,
    1727                 :           png_sizeof(png_text));
    1728                 :       text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
    1729                 :       text_ptr->key = key;
    1730                 :       text_ptr->itxt_length = 0;
    1731                 :       text_ptr->lang = NULL;
    1732                 :       text_ptr->lang_key = NULL;
    1733                 :       text_ptr->text = text;
    1734                 : 
    1735                 :       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    1736                 : 
    1737                 :       png_free(png_ptr, key);
    1738                 :       png_free(png_ptr, text_ptr);
    1739                 : 
    1740                 :       if (ret)
    1741                 :          png_warning(png_ptr, "Insufficient memory to store text chunk");
    1742                 :    }
    1743                 : }
    1744                 : #endif
    1745                 : 
    1746                 : #ifdef PNG_READ_iTXt_SUPPORTED
    1747                 : void /* PRIVATE */
    1748                 : png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
    1749                 :     length)
    1750                 : {
    1751                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
    1752                 :    {
    1753                 :       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
    1754                 :       png_error(png_ptr, "Out of place iTXt");
    1755                 :       /* NOT REACHED */
    1756                 :    }
    1757                 : 
    1758                 : #ifdef PNG_MAX_MALLOC_64K
    1759                 :    png_ptr->skip_length = 0;  /* This may not be necessary */
    1760                 : 
    1761                 :    if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
    1762                 :    {
    1763                 :       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
    1764                 :       png_ptr->skip_length = length - (png_uint_32)65535L;
    1765                 :       length = (png_uint_32)65535L;
    1766                 :    }
    1767                 : #endif
    1768                 : 
    1769                 :    png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
    1770                 :    png_ptr->current_text[length] = '\0';
    1771                 :    png_ptr->current_text_ptr = png_ptr->current_text;
    1772                 :    png_ptr->current_text_size = (png_size_t)length;
    1773                 :    png_ptr->current_text_left = (png_size_t)length;
    1774                 :    png_ptr->process_mode = PNG_READ_iTXt_MODE;
    1775                 : }
    1776                 : 
    1777                 : void /* PRIVATE */
    1778                 : png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
    1779                 : {
    1780                 : 
    1781                 :    if (png_ptr->buffer_size && png_ptr->current_text_left)
    1782                 :    {
    1783                 :       png_size_t text_size;
    1784                 : 
    1785                 :       if (png_ptr->buffer_size < png_ptr->current_text_left)
    1786                 :          text_size = png_ptr->buffer_size;
    1787                 : 
    1788                 :       else
    1789                 :          text_size = png_ptr->current_text_left;
    1790                 : 
    1791                 :       png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
    1792                 :       png_ptr->current_text_left -= text_size;
    1793                 :       png_ptr->current_text_ptr += text_size;
    1794                 :    }
    1795                 : 
    1796                 :    if (!(png_ptr->current_text_left))
    1797                 :    {
    1798                 :       png_textp text_ptr;
    1799                 :       png_charp key;
    1800                 :       int comp_flag;
    1801                 :       png_charp lang;
    1802                 :       png_charp lang_key;
    1803                 :       png_charp text;
    1804                 :       int ret;
    1805                 : 
    1806                 :       if (png_ptr->buffer_size < 4)
    1807                 :       {
    1808                 :          png_push_save_buffer(png_ptr);
    1809                 :          return;
    1810                 :       }
    1811                 : 
    1812                 :       png_push_crc_finish(png_ptr);
    1813                 : 
    1814                 : #ifdef PNG_MAX_MALLOC_64K
    1815                 :       if (png_ptr->skip_length)
    1816                 :          return;
    1817                 : #endif
    1818                 : 
    1819                 :       key = png_ptr->current_text;
    1820                 : 
    1821                 :       for (lang = key; *lang; lang++)
    1822                 :          /* Empty loop */ ;
    1823                 : 
    1824                 :       if (lang < key + png_ptr->current_text_size - 3)
    1825                 :          lang++;
    1826                 : 
    1827                 :       comp_flag = *lang++;
    1828                 :       lang++;     /* Skip comp_type, always zero */
    1829                 : 
    1830                 :       for (lang_key = lang; *lang_key; lang_key++)
    1831                 :          /* Empty loop */ ;
    1832                 : 
    1833                 :       lang_key++;        /* Skip NUL separator */
    1834                 : 
    1835                 :       text=lang_key;
    1836                 : 
    1837                 :       if (lang_key < key + png_ptr->current_text_size - 1)
    1838                 :       {
    1839                 :          for (; *text; text++)
    1840                 :             /* Empty loop */ ;
    1841                 :       }
    1842                 : 
    1843                 :       if (text < key + png_ptr->current_text_size)
    1844                 :          text++;
    1845                 : 
    1846                 :       text_ptr = (png_textp)png_malloc(png_ptr,
    1847                 :           png_sizeof(png_text));
    1848                 : 
    1849                 :       text_ptr->compression = comp_flag + 2;
    1850                 :       text_ptr->key = key;
    1851                 :       text_ptr->lang = lang;
    1852                 :       text_ptr->lang_key = lang_key;
    1853                 :       text_ptr->text = text;
    1854                 :       text_ptr->text_length = 0;
    1855                 :       text_ptr->itxt_length = png_strlen(text);
    1856                 : 
    1857                 :       ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    1858                 : 
    1859                 :       png_ptr->current_text = NULL;
    1860                 : 
    1861                 :       png_free(png_ptr, text_ptr);
    1862                 :       if (ret)
    1863                 :          png_warning(png_ptr, "Insufficient memory to store iTXt chunk");
    1864                 :    }
    1865                 : }
    1866                 : #endif
    1867                 : 
    1868                 : /* This function is called when we haven't found a handler for this
    1869                 :  * chunk.  If there isn't a problem with the chunk itself (ie a bad chunk
    1870                 :  * name or a critical chunk), the chunk is (currently) silently ignored.
    1871                 :  */
    1872                 : void /* PRIVATE */
    1873               1 : png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
    1874                 :     length)
    1875                 : {
    1876               1 :    png_uint_32 skip = 0;
    1877               1 :    png_uint_32 chunk_name = png_ptr->chunk_name;
    1878                 : 
    1879               1 :    if (PNG_CHUNK_CRITICAL(chunk_name))
    1880                 :    {
    1881                 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    1882                 :       if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
    1883                 :           PNG_HANDLE_CHUNK_ALWAYS
    1884                 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    1885                 :           && png_ptr->read_user_chunk_fn == NULL
    1886                 : #endif
    1887                 :           )
    1888                 : #endif
    1889               0 :          png_chunk_error(png_ptr, "unknown critical chunk");
    1890                 : 
    1891                 :       PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */
    1892                 :    }
    1893                 : 
    1894                 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    1895                 :    /* TODO: the code below is apparently just using the
    1896                 :     * png_struct::unknown_chunk member as a temporarily variable, it should be
    1897                 :     * possible to eliminate both it and the temporary buffer.
    1898                 :     */
    1899                 :    if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
    1900                 :    {
    1901                 : #ifdef PNG_MAX_MALLOC_64K
    1902                 :       if (length > 65535)
    1903                 :       {
    1904                 :          png_warning(png_ptr, "unknown chunk too large to fit in memory");
    1905                 :          skip = length - 65535;
    1906                 :          length = 65535;
    1907                 :       }
    1908                 : #endif
    1909                 :       /* This is just a record for the user; libpng doesn't use the character
    1910                 :        * form of the name.
    1911                 :        */
    1912                 :       PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
    1913                 : 
    1914                 :       png_ptr->unknown_chunk.size = length;
    1915                 : 
    1916                 :       if (length == 0)
    1917                 :          png_ptr->unknown_chunk.data = NULL;
    1918                 : 
    1919                 :       else
    1920                 :       {
    1921                 :          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
    1922                 :             png_ptr->unknown_chunk.size);
    1923                 :          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data,
    1924                 :             png_ptr->unknown_chunk.size);
    1925                 :       }
    1926                 : 
    1927                 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    1928                 :       if (png_ptr->read_user_chunk_fn != NULL)
    1929                 :       {
    1930                 :          /* Callback to user unknown chunk handler */
    1931                 :          int ret;
    1932                 :          ret = (*(png_ptr->read_user_chunk_fn))
    1933                 :              (png_ptr, &png_ptr->unknown_chunk);
    1934                 : 
    1935                 :          if (ret < 0)
    1936                 :             png_chunk_error(png_ptr, "error in user chunk");
    1937                 : 
    1938                 :          if (ret == 0)
    1939                 :          {
    1940                 :             if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
    1941                 :                if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
    1942                 :                    PNG_HANDLE_CHUNK_ALWAYS)
    1943                 :                   png_chunk_error(png_ptr, "unknown critical chunk");
    1944                 :             png_set_unknown_chunks(png_ptr, info_ptr,
    1945                 :                 &png_ptr->unknown_chunk, 1);
    1946                 :          }
    1947                 :       }
    1948                 : 
    1949                 :       else
    1950                 : #endif
    1951                 :          png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
    1952                 :       png_free(png_ptr, png_ptr->unknown_chunk.data);
    1953                 :       png_ptr->unknown_chunk.data = NULL;
    1954                 :    }
    1955                 : 
    1956                 :    else
    1957                 : #endif
    1958               1 :       skip=length;
    1959               1 :    png_push_crc_skip(png_ptr, skip);
    1960               1 : }
    1961                 : 
    1962                 : void /* PRIVATE */
    1963               4 : png_push_have_info(png_structp png_ptr, png_infop info_ptr)
    1964                 : {
    1965               4 :    if (png_ptr->info_fn != NULL)
    1966               4 :       (*(png_ptr->info_fn))(png_ptr, info_ptr);
    1967               4 : }
    1968                 : 
    1969                 : void /* PRIVATE */
    1970               4 : png_push_have_end(png_structp png_ptr, png_infop info_ptr)
    1971                 : {
    1972               4 :    if (png_ptr->end_fn != NULL)
    1973               4 :       (*(png_ptr->end_fn))(png_ptr, info_ptr);
    1974               4 : }
    1975                 : 
    1976                 : void /* PRIVATE */
    1977             195 : png_push_have_row(png_structp png_ptr, png_bytep row)
    1978                 : {
    1979             195 :    if (png_ptr->row_fn != NULL)
    1980             390 :       (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
    1981             195 :          (int)png_ptr->pass);
    1982             195 : }
    1983                 : 
    1984                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    1985                 : void PNGAPI
    1986               0 : png_progressive_combine_row (png_structp png_ptr, png_bytep old_row,
    1987                 :     png_const_bytep new_row)
    1988                 : {
    1989               0 :    if (png_ptr == NULL)
    1990               0 :       return;
    1991                 : 
    1992                 :    /* new_row is a flag here - if it is NULL then the app callback was called
    1993                 :     * from an empty row (see the calls to png_struct::row_fn below), otherwise
    1994                 :     * it must be png_ptr->row_buf+1
    1995                 :     */
    1996               0 :    if (new_row != NULL)
    1997               0 :       png_combine_row(png_ptr, old_row, 1/*display*/);
    1998                 : }
    1999                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    2000                 : 
    2001                 : void PNGAPI
    2002               4 : png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
    2003                 :     png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
    2004                 :     png_progressive_end_ptr end_fn)
    2005                 : {
    2006               4 :    if (png_ptr == NULL)
    2007               0 :       return;
    2008                 : 
    2009               4 :    png_ptr->info_fn = info_fn;
    2010               4 :    png_ptr->row_fn = row_fn;
    2011               4 :    png_ptr->end_fn = end_fn;
    2012                 : 
    2013               4 :    png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
    2014                 : }
    2015                 : 
    2016                 : #ifdef PNG_READ_APNG_SUPPORTED
    2017                 : void PNGAPI
    2018               0 : png_set_progressive_frame_fn(png_structp png_ptr,
    2019                 :    png_progressive_frame_ptr frame_info_fn,
    2020                 :    png_progressive_frame_ptr frame_end_fn)
    2021                 : {
    2022               0 :    png_ptr->frame_info_fn = frame_info_fn;
    2023               0 :    png_ptr->frame_end_fn = frame_end_fn;
    2024               0 : }
    2025                 : #endif
    2026                 : 
    2027                 : png_voidp PNGAPI
    2028             203 : png_get_progressive_ptr(png_const_structp png_ptr)
    2029                 : {
    2030             203 :    if (png_ptr == NULL)
    2031               0 :       return (NULL);
    2032                 : 
    2033             203 :    return png_ptr->io_ptr;
    2034                 : }
    2035                 : #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

Generated by: LCOV version 1.7