LCOV - code coverage report
Current view: directory - media/libpng - pngrutil.c (source / functions) Found Hit Coverage
Test: app.info Lines: 884 189 21.4 %
Date: 2012-06-02 Functions: 37 17 45.9 %

       1                 : 
       2                 : /* pngrutil.c - utilities to read a PNG file
       3                 :  *
       4                 :  * Last changed in libpng 1.5.9 [February 18, 2012]
       5                 :  * Copyright (c) 1998-2012 Glenn Randers-Pehrson
       6                 :  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
       7                 :  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
       8                 :  *
       9                 :  * This code is released under the libpng license.
      10                 :  * For conditions of distribution and use, see the disclaimer
      11                 :  * and license in png.h
      12                 :  *
      13                 :  * This file contains routines that are only called from within
      14                 :  * libpng itself during the course of reading an image.
      15                 :  */
      16                 : 
      17                 : #include "pngpriv.h"
      18                 : 
      19                 : #ifdef PNG_READ_SUPPORTED
      20                 : 
      21                 : #define png_strtod(p,a,b) strtod(a,b)
      22                 : 
      23                 : png_uint_32 PNGAPI
      24              24 : png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
      25                 : {
      26              24 :    png_uint_32 uval = png_get_uint_32(buf);
      27                 : 
      28              24 :    if (uval > PNG_UINT_31_MAX)
      29               0 :       png_error(png_ptr, "PNG unsigned integer out of range");
      30                 : 
      31              24 :    return (uval);
      32                 : }
      33                 : 
      34                 : #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
      35                 : /* The following is a variation on the above for use with the fixed
      36                 :  * point values used for gAMA and cHRM.  Instead of png_error it
      37                 :  * issues a warning and returns (-1) - an invalid value because both
      38                 :  * gAMA and cHRM use *unsigned* integers for fixed point values.
      39                 :  */
      40                 : #define PNG_FIXED_ERROR (-1)
      41                 : 
      42                 : static png_fixed_point /* PRIVATE */
      43               1 : png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
      44                 : {
      45               1 :    png_uint_32 uval = png_get_uint_32(buf);
      46                 : 
      47               1 :    if (uval <= PNG_UINT_31_MAX)
      48               1 :       return (png_fixed_point)uval; /* known to be in range */
      49                 : 
      50                 :    /* The caller can turn off the warning by passing NULL. */
      51                 :    if (png_ptr != NULL)
      52                 :       png_warning(png_ptr, "PNG fixed point integer out of range");
      53                 : 
      54               0 :    return PNG_FIXED_ERROR;
      55                 : }
      56                 : #endif
      57                 : 
      58                 : #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
      59                 : /* NOTE: the read macros will obscure these definitions, so that if
      60                 :  * PNG_USE_READ_MACROS is set the library will not use them internally,
      61                 :  * but the APIs will still be available externally.
      62                 :  *
      63                 :  * The parentheses around "PNGAPI function_name" in the following three
      64                 :  * functions are necessary because they allow the macros to co-exist with
      65                 :  * these (unused but exported) functions.
      66                 :  */
      67                 : 
      68                 : /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
      69                 : png_uint_32 (PNGAPI
      70                 : png_get_uint_32)(png_const_bytep buf)
      71                 : {
      72                 :    png_uint_32 uval =
      73                 :        ((png_uint_32)(*(buf    )) << 24) +
      74                 :        ((png_uint_32)(*(buf + 1)) << 16) +
      75                 :        ((png_uint_32)(*(buf + 2)) <<  8) +
      76                 :        ((png_uint_32)(*(buf + 3))      ) ;
      77                 : 
      78                 :    return uval;
      79                 : }
      80                 : 
      81                 : /* Grab a signed 32-bit integer from a buffer in big-endian format.  The
      82                 :  * data is stored in the PNG file in two's complement format and there
      83                 :  * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
      84                 :  * the following code does a two's complement to native conversion.
      85                 :  */
      86                 : png_int_32 (PNGAPI
      87                 : png_get_int_32)(png_const_bytep buf)
      88                 : {
      89                 :    png_uint_32 uval = png_get_uint_32(buf);
      90                 :    if ((uval & 0x80000000) == 0) /* non-negative */
      91                 :       return uval;
      92                 : 
      93                 :    uval = (uval ^ 0xffffffff) + 1;  /* 2's complement: -x = ~x+1 */
      94                 :    return -(png_int_32)uval;
      95                 : }
      96                 : 
      97                 : /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
      98                 : png_uint_16 (PNGAPI
      99                 : png_get_uint_16)(png_const_bytep buf)
     100                 : {
     101                 :    /* ANSI-C requires an int value to accomodate at least 16 bits so this
     102                 :     * works and allows the compiler not to worry about possible narrowing
     103                 :     * on 32 bit systems.  (Pre-ANSI systems did not make integers smaller
     104                 :     * than 16 bits either.)
     105                 :     */
     106                 :    unsigned int val =
     107                 :        ((unsigned int)(*buf) << 8) +
     108                 :        ((unsigned int)(*(buf + 1)));
     109                 : 
     110                 :    return (png_uint_16)val;
     111                 : }
     112                 : 
     113                 : #endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
     114                 : 
     115                 : /* Read and check the PNG file signature */
     116                 : void /* PRIVATE */
     117               0 : png_read_sig(png_structp png_ptr, png_infop info_ptr)
     118                 : {
     119                 :    png_size_t num_checked, num_to_check;
     120                 : 
     121                 :    /* Exit if the user application does not expect a signature. */
     122               0 :    if (png_ptr->sig_bytes >= 8)
     123               0 :       return;
     124                 : 
     125               0 :    num_checked = png_ptr->sig_bytes;
     126               0 :    num_to_check = 8 - num_checked;
     127                 : 
     128                 : #ifdef PNG_IO_STATE_SUPPORTED
     129                 :    png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
     130                 : #endif
     131                 : 
     132                 :    /* The signature must be serialized in a single I/O call. */
     133               0 :    png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
     134               0 :    png_ptr->sig_bytes = 8;
     135                 : 
     136               0 :    if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
     137                 :    {
     138               0 :       if (num_checked < 4 &&
     139               0 :           png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
     140               0 :          png_error(png_ptr, "Not a PNG file");
     141                 :       else
     142               0 :          png_error(png_ptr, "PNG file corrupted by ASCII conversion");
     143                 :    }
     144               0 :    if (num_checked < 3)
     145               0 :       png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
     146                 : }
     147                 : 
     148                 : /* Read the chunk header (length + type name).
     149                 :  * Put the type name into png_ptr->chunk_name, and return the length.
     150                 :  */
     151                 : png_uint_32 /* PRIVATE */
     152               0 : png_read_chunk_header(png_structp png_ptr)
     153                 : {
     154                 :    png_byte buf[8];
     155                 :    png_uint_32 length;
     156                 : 
     157                 : #ifdef PNG_IO_STATE_SUPPORTED
     158                 :    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
     159                 : #endif
     160                 : 
     161                 :    /* Read the length and the chunk name.
     162                 :     * This must be performed in a single I/O call.
     163                 :     */
     164               0 :    png_read_data(png_ptr, buf, 8);
     165               0 :    length = png_get_uint_31(png_ptr, buf);
     166                 : 
     167                 :    /* Put the chunk name into png_ptr->chunk_name. */
     168               0 :    png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
     169                 : 
     170                 :    png_debug2(0, "Reading %lx chunk, length = %lu",
     171                 :        (unsigned long)png_ptr->chunk_name, (unsigned long)length);
     172                 : 
     173                 :    /* Reset the crc and run it over the chunk name. */
     174               0 :    png_reset_crc(png_ptr);
     175               0 :    png_calculate_crc(png_ptr, buf + 4, 4);
     176                 : 
     177                 :    /* Check to see if chunk name is valid. */
     178               0 :    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
     179                 : 
     180                 : #ifdef PNG_IO_STATE_SUPPORTED
     181                 :    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
     182                 : #endif
     183                 : 
     184               0 :    return length;
     185                 : }
     186                 : 
     187                 : /* Read data, and (optionally) run it through the CRC. */
     188                 : void /* PRIVATE */
     189              21 : png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
     190                 : {
     191              21 :    if (png_ptr == NULL)
     192               0 :       return;
     193                 : 
     194              21 :    png_read_data(png_ptr, buf, length);
     195              21 :    png_calculate_crc(png_ptr, buf, length);
     196                 : }
     197                 : 
     198                 : /* Optionally skip data and then check the CRC.  Depending on whether we
     199                 :  * are reading a ancillary or critical chunk, and how the program has set
     200                 :  * things up, we may calculate the CRC on the data and print a message.
     201                 :  * Returns '1' if there was a CRC error, '0' otherwise.
     202                 :  */
     203                 : int /* PRIVATE */
     204              16 : png_crc_finish(png_structp png_ptr, png_uint_32 skip)
     205                 : {
     206                 :    png_size_t i;
     207              16 :    png_size_t istop = png_ptr->zbuf_size;
     208                 : 
     209              16 :    for (i = (png_size_t)skip; i > istop; i -= istop)
     210                 :    {
     211               0 :       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
     212                 :    }
     213                 : 
     214              16 :    if (i)
     215                 :    {
     216               0 :       png_crc_read(png_ptr, png_ptr->zbuf, i);
     217                 :    }
     218                 : 
     219              16 :    if (png_crc_error(png_ptr))
     220                 :    {
     221               0 :       if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
     222               0 :           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
     223               0 :           (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
     224                 :       {
     225                 :          png_chunk_warning(png_ptr, "CRC error");
     226                 :       }
     227                 : 
     228                 :       else
     229                 :       {
     230               0 :          png_chunk_benign_error(png_ptr, "CRC error");
     231                 :          return (0);
     232                 :       }
     233                 : 
     234               0 :       return (1);
     235                 :    }
     236                 : 
     237              16 :    return (0);
     238                 : }
     239                 : 
     240                 : /* Compare the CRC stored in the PNG file with that calculated by libpng from
     241                 :  * the data it has read thus far.
     242                 :  */
     243                 : int /* PRIVATE */
     244              16 : png_crc_error(png_structp png_ptr)
     245                 : {
     246                 :    png_byte crc_bytes[4];
     247                 :    png_uint_32 crc;
     248              16 :    int need_crc = 1;
     249                 : 
     250              16 :    if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
     251                 :    {
     252               2 :       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
     253                 :           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
     254               0 :          need_crc = 0;
     255                 :    }
     256                 : 
     257                 :    else /* critical */
     258                 :    {
     259              14 :       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
     260               0 :          need_crc = 0;
     261                 :    }
     262                 : 
     263                 : #ifdef PNG_IO_STATE_SUPPORTED
     264                 :    png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
     265                 : #endif
     266                 : 
     267                 :    /* The chunk CRC must be serialized in a single I/O call. */
     268              16 :    png_read_data(png_ptr, crc_bytes, 4);
     269                 : 
     270              16 :    if (need_crc)
     271                 :    {
     272              16 :       crc = png_get_uint_32(crc_bytes);
     273              16 :       return ((int)(crc != png_ptr->crc));
     274                 :    }
     275                 : 
     276                 :    else
     277               0 :       return (0);
     278                 : }
     279                 : 
     280                 : #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
     281                 : static png_size_t
     282               0 : png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
     283                 :     png_bytep output, png_size_t output_size)
     284                 : {
     285               0 :    png_size_t count = 0;
     286                 : 
     287                 :    /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
     288                 :     * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
     289                 :     * more".  Consequently it is necessary to chunk the input to zlib.  This
     290                 :     * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
     291                 :     * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
     292                 :     * lower value in pngpriv.h and this may sometimes have a performance
     293                 :     * advantage, because it forces access of the input data to be separated from
     294                 :     * at least some of the use by some period of time.
     295                 :     */
     296               0 :    png_ptr->zstream.next_in = data;
     297                 :    /* avail_in is set below from 'size' */
     298               0 :    png_ptr->zstream.avail_in = 0;
     299                 : 
     300                 :    while (1)
     301                 :    {
     302                 :       int ret, avail;
     303                 : 
     304                 :       /* The setting of 'avail_in' used to be outside the loop; by setting it
     305                 :        * inside it is possible to chunk the input to zlib and simply rely on
     306                 :        * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
     307                 :        * data to be passed through zlib at the unavoidable cost of requiring a
     308                 :        * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
     309                 :        * input bytes.
     310                 :        */
     311               0 :       if (png_ptr->zstream.avail_in == 0 && size > 0)
     312                 :       {
     313                 :          if (size <= ZLIB_IO_MAX)
     314                 :          {
     315                 :             /* The value is less than ZLIB_IO_MAX so the cast is safe: */
     316               0 :             png_ptr->zstream.avail_in = (uInt)size;
     317               0 :             size = 0;
     318                 :          }
     319                 : 
     320                 :          else
     321                 :          {
     322                 :             png_ptr->zstream.avail_in = ZLIB_IO_MAX;
     323                 :             size -= ZLIB_IO_MAX;
     324                 :          }
     325                 :       }
     326                 : 
     327                 :       /* Reset the output buffer each time round - we empty it
     328                 :        * after every inflate call.
     329                 :        */
     330               0 :       png_ptr->zstream.next_out = png_ptr->zbuf;
     331               0 :       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
     332                 : 
     333               0 :       ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
     334               0 :       avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
     335                 : 
     336                 :       /* First copy/count any new output - but only if we didn't
     337                 :        * get an error code.
     338                 :        */
     339               0 :       if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
     340                 :       {
     341               0 :          png_size_t space = avail; /* > 0, see above */
     342                 : 
     343               0 :          if (output != 0 && output_size > count)
     344                 :          {
     345               0 :             png_size_t copy = output_size - count;
     346                 : 
     347               0 :             if (space < copy)
     348               0 :                copy = space;
     349                 : 
     350               0 :             png_memcpy(output + count, png_ptr->zbuf, copy);
     351                 :          }
     352               0 :          count += space;
     353                 :       }
     354                 : 
     355               0 :       if (ret == Z_OK)
     356               0 :          continue;
     357                 : 
     358                 :       /* Termination conditions - always reset the zstream, it
     359                 :        * must be left in inflateInit state.
     360                 :        */
     361               0 :       png_ptr->zstream.avail_in = 0;
     362               0 :       inflateReset(&png_ptr->zstream);
     363                 : 
     364               0 :       if (ret == Z_STREAM_END)
     365               0 :          return count; /* NOTE: may be zero. */
     366                 : 
     367                 :       /* Now handle the error codes - the API always returns 0
     368                 :        * and the error message is dumped into the uncompressed
     369                 :        * buffer if available.
     370                 :        */
     371                 : #     ifdef PNG_WARNINGS_SUPPORTED
     372                 :       {
     373                 :          png_const_charp msg;
     374                 : 
     375                 :          if (png_ptr->zstream.msg != 0)
     376                 :             msg = png_ptr->zstream.msg;
     377                 : 
     378                 :          else switch (ret)
     379                 :          {
     380                 :             case Z_BUF_ERROR:
     381                 :                msg = "Buffer error in compressed datastream";
     382                 :                break;
     383                 : 
     384                 :             case Z_DATA_ERROR:
     385                 :                msg = "Data error in compressed datastream";
     386                 :                break;
     387                 : 
     388                 :             default:
     389                 :                msg = "Incomplete compressed datastream";
     390                 :                break;
     391                 :          }
     392                 : 
     393                 :          png_chunk_warning(png_ptr, msg);
     394                 :       }
     395                 : #     endif
     396                 : 
     397                 :       /* 0 means an error - notice that this code simply ignores
     398                 :        * zero length compressed chunks as a result.
     399                 :        */
     400               0 :       return 0;
     401               0 :    }
     402                 : }
     403                 : 
     404                 : /*
     405                 :  * Decompress trailing data in a chunk.  The assumption is that chunkdata
     406                 :  * points at an allocated area holding the contents of a chunk with a
     407                 :  * trailing compressed part.  What we get back is an allocated area
     408                 :  * holding the original prefix part and an uncompressed version of the
     409                 :  * trailing part (the malloc area passed in is freed).
     410                 :  */
     411                 : void /* PRIVATE */
     412               0 : png_decompress_chunk(png_structp png_ptr, int comp_type,
     413                 :     png_size_t chunklength,
     414                 :     png_size_t prefix_size, png_size_t *newlength)
     415                 : {
     416                 :    /* The caller should guarantee this */
     417               0 :    if (prefix_size > chunklength)
     418                 :    {
     419                 :       /* The recovery is to delete the chunk. */
     420                 :       png_warning(png_ptr, "invalid chunklength");
     421               0 :       prefix_size = 0; /* To delete everything */
     422                 :    }
     423                 : 
     424               0 :    else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
     425                 :    {
     426               0 :       png_size_t expanded_size = png_inflate(png_ptr,
     427               0 :           (png_bytep)(png_ptr->chunkdata + prefix_size),
     428                 :           chunklength - prefix_size,
     429                 :           0,            /* output */
     430                 :           0);           /* output size */
     431                 : 
     432                 :       /* Now check the limits on this chunk - if the limit fails the
     433                 :        * compressed data will be removed, the prefix will remain.
     434                 :        */
     435               0 :       if (prefix_size >= (~(png_size_t)0) - 1 ||
     436               0 :          expanded_size >= (~(png_size_t)0) - 1 - prefix_size
     437                 : #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
     438                 :          || (png_ptr->user_chunk_malloc_max &&
     439                 :           (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
     440                 : #else
     441                 : #  ifdef PNG_USER_CHUNK_MALLOC_MAX
     442               0 :          || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
     443               0 :           prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
     444                 : #  endif
     445                 : #endif
     446                 :          )
     447                 :          png_warning(png_ptr, "Exceeded size limit while expanding chunk");
     448                 : 
     449                 :       /* If the size is zero either there was an error and a message
     450                 :        * has already been output (warning) or the size really is zero
     451                 :        * and we have nothing to do - the code will exit through the
     452                 :        * error case below.
     453                 :        */
     454               0 :       else if (expanded_size > 0)
     455                 :       {
     456                 :          /* Success (maybe) - really uncompress the chunk. */
     457               0 :          png_size_t new_size = 0;
     458               0 :          png_charp text = (png_charp)png_malloc_warn(png_ptr,
     459               0 :              prefix_size + expanded_size + 1);
     460                 : 
     461               0 :          if (text != NULL)
     462                 :          {
     463               0 :             png_memcpy(text, png_ptr->chunkdata, prefix_size);
     464               0 :             new_size = png_inflate(png_ptr,
     465               0 :                 (png_bytep)(png_ptr->chunkdata + prefix_size),
     466                 :                 chunklength - prefix_size,
     467               0 :                 (png_bytep)(text + prefix_size), expanded_size);
     468               0 :             text[prefix_size + expanded_size] = 0; /* just in case */
     469                 : 
     470               0 :             if (new_size == expanded_size)
     471                 :             {
     472               0 :                png_free(png_ptr, png_ptr->chunkdata);
     473               0 :                png_ptr->chunkdata = text;
     474               0 :                *newlength = prefix_size + expanded_size;
     475               0 :                return; /* The success return! */
     476                 :             }
     477                 : 
     478                 :             png_warning(png_ptr, "png_inflate logic error");
     479               0 :             png_free(png_ptr, text);
     480                 :          }
     481                 : 
     482                 :          else
     483                 :             png_warning(png_ptr, "Not enough memory to decompress chunk");
     484                 :       }
     485                 :    }
     486                 : 
     487                 :    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
     488                 :    {
     489                 :       PNG_WARNING_PARAMETERS(p)
     490                 :       png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
     491                 :       png_formatted_warning(png_ptr, p, "Unknown compression type @1");
     492                 : 
     493                 :       /* The recovery is to simply drop the data. */
     494                 :    }
     495                 : 
     496                 :    /* Generic error return - leave the prefix, delete the compressed
     497                 :     * data, reallocate the chunkdata to remove the potentially large
     498                 :     * amount of compressed data.
     499                 :     */
     500                 :    {
     501               0 :       png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
     502                 : 
     503               0 :       if (text != NULL)
     504                 :       {
     505               0 :          if (prefix_size > 0)
     506               0 :             png_memcpy(text, png_ptr->chunkdata, prefix_size);
     507                 : 
     508               0 :          png_free(png_ptr, png_ptr->chunkdata);
     509               0 :          png_ptr->chunkdata = text;
     510                 : 
     511                 :          /* This is an extra zero in the 'uncompressed' part. */
     512               0 :          *(png_ptr->chunkdata + prefix_size) = 0x00;
     513                 :       }
     514                 :       /* Ignore a malloc error here - it is safe. */
     515                 :    }
     516                 : 
     517               0 :    *newlength = prefix_size;
     518                 : }
     519                 : #endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
     520                 : 
     521                 : /* Read and check the IDHR chunk */
     522                 : void /* PRIVATE */
     523               4 : png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     524                 : {
     525                 :    png_byte buf[13];
     526                 :    png_uint_32 width, height;
     527                 :    int bit_depth, color_type, compression_type, filter_type;
     528                 :    int interlace_type;
     529                 : 
     530                 :    png_debug(1, "in png_handle_IHDR");
     531                 : 
     532               4 :    if (png_ptr->mode & PNG_HAVE_IHDR)
     533               0 :       png_error(png_ptr, "Out of place IHDR");
     534                 : 
     535                 :    /* Check the length */
     536               4 :    if (length != 13)
     537               0 :       png_error(png_ptr, "Invalid IHDR chunk");
     538                 : 
     539               4 :    png_ptr->mode |= PNG_HAVE_IHDR;
     540                 : 
     541               4 :    png_crc_read(png_ptr, buf, 13);
     542               4 :    png_crc_finish(png_ptr, 0);
     543                 : 
     544               4 :    width = png_get_uint_31(png_ptr, buf);
     545               4 :    height = png_get_uint_31(png_ptr, buf + 4);
     546               4 :    bit_depth = buf[8];
     547               4 :    color_type = buf[9];
     548               4 :    compression_type = buf[10];
     549               4 :    filter_type = buf[11];
     550               4 :    interlace_type = buf[12];
     551                 : 
     552                 : #ifdef PNG_READ_APNG_SUPPORTED
     553               4 :    png_ptr->first_frame_width = width;
     554               4 :    png_ptr->first_frame_height = height;
     555                 : #endif
     556                 : 
     557                 :    /* Set internal variables */
     558               4 :    png_ptr->width = width;
     559               4 :    png_ptr->height = height;
     560               4 :    png_ptr->bit_depth = (png_byte)bit_depth;
     561               4 :    png_ptr->interlaced = (png_byte)interlace_type;
     562               4 :    png_ptr->color_type = (png_byte)color_type;
     563                 : #ifdef PNG_MNG_FEATURES_SUPPORTED
     564                 :    png_ptr->filter_type = (png_byte)filter_type;
     565                 : #endif
     566               4 :    png_ptr->compression_type = (png_byte)compression_type;
     567                 : 
     568                 :    /* Find number of channels */
     569               4 :    switch (png_ptr->color_type)
     570                 :    {
     571                 :       default: /* invalid, png_set_IHDR calls png_error */
     572                 :       case PNG_COLOR_TYPE_GRAY:
     573                 :       case PNG_COLOR_TYPE_PALETTE:
     574               0 :          png_ptr->channels = 1;
     575               0 :          break;
     576                 : 
     577                 :       case PNG_COLOR_TYPE_RGB:
     578               1 :          png_ptr->channels = 3;
     579               1 :          break;
     580                 : 
     581                 :       case PNG_COLOR_TYPE_GRAY_ALPHA:
     582               0 :          png_ptr->channels = 2;
     583               0 :          break;
     584                 : 
     585                 :       case PNG_COLOR_TYPE_RGB_ALPHA:
     586               3 :          png_ptr->channels = 4;
     587               3 :          break;
     588                 :    }
     589                 : 
     590                 :    /* Set up other useful info */
     591               8 :    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
     592               4 :    png_ptr->channels);
     593               4 :    png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
     594                 :    png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
     595                 :    png_debug1(3, "channels = %d", png_ptr->channels);
     596                 :    png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
     597               4 :    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
     598                 :        color_type, interlace_type, compression_type, filter_type);
     599               4 : }
     600                 : 
     601                 : /* Read and check the palette */
     602                 : void /* PRIVATE */
     603               0 : png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     604                 : {
     605                 :    png_color palette[PNG_MAX_PALETTE_LENGTH];
     606                 :    int num, i;
     607                 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
     608                 :    png_colorp pal_ptr;
     609                 : #endif
     610                 : 
     611                 :    png_debug(1, "in png_handle_PLTE");
     612                 : 
     613               0 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     614               0 :       png_error(png_ptr, "Missing IHDR before PLTE");
     615                 : 
     616               0 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
     617                 :    {
     618                 :       png_warning(png_ptr, "Invalid PLTE after IDAT");
     619               0 :       png_crc_finish(png_ptr, length);
     620               0 :       return;
     621                 :    }
     622                 : 
     623               0 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
     624               0 :       png_error(png_ptr, "Duplicate PLTE chunk");
     625                 : 
     626               0 :    png_ptr->mode |= PNG_HAVE_PLTE;
     627                 : 
     628               0 :    if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
     629                 :    {
     630                 :       png_warning(png_ptr,
     631                 :           "Ignoring PLTE chunk in grayscale PNG");
     632               0 :       png_crc_finish(png_ptr, length);
     633               0 :       return;
     634                 :    }
     635                 : 
     636                 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
     637               0 :    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
     638                 :    {
     639               0 :       png_crc_finish(png_ptr, length);
     640               0 :       return;
     641                 :    }
     642                 : #endif
     643                 : 
     644               0 :    if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
     645                 :    {
     646               0 :       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
     647                 :       {
     648                 :          png_warning(png_ptr, "Invalid palette chunk");
     649               0 :          png_crc_finish(png_ptr, length);
     650               0 :          return;
     651                 :       }
     652                 : 
     653                 :       else
     654                 :       {
     655               0 :          png_error(png_ptr, "Invalid palette chunk");
     656                 :       }
     657                 :    }
     658                 : 
     659               0 :    num = (int)length / 3;
     660                 : 
     661                 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
     662               0 :    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
     663                 :    {
     664                 :       png_byte buf[3];
     665                 : 
     666               0 :       png_crc_read(png_ptr, buf, 3);
     667               0 :       pal_ptr->red = buf[0];
     668               0 :       pal_ptr->green = buf[1];
     669               0 :       pal_ptr->blue = buf[2];
     670                 :    }
     671                 : #else
     672                 :    for (i = 0; i < num; i++)
     673                 :    {
     674                 :       png_byte buf[3];
     675                 : 
     676                 :       png_crc_read(png_ptr, buf, 3);
     677                 :       /* Don't depend upon png_color being any order */
     678                 :       palette[i].red = buf[0];
     679                 :       palette[i].green = buf[1];
     680                 :       palette[i].blue = buf[2];
     681                 :    }
     682                 : #endif
     683                 : 
     684                 :    /* If we actually need the PLTE chunk (ie for a paletted image), we do
     685                 :     * whatever the normal CRC configuration tells us.  However, if we
     686                 :     * have an RGB image, the PLTE can be considered ancillary, so
     687                 :     * we will act as though it is.
     688                 :     */
     689                 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
     690               0 :    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
     691                 : #endif
     692                 :    {
     693               0 :       png_crc_finish(png_ptr, 0);
     694                 :    }
     695                 : 
     696                 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
     697               0 :    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
     698                 :    {
     699                 :       /* If we don't want to use the data from an ancillary chunk,
     700                 :        * we have two options: an error abort, or a warning and we
     701                 :        * ignore the data in this chunk (which should be OK, since
     702                 :        * it's considered ancillary for a RGB or RGBA image).
     703                 :        */
     704               0 :       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
     705                 :       {
     706               0 :          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
     707                 :          {
     708               0 :             png_chunk_benign_error(png_ptr, "CRC error");
     709                 :          }
     710                 : 
     711                 :          else
     712                 :          {
     713                 :             png_chunk_warning(png_ptr, "CRC error");
     714               0 :             return;
     715                 :          }
     716                 :       }
     717                 : 
     718                 :       /* Otherwise, we (optionally) emit a warning and use the chunk. */
     719               0 :       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
     720                 :       {
     721                 :          png_chunk_warning(png_ptr, "CRC error");
     722                 :       }
     723                 :    }
     724                 : #endif
     725                 : 
     726               0 :    png_set_PLTE(png_ptr, info_ptr, palette, num);
     727                 : 
     728                 : #ifdef PNG_READ_tRNS_SUPPORTED
     729               0 :    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
     730                 :    {
     731               0 :       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
     732                 :       {
     733               0 :          if (png_ptr->num_trans > (png_uint_16)num)
     734                 :          {
     735                 :             png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
     736               0 :             png_ptr->num_trans = (png_uint_16)num;
     737                 :          }
     738                 : 
     739               0 :          if (info_ptr->num_trans > (png_uint_16)num)
     740                 :          {
     741                 :             png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
     742               0 :             info_ptr->num_trans = (png_uint_16)num;
     743                 :          }
     744                 :       }
     745                 :    }
     746                 : #endif
     747                 : 
     748                 : }
     749                 : 
     750                 : void /* PRIVATE */
     751               4 : png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     752                 : {
     753                 :    png_debug(1, "in png_handle_IEND");
     754                 : 
     755               4 :    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
     756                 :    {
     757               0 :       png_error(png_ptr, "No image in file");
     758                 :    }
     759                 : 
     760               4 :    png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
     761                 : 
     762                 :    if (length != 0)
     763                 :    {
     764                 :       png_warning(png_ptr, "Incorrect IEND chunk length");
     765                 :    }
     766                 : 
     767               4 :    png_crc_finish(png_ptr, length);
     768                 : 
     769                 :    PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
     770               4 : }
     771                 : 
     772                 : #ifdef PNG_READ_gAMA_SUPPORTED
     773                 : void /* PRIVATE */
     774               1 : png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     775                 : {
     776                 :    png_fixed_point igamma;
     777                 :    png_byte buf[4];
     778                 : 
     779                 :    png_debug(1, "in png_handle_gAMA");
     780                 : 
     781               1 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     782               0 :       png_error(png_ptr, "Missing IHDR before gAMA");
     783                 : 
     784               1 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
     785                 :    {
     786                 :       png_warning(png_ptr, "Invalid gAMA after IDAT");
     787               0 :       png_crc_finish(png_ptr, length);
     788               0 :       return;
     789                 :    }
     790                 : 
     791               1 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
     792                 :       /* Should be an error, but we can cope with it */
     793                 :       png_warning(png_ptr, "Out of place gAMA chunk");
     794                 : 
     795               1 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
     796                 : #ifdef PNG_READ_sRGB_SUPPORTED
     797               0 :        && !(info_ptr->valid & PNG_INFO_sRGB)
     798                 : #endif
     799                 :        )
     800                 :    {
     801                 :       png_warning(png_ptr, "Duplicate gAMA chunk");
     802               0 :       png_crc_finish(png_ptr, length);
     803               0 :       return;
     804                 :    }
     805                 : 
     806               1 :    if (length != 4)
     807                 :    {
     808                 :       png_warning(png_ptr, "Incorrect gAMA chunk length");
     809               0 :       png_crc_finish(png_ptr, length);
     810               0 :       return;
     811                 :    }
     812                 : 
     813               1 :    png_crc_read(png_ptr, buf, 4);
     814                 : 
     815               1 :    if (png_crc_finish(png_ptr, 0))
     816               0 :       return;
     817                 : 
     818               1 :    igamma = png_get_fixed_point(NULL, buf);
     819                 : 
     820                 :    /* Check for zero gamma or an error. */
     821               1 :    if (igamma <= 0)
     822                 :    {
     823                 :       png_warning(png_ptr,
     824                 :           "Ignoring gAMA chunk with out of range gamma");
     825                 : 
     826               0 :       return;
     827                 :    }
     828                 : 
     829                 : #  ifdef PNG_READ_sRGB_SUPPORTED
     830               1 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
     831                 :    {
     832               0 :       if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
     833                 :       {
     834                 :          PNG_WARNING_PARAMETERS(p)
     835                 :          png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
     836                 :          png_formatted_warning(png_ptr, p,
     837                 :              "Ignoring incorrect gAMA value @1 when sRGB is also present");
     838               0 :          return;
     839                 :       }
     840                 :    }
     841                 : #  endif /* PNG_READ_sRGB_SUPPORTED */
     842                 : 
     843                 : #  ifdef PNG_READ_GAMMA_SUPPORTED
     844                 :    /* Gamma correction on read is supported. */
     845               1 :    png_ptr->gamma = igamma;
     846                 : #  endif
     847                 :    /* And set the 'info' structure members. */
     848               1 :    png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
     849                 : }
     850                 : #endif
     851                 : 
     852                 : #ifdef PNG_READ_sBIT_SUPPORTED
     853                 : void /* PRIVATE */
     854                 : png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     855                 : {
     856                 :    png_size_t truelen;
     857                 :    png_byte buf[4];
     858                 : 
     859                 :    png_debug(1, "in png_handle_sBIT");
     860                 : 
     861                 :    buf[0] = buf[1] = buf[2] = buf[3] = 0;
     862                 : 
     863                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     864                 :       png_error(png_ptr, "Missing IHDR before sBIT");
     865                 : 
     866                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
     867                 :    {
     868                 :       png_warning(png_ptr, "Invalid sBIT after IDAT");
     869                 :       png_crc_finish(png_ptr, length);
     870                 :       return;
     871                 :    }
     872                 : 
     873                 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
     874                 :    {
     875                 :       /* Should be an error, but we can cope with it */
     876                 :       png_warning(png_ptr, "Out of place sBIT chunk");
     877                 :    }
     878                 : 
     879                 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
     880                 :    {
     881                 :       png_warning(png_ptr, "Duplicate sBIT chunk");
     882                 :       png_crc_finish(png_ptr, length);
     883                 :       return;
     884                 :    }
     885                 : 
     886                 :    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
     887                 :       truelen = 3;
     888                 : 
     889                 :    else
     890                 :       truelen = (png_size_t)png_ptr->channels;
     891                 : 
     892                 :    if (length != truelen || length > 4)
     893                 :    {
     894                 :       png_warning(png_ptr, "Incorrect sBIT chunk length");
     895                 :       png_crc_finish(png_ptr, length);
     896                 :       return;
     897                 :    }
     898                 : 
     899                 :    png_crc_read(png_ptr, buf, truelen);
     900                 : 
     901                 :    if (png_crc_finish(png_ptr, 0))
     902                 :       return;
     903                 : 
     904                 :    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
     905                 :    {
     906                 :       png_ptr->sig_bit.red = buf[0];
     907                 :       png_ptr->sig_bit.green = buf[1];
     908                 :       png_ptr->sig_bit.blue = buf[2];
     909                 :       png_ptr->sig_bit.alpha = buf[3];
     910                 :    }
     911                 : 
     912                 :    else
     913                 :    {
     914                 :       png_ptr->sig_bit.gray = buf[0];
     915                 :       png_ptr->sig_bit.red = buf[0];
     916                 :       png_ptr->sig_bit.green = buf[0];
     917                 :       png_ptr->sig_bit.blue = buf[0];
     918                 :       png_ptr->sig_bit.alpha = buf[1];
     919                 :    }
     920                 : 
     921                 :    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
     922                 : }
     923                 : #endif
     924                 : 
     925                 : #ifdef PNG_READ_cHRM_SUPPORTED
     926                 : void /* PRIVATE */
     927               0 : png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
     928                 : {
     929                 :    png_byte buf[32];
     930                 :    png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
     931                 :       y_blue;
     932                 : 
     933                 :    png_debug(1, "in png_handle_cHRM");
     934                 : 
     935               0 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
     936               0 :       png_error(png_ptr, "Missing IHDR before cHRM");
     937                 : 
     938               0 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
     939                 :    {
     940                 :       png_warning(png_ptr, "Invalid cHRM after IDAT");
     941               0 :       png_crc_finish(png_ptr, length);
     942               0 :       return;
     943                 :    }
     944                 : 
     945               0 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
     946                 :       /* Should be an error, but we can cope with it */
     947                 :       png_warning(png_ptr, "Out of place cHRM chunk");
     948                 : 
     949               0 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
     950                 : #  ifdef PNG_READ_sRGB_SUPPORTED
     951               0 :        && !(info_ptr->valid & PNG_INFO_sRGB)
     952                 : #  endif
     953                 :       )
     954                 :    {
     955                 :       png_warning(png_ptr, "Duplicate cHRM chunk");
     956               0 :       png_crc_finish(png_ptr, length);
     957               0 :       return;
     958                 :    }
     959                 : 
     960               0 :    if (length != 32)
     961                 :    {
     962                 :       png_warning(png_ptr, "Incorrect cHRM chunk length");
     963               0 :       png_crc_finish(png_ptr, length);
     964               0 :       return;
     965                 :    }
     966                 : 
     967               0 :    png_crc_read(png_ptr, buf, 32);
     968                 : 
     969               0 :    if (png_crc_finish(png_ptr, 0))
     970               0 :       return;
     971                 : 
     972               0 :    x_white = png_get_fixed_point(NULL, buf);
     973               0 :    y_white = png_get_fixed_point(NULL, buf + 4);
     974               0 :    x_red   = png_get_fixed_point(NULL, buf + 8);
     975               0 :    y_red   = png_get_fixed_point(NULL, buf + 12);
     976               0 :    x_green = png_get_fixed_point(NULL, buf + 16);
     977               0 :    y_green = png_get_fixed_point(NULL, buf + 20);
     978               0 :    x_blue  = png_get_fixed_point(NULL, buf + 24);
     979               0 :    y_blue  = png_get_fixed_point(NULL, buf + 28);
     980                 : 
     981               0 :    if (x_white == PNG_FIXED_ERROR ||
     982               0 :        y_white == PNG_FIXED_ERROR ||
     983               0 :        x_red   == PNG_FIXED_ERROR ||
     984               0 :        y_red   == PNG_FIXED_ERROR ||
     985               0 :        x_green == PNG_FIXED_ERROR ||
     986               0 :        y_green == PNG_FIXED_ERROR ||
     987               0 :        x_blue  == PNG_FIXED_ERROR ||
     988                 :        y_blue  == PNG_FIXED_ERROR)
     989                 :    {
     990                 :       png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
     991               0 :       return;
     992                 :    }
     993                 : 
     994                 : #ifdef PNG_READ_sRGB_SUPPORTED
     995               0 :    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
     996                 :    {
     997                 :       if (PNG_OUT_OF_RANGE(x_white, 31270,  1000) ||
     998                 :           PNG_OUT_OF_RANGE(y_white, 32900,  1000) ||
     999                 :           PNG_OUT_OF_RANGE(x_red,   64000,  1000) ||
    1000                 :           PNG_OUT_OF_RANGE(y_red,   33000,  1000) ||
    1001                 :           PNG_OUT_OF_RANGE(x_green, 30000,  1000) ||
    1002                 :           PNG_OUT_OF_RANGE(y_green, 60000,  1000) ||
    1003                 :           PNG_OUT_OF_RANGE(x_blue,  15000,  1000) ||
    1004                 :           PNG_OUT_OF_RANGE(y_blue,   6000,  1000))
    1005                 :       {
    1006                 :          PNG_WARNING_PARAMETERS(p)
    1007                 : 
    1008                 :          png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
    1009                 :          png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
    1010                 :          png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
    1011                 :          png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
    1012                 :          png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
    1013                 :          png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
    1014                 :          png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
    1015                 :          png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
    1016                 : 
    1017                 :          png_formatted_warning(png_ptr, p,
    1018                 :              "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
    1019                 :              "when sRGB is also present");
    1020                 :       }
    1021               0 :       return;
    1022                 :    }
    1023                 : #endif /* PNG_READ_sRGB_SUPPORTED */
    1024                 : 
    1025                 : #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    1026                 :    /* Store the _white values as default coefficients for the rgb to gray
    1027                 :     * operation if it is supported.  Check if the transform is already set to
    1028                 :     * avoid destroying the transform values.
    1029                 :     */
    1030                 :    if (!png_ptr->rgb_to_gray_coefficients_set)
    1031                 :    {
    1032                 :       /* png_set_background has not been called and we haven't seen an sRGB
    1033                 :        * chunk yet.  Find the XYZ of the three end points.
    1034                 :        */
    1035                 :       png_XYZ XYZ;
    1036                 :       png_xy xy;
    1037                 : 
    1038                 :       xy.redx = x_red;
    1039                 :       xy.redy = y_red;
    1040                 :       xy.greenx = x_green;
    1041                 :       xy.greeny = y_green;
    1042                 :       xy.bluex = x_blue;
    1043                 :       xy.bluey = y_blue;
    1044                 :       xy.whitex = x_white;
    1045                 :       xy.whitey = y_white;
    1046                 : 
    1047                 :       if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
    1048                 :       {
    1049                 :          /* The success case, because XYZ_from_xy normalises to a reference
    1050                 :           * white Y of 1.0 we just need to scale the numbers.  This should
    1051                 :           * always work just fine. It is an internal error if this overflows.
    1052                 :           */
    1053                 :          {
    1054                 :             png_fixed_point r, g, b;
    1055                 :             if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
    1056                 :                r >= 0 && r <= 32768 &&
    1057                 :                png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
    1058                 :                g >= 0 && g <= 32768 &&
    1059                 :                png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
    1060                 :                b >= 0 && b <= 32768 &&
    1061                 :                r+g+b <= 32769)
    1062                 :             {
    1063                 :                /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
    1064                 :                 * all of the coefficients were rounded up.  Handle this by
    1065                 :                 * reducing the *largest* coefficient by 1; this matches the
    1066                 :                 * approach used for the default coefficients in pngrtran.c
    1067                 :                 */
    1068                 :                int add = 0;
    1069                 : 
    1070                 :                if (r+g+b > 32768)
    1071                 :                   add = -1;
    1072                 :                else if (r+g+b < 32768)
    1073                 :                   add = 1;
    1074                 : 
    1075                 :                if (add != 0)
    1076                 :                {
    1077                 :                   if (g >= r && g >= b)
    1078                 :                      g += add;
    1079                 :                   else if (r >= g && r >= b)
    1080                 :                      r += add;
    1081                 :                   else
    1082                 :                      b += add;
    1083                 :                }
    1084                 : 
    1085                 :                /* Check for an internal error. */
    1086                 :                if (r+g+b != 32768)
    1087                 :                   png_error(png_ptr,
    1088                 :                      "internal error handling cHRM coefficients");
    1089                 : 
    1090                 :                png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
    1091                 :                png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
    1092                 :             }
    1093                 : 
    1094                 :             /* This is a png_error at present even though it could be ignored -
    1095                 :              * it should never happen, but it is important that if it does, the
    1096                 :              * bug is fixed.
    1097                 :              */
    1098                 :             else
    1099                 :                png_error(png_ptr, "internal error handling cHRM->XYZ");
    1100                 :          }
    1101                 :       }
    1102                 :    }
    1103                 : #endif
    1104                 : 
    1105               0 :    png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
    1106                 :       x_green, y_green, x_blue, y_blue);
    1107                 : }
    1108                 : #endif
    1109                 : 
    1110                 : #ifdef PNG_READ_sRGB_SUPPORTED
    1111                 : void /* PRIVATE */
    1112               0 : png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1113                 : {
    1114                 :    int intent;
    1115                 :    png_byte buf[1];
    1116                 : 
    1117                 :    png_debug(1, "in png_handle_sRGB");
    1118                 : 
    1119               0 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1120               0 :       png_error(png_ptr, "Missing IHDR before sRGB");
    1121                 : 
    1122               0 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1123                 :    {
    1124                 :       png_warning(png_ptr, "Invalid sRGB after IDAT");
    1125               0 :       png_crc_finish(png_ptr, length);
    1126               0 :       return;
    1127                 :    }
    1128                 : 
    1129               0 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
    1130                 :       /* Should be an error, but we can cope with it */
    1131                 :       png_warning(png_ptr, "Out of place sRGB chunk");
    1132                 : 
    1133               0 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
    1134                 :    {
    1135                 :       png_warning(png_ptr, "Duplicate sRGB chunk");
    1136               0 :       png_crc_finish(png_ptr, length);
    1137               0 :       return;
    1138                 :    }
    1139                 : 
    1140               0 :    if (length != 1)
    1141                 :    {
    1142                 :       png_warning(png_ptr, "Incorrect sRGB chunk length");
    1143               0 :       png_crc_finish(png_ptr, length);
    1144               0 :       return;
    1145                 :    }
    1146                 : 
    1147               0 :    png_crc_read(png_ptr, buf, 1);
    1148                 : 
    1149               0 :    if (png_crc_finish(png_ptr, 0))
    1150               0 :       return;
    1151                 : 
    1152               0 :    intent = buf[0];
    1153                 : 
    1154                 :    /* Check for bad intent */
    1155               0 :    if (intent >= PNG_sRGB_INTENT_LAST)
    1156                 :    {
    1157                 :       png_warning(png_ptr, "Unknown sRGB intent");
    1158               0 :       return;
    1159                 :    }
    1160                 : 
    1161                 : #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
    1162               0 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
    1163                 :    {
    1164               0 :       if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
    1165                 :       {
    1166                 :          PNG_WARNING_PARAMETERS(p)
    1167                 : 
    1168                 :          png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
    1169                 :             info_ptr->gamma);
    1170                 : 
    1171                 :          png_formatted_warning(png_ptr, p,
    1172                 :              "Ignoring incorrect gAMA value @1 when sRGB is also present");
    1173                 :       }
    1174                 :    }
    1175                 : #endif /* PNG_READ_gAMA_SUPPORTED */
    1176                 : 
    1177                 : #ifdef PNG_READ_cHRM_SUPPORTED
    1178               0 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
    1179               0 :       if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270,  1000) ||
    1180               0 :           PNG_OUT_OF_RANGE(info_ptr->y_white, 32900,  1000) ||
    1181               0 :           PNG_OUT_OF_RANGE(info_ptr->x_red,   64000,  1000) ||
    1182               0 :           PNG_OUT_OF_RANGE(info_ptr->y_red,   33000,  1000) ||
    1183               0 :           PNG_OUT_OF_RANGE(info_ptr->x_green, 30000,  1000) ||
    1184               0 :           PNG_OUT_OF_RANGE(info_ptr->y_green, 60000,  1000) ||
    1185               0 :           PNG_OUT_OF_RANGE(info_ptr->x_blue,  15000,  1000) ||
    1186               0 :           PNG_OUT_OF_RANGE(info_ptr->y_blue,   6000,  1000))
    1187                 :       {
    1188                 :          png_warning(png_ptr,
    1189                 :              "Ignoring incorrect cHRM value when sRGB is also present");
    1190                 :       }
    1191                 : #endif /* PNG_READ_cHRM_SUPPORTED */
    1192                 : 
    1193                 :    /* This is recorded for use when handling the cHRM chunk above.  An sRGB
    1194                 :     * chunk unconditionally overwrites the coefficients for grayscale conversion
    1195                 :     * too.
    1196                 :     */
    1197               0 :    png_ptr->is_sRGB = 1;
    1198                 : 
    1199                 : #  ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    1200                 :       /* Don't overwrite user supplied values: */
    1201                 :       if (!png_ptr->rgb_to_gray_coefficients_set)
    1202                 :       {
    1203                 :          /* These numbers come from the sRGB specification (or, since one has to
    1204                 :           * pay much money to get a copy, the wikipedia sRGB page) the
    1205                 :           * chromaticity values quoted have been inverted to get the reverse
    1206                 :           * transformation from RGB to XYZ and the 'Y' coefficients scaled by
    1207                 :           * 32768 (then rounded).
    1208                 :           *
    1209                 :           * sRGB and ITU Rec-709 both truncate the values for the D65 white
    1210                 :           * point to four digits and, even though it actually stores five
    1211                 :           * digits, the PNG spec gives the truncated value.
    1212                 :           *
    1213                 :           * This means that when the chromaticities are converted back to XYZ
    1214                 :           * end points we end up with (6968,23435,2366), which, as described in
    1215                 :           * pngrtran.c, would overflow.  If the five digit precision and up is
    1216                 :           * used we get, instead:
    1217                 :           *
    1218                 :           *    6968*R + 23435*G + 2365*B
    1219                 :           *
    1220                 :           * (Notice that this rounds the blue coefficient down, rather than the
    1221                 :           * choice used in pngrtran.c which is to round the green one down.)
    1222                 :           */
    1223                 :          png_ptr->rgb_to_gray_red_coeff   =  6968; /* 0.212639005871510 */
    1224                 :          png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
    1225                 :          /* png_ptr->rgb_to_gray_blue_coeff  =  2366; 0.072192315360734      */
    1226                 : 
    1227                 :          /* The following keeps the cHRM chunk from destroying the
    1228                 :           * coefficients again in the event that it follows the sRGB chunk.
    1229                 :           */
    1230                 :          png_ptr->rgb_to_gray_coefficients_set = 1;
    1231                 :       }
    1232                 : #  endif
    1233                 : 
    1234               0 :    png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
    1235                 : }
    1236                 : #endif /* PNG_READ_sRGB_SUPPORTED */
    1237                 : 
    1238                 : #ifdef PNG_READ_iCCP_SUPPORTED
    1239                 : void /* PRIVATE */
    1240               0 : png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1241                 : /* Note: this does not properly handle chunks that are > 64K under DOS */
    1242                 : {
    1243                 :    png_byte compression_type;
    1244                 :    png_bytep pC;
    1245                 :    png_charp profile;
    1246               0 :    png_uint_32 skip = 0;
    1247                 :    png_uint_32 profile_size;
    1248                 :    png_alloc_size_t profile_length;
    1249                 :    png_size_t slength, prefix_length, data_length;
    1250                 : 
    1251                 :    png_debug(1, "in png_handle_iCCP");
    1252                 : 
    1253               0 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1254               0 :       png_error(png_ptr, "Missing IHDR before iCCP");
    1255                 : 
    1256               0 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1257                 :    {
    1258                 :       png_warning(png_ptr, "Invalid iCCP after IDAT");
    1259               0 :       png_crc_finish(png_ptr, length);
    1260               0 :       return;
    1261                 :    }
    1262                 : 
    1263               0 :    else if (png_ptr->mode & PNG_HAVE_PLTE)
    1264                 :       /* Should be an error, but we can cope with it */
    1265                 :       png_warning(png_ptr, "Out of place iCCP chunk");
    1266                 : 
    1267               0 :    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
    1268                 :    {
    1269                 :       png_warning(png_ptr, "Duplicate iCCP chunk");
    1270               0 :       png_crc_finish(png_ptr, length);
    1271               0 :       return;
    1272                 :    }
    1273                 : 
    1274                 : #ifdef PNG_MAX_MALLOC_64K
    1275                 :    if (length > (png_uint_32)65535L)
    1276                 :    {
    1277                 :       png_warning(png_ptr, "iCCP chunk too large to fit in memory");
    1278                 :       skip = length - (png_uint_32)65535L;
    1279                 :       length = (png_uint_32)65535L;
    1280                 :    }
    1281                 : #endif
    1282                 : 
    1283               0 :    png_free(png_ptr, png_ptr->chunkdata);
    1284               0 :    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
    1285               0 :    slength = length;
    1286               0 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    1287                 : 
    1288               0 :    if (png_crc_finish(png_ptr, skip))
    1289                 :    {
    1290               0 :       png_free(png_ptr, png_ptr->chunkdata);
    1291               0 :       png_ptr->chunkdata = NULL;
    1292               0 :       return;
    1293                 :    }
    1294                 : 
    1295               0 :    png_ptr->chunkdata[slength] = 0x00;
    1296                 : 
    1297               0 :    for (profile = png_ptr->chunkdata; *profile; profile++)
    1298                 :       /* Empty loop to find end of name */ ;
    1299                 : 
    1300               0 :    ++profile;
    1301                 : 
    1302                 :    /* There should be at least one zero (the compression type byte)
    1303                 :     * following the separator, and we should be on it
    1304                 :     */
    1305               0 :    if (profile >= png_ptr->chunkdata + slength - 1)
    1306                 :    {
    1307               0 :       png_free(png_ptr, png_ptr->chunkdata);
    1308               0 :       png_ptr->chunkdata = NULL;
    1309                 :       png_warning(png_ptr, "Malformed iCCP chunk");
    1310               0 :       return;
    1311                 :    }
    1312                 : 
    1313                 :    /* Compression_type should always be zero */
    1314               0 :    compression_type = *profile++;
    1315                 : 
    1316               0 :    if (compression_type)
    1317                 :    {
    1318                 :       png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
    1319               0 :       compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
    1320                 :                                  wrote nonzero) */
    1321                 :    }
    1322                 : 
    1323               0 :    prefix_length = profile - png_ptr->chunkdata;
    1324               0 :    png_decompress_chunk(png_ptr, compression_type,
    1325                 :        slength, prefix_length, &data_length);
    1326                 : 
    1327               0 :    profile_length = data_length - prefix_length;
    1328                 : 
    1329               0 :    if (prefix_length > data_length || profile_length < 4)
    1330                 :    {
    1331               0 :       png_free(png_ptr, png_ptr->chunkdata);
    1332               0 :       png_ptr->chunkdata = NULL;
    1333                 :       png_warning(png_ptr, "Profile size field missing from iCCP chunk");
    1334               0 :       return;
    1335                 :    }
    1336                 : 
    1337                 :    /* Check the profile_size recorded in the first 32 bits of the ICC profile */
    1338               0 :    pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
    1339               0 :    profile_size = ((*(pC    )) << 24) |
    1340               0 :                   ((*(pC + 1)) << 16) |
    1341               0 :                   ((*(pC + 2)) <<  8) |
    1342               0 :                   ((*(pC + 3))      );
    1343                 : 
    1344                 :    /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
    1345                 :     * because profile_size is a 32 bit value.
    1346                 :     */
    1347               0 :    if (profile_size < profile_length)
    1348               0 :       profile_length = profile_size;
    1349                 : 
    1350                 :    /* And the following guarantees that profile_size == profile_length. */
    1351               0 :    if (profile_size > profile_length)
    1352                 :    {
    1353                 :       PNG_WARNING_PARAMETERS(p)
    1354                 : 
    1355               0 :       png_free(png_ptr, png_ptr->chunkdata);
    1356               0 :       png_ptr->chunkdata = NULL;
    1357                 : 
    1358                 :       png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
    1359                 :       png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
    1360                 :       png_formatted_warning(png_ptr, p,
    1361                 :          "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
    1362               0 :       return;
    1363                 :    }
    1364                 : 
    1365               0 :    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
    1366               0 :        compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
    1367                 :        profile_size);
    1368               0 :    png_free(png_ptr, png_ptr->chunkdata);
    1369               0 :    png_ptr->chunkdata = NULL;
    1370                 : }
    1371                 : #endif /* PNG_READ_iCCP_SUPPORTED */
    1372                 : 
    1373                 : #ifdef PNG_READ_sPLT_SUPPORTED
    1374                 : void /* PRIVATE */
    1375                 : png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1376                 : /* Note: this does not properly handle chunks that are > 64K under DOS */
    1377                 : {
    1378                 :    png_bytep entry_start;
    1379                 :    png_sPLT_t new_palette;
    1380                 :    png_sPLT_entryp pp;
    1381                 :    png_uint_32 data_length;
    1382                 :    int entry_size, i;
    1383                 :    png_uint_32 skip = 0;
    1384                 :    png_size_t slength;
    1385                 :    png_uint_32 dl;
    1386                 :    png_size_t max_dl;
    1387                 : 
    1388                 :    png_debug(1, "in png_handle_sPLT");
    1389                 : 
    1390                 : #ifdef PNG_USER_LIMITS_SUPPORTED
    1391                 : 
    1392                 :    if (png_ptr->user_chunk_cache_max != 0)
    1393                 :    {
    1394                 :       if (png_ptr->user_chunk_cache_max == 1)
    1395                 :       {
    1396                 :          png_crc_finish(png_ptr, length);
    1397                 :          return;
    1398                 :       }
    1399                 : 
    1400                 :       if (--png_ptr->user_chunk_cache_max == 1)
    1401                 :       {
    1402                 :          png_warning(png_ptr, "No space in chunk cache for sPLT");
    1403                 :          png_crc_finish(png_ptr, length);
    1404                 :          return;
    1405                 :       }
    1406                 :    }
    1407                 : #endif
    1408                 : 
    1409                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1410                 :       png_error(png_ptr, "Missing IHDR before sPLT");
    1411                 : 
    1412                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1413                 :    {
    1414                 :       png_warning(png_ptr, "Invalid sPLT after IDAT");
    1415                 :       png_crc_finish(png_ptr, length);
    1416                 :       return;
    1417                 :    }
    1418                 : 
    1419                 : #ifdef PNG_MAX_MALLOC_64K
    1420                 :    if (length > (png_uint_32)65535L)
    1421                 :    {
    1422                 :       png_warning(png_ptr, "sPLT chunk too large to fit in memory");
    1423                 :       skip = length - (png_uint_32)65535L;
    1424                 :       length = (png_uint_32)65535L;
    1425                 :    }
    1426                 : #endif
    1427                 : 
    1428                 :    png_free(png_ptr, png_ptr->chunkdata);
    1429                 :    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
    1430                 : 
    1431                 :    /* WARNING: this may break if size_t is less than 32 bits; it is assumed
    1432                 :     * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
    1433                 :     * potential breakage point if the types in pngconf.h aren't exactly right.
    1434                 :     */
    1435                 :    slength = length;
    1436                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    1437                 : 
    1438                 :    if (png_crc_finish(png_ptr, skip))
    1439                 :    {
    1440                 :       png_free(png_ptr, png_ptr->chunkdata);
    1441                 :       png_ptr->chunkdata = NULL;
    1442                 :       return;
    1443                 :    }
    1444                 : 
    1445                 :    png_ptr->chunkdata[slength] = 0x00;
    1446                 : 
    1447                 :    for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
    1448                 :        entry_start++)
    1449                 :       /* Empty loop to find end of name */ ;
    1450                 : 
    1451                 :    ++entry_start;
    1452                 : 
    1453                 :    /* A sample depth should follow the separator, and we should be on it  */
    1454                 :    if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
    1455                 :    {
    1456                 :       png_free(png_ptr, png_ptr->chunkdata);
    1457                 :       png_ptr->chunkdata = NULL;
    1458                 :       png_warning(png_ptr, "malformed sPLT chunk");
    1459                 :       return;
    1460                 :    }
    1461                 : 
    1462                 :    new_palette.depth = *entry_start++;
    1463                 :    entry_size = (new_palette.depth == 8 ? 6 : 10);
    1464                 :    /* This must fit in a png_uint_32 because it is derived from the original
    1465                 :     * chunk data length (and use 'length', not 'slength' here for clarity -
    1466                 :     * they are guaranteed to be the same, see the tests above.)
    1467                 :     */
    1468                 :    data_length = length - (png_uint_32)(entry_start -
    1469                 :       (png_bytep)png_ptr->chunkdata);
    1470                 : 
    1471                 :    /* Integrity-check the data length */
    1472                 :    if (data_length % entry_size)
    1473                 :    {
    1474                 :       png_free(png_ptr, png_ptr->chunkdata);
    1475                 :       png_ptr->chunkdata = NULL;
    1476                 :       png_warning(png_ptr, "sPLT chunk has bad length");
    1477                 :       return;
    1478                 :    }
    1479                 : 
    1480                 :    dl = (png_int_32)(data_length / entry_size);
    1481                 :    max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
    1482                 : 
    1483                 :    if (dl > max_dl)
    1484                 :    {
    1485                 :        png_warning(png_ptr, "sPLT chunk too long");
    1486                 :        return;
    1487                 :    }
    1488                 : 
    1489                 :    new_palette.nentries = (png_int_32)(data_length / entry_size);
    1490                 : 
    1491                 :    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
    1492                 :        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
    1493                 : 
    1494                 :    if (new_palette.entries == NULL)
    1495                 :    {
    1496                 :        png_warning(png_ptr, "sPLT chunk requires too much memory");
    1497                 :        return;
    1498                 :    }
    1499                 : 
    1500                 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
    1501                 :    for (i = 0; i < new_palette.nentries; i++)
    1502                 :    {
    1503                 :       pp = new_palette.entries + i;
    1504                 : 
    1505                 :       if (new_palette.depth == 8)
    1506                 :       {
    1507                 :          pp->red = *entry_start++;
    1508                 :          pp->green = *entry_start++;
    1509                 :          pp->blue = *entry_start++;
    1510                 :          pp->alpha = *entry_start++;
    1511                 :       }
    1512                 : 
    1513                 :       else
    1514                 :       {
    1515                 :          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
    1516                 :          pp->green = png_get_uint_16(entry_start); entry_start += 2;
    1517                 :          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
    1518                 :          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
    1519                 :       }
    1520                 : 
    1521                 :       pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
    1522                 :    }
    1523                 : #else
    1524                 :    pp = new_palette.entries;
    1525                 : 
    1526                 :    for (i = 0; i < new_palette.nentries; i++)
    1527                 :    {
    1528                 : 
    1529                 :       if (new_palette.depth == 8)
    1530                 :       {
    1531                 :          pp[i].red   = *entry_start++;
    1532                 :          pp[i].green = *entry_start++;
    1533                 :          pp[i].blue  = *entry_start++;
    1534                 :          pp[i].alpha = *entry_start++;
    1535                 :       }
    1536                 : 
    1537                 :       else
    1538                 :       {
    1539                 :          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
    1540                 :          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
    1541                 :          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
    1542                 :          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
    1543                 :       }
    1544                 : 
    1545                 :       pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
    1546                 :    }
    1547                 : #endif
    1548                 : 
    1549                 :    /* Discard all chunk data except the name and stash that */
    1550                 :    new_palette.name = png_ptr->chunkdata;
    1551                 : 
    1552                 :    png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
    1553                 : 
    1554                 :    png_free(png_ptr, png_ptr->chunkdata);
    1555                 :    png_ptr->chunkdata = NULL;
    1556                 :    png_free(png_ptr, new_palette.entries);
    1557                 : }
    1558                 : #endif /* PNG_READ_sPLT_SUPPORTED */
    1559                 : 
    1560                 : #ifdef PNG_READ_tRNS_SUPPORTED
    1561                 : void /* PRIVATE */
    1562               0 : png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1563                 : {
    1564                 :    png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
    1565                 : 
    1566                 :    png_debug(1, "in png_handle_tRNS");
    1567                 : 
    1568               0 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1569               0 :       png_error(png_ptr, "Missing IHDR before tRNS");
    1570                 : 
    1571               0 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1572                 :    {
    1573                 :       png_warning(png_ptr, "Invalid tRNS after IDAT");
    1574               0 :       png_crc_finish(png_ptr, length);
    1575               0 :       return;
    1576                 :    }
    1577                 : 
    1578               0 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
    1579                 :    {
    1580                 :       png_warning(png_ptr, "Duplicate tRNS chunk");
    1581               0 :       png_crc_finish(png_ptr, length);
    1582               0 :       return;
    1583                 :    }
    1584                 : 
    1585               0 :    if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    1586                 :    {
    1587                 :       png_byte buf[2];
    1588                 : 
    1589               0 :       if (length != 2)
    1590                 :       {
    1591                 :          png_warning(png_ptr, "Incorrect tRNS chunk length");
    1592               0 :          png_crc_finish(png_ptr, length);
    1593               0 :          return;
    1594                 :       }
    1595                 : 
    1596               0 :       png_crc_read(png_ptr, buf, 2);
    1597               0 :       png_ptr->num_trans = 1;
    1598               0 :       png_ptr->trans_color.gray = png_get_uint_16(buf);
    1599                 :    }
    1600                 : 
    1601               0 :    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
    1602                 :    {
    1603                 :       png_byte buf[6];
    1604                 : 
    1605               0 :       if (length != 6)
    1606                 :       {
    1607                 :          png_warning(png_ptr, "Incorrect tRNS chunk length");
    1608               0 :          png_crc_finish(png_ptr, length);
    1609               0 :          return;
    1610                 :       }
    1611                 : 
    1612               0 :       png_crc_read(png_ptr, buf, (png_size_t)length);
    1613               0 :       png_ptr->num_trans = 1;
    1614               0 :       png_ptr->trans_color.red = png_get_uint_16(buf);
    1615               0 :       png_ptr->trans_color.green = png_get_uint_16(buf + 2);
    1616               0 :       png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
    1617                 :    }
    1618                 : 
    1619               0 :    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    1620                 :    {
    1621               0 :       if (!(png_ptr->mode & PNG_HAVE_PLTE))
    1622                 :       {
    1623                 :          /* Should be an error, but we can cope with it. */
    1624                 :          png_warning(png_ptr, "Missing PLTE before tRNS");
    1625                 :       }
    1626                 : 
    1627               0 :       if (length > (png_uint_32)png_ptr->num_palette ||
    1628                 :           length > PNG_MAX_PALETTE_LENGTH)
    1629                 :       {
    1630                 :          png_warning(png_ptr, "Incorrect tRNS chunk length");
    1631               0 :          png_crc_finish(png_ptr, length);
    1632               0 :          return;
    1633                 :       }
    1634                 : 
    1635               0 :       if (length == 0)
    1636                 :       {
    1637                 :          png_warning(png_ptr, "Zero length tRNS chunk");
    1638               0 :          png_crc_finish(png_ptr, length);
    1639               0 :          return;
    1640                 :       }
    1641                 : 
    1642               0 :       png_crc_read(png_ptr, readbuf, (png_size_t)length);
    1643               0 :       png_ptr->num_trans = (png_uint_16)length;
    1644                 :    }
    1645                 : 
    1646                 :    else
    1647                 :    {
    1648                 :       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
    1649               0 :       png_crc_finish(png_ptr, length);
    1650               0 :       return;
    1651                 :    }
    1652                 : 
    1653               0 :    if (png_crc_finish(png_ptr, 0))
    1654                 :    {
    1655               0 :       png_ptr->num_trans = 0;
    1656               0 :       return;
    1657                 :    }
    1658                 : 
    1659               0 :    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
    1660               0 :        &(png_ptr->trans_color));
    1661                 : }
    1662                 : #endif
    1663                 : 
    1664                 : #ifdef PNG_READ_bKGD_SUPPORTED
    1665                 : void /* PRIVATE */
    1666                 : png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1667                 : {
    1668                 :    png_size_t truelen;
    1669                 :    png_byte buf[6];
    1670                 :    png_color_16 background;
    1671                 : 
    1672                 :    png_debug(1, "in png_handle_bKGD");
    1673                 : 
    1674                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1675                 :       png_error(png_ptr, "Missing IHDR before bKGD");
    1676                 : 
    1677                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1678                 :    {
    1679                 :       png_warning(png_ptr, "Invalid bKGD after IDAT");
    1680                 :       png_crc_finish(png_ptr, length);
    1681                 :       return;
    1682                 :    }
    1683                 : 
    1684                 :    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
    1685                 :        !(png_ptr->mode & PNG_HAVE_PLTE))
    1686                 :    {
    1687                 :       png_warning(png_ptr, "Missing PLTE before bKGD");
    1688                 :       png_crc_finish(png_ptr, length);
    1689                 :       return;
    1690                 :    }
    1691                 : 
    1692                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
    1693                 :    {
    1694                 :       png_warning(png_ptr, "Duplicate bKGD chunk");
    1695                 :       png_crc_finish(png_ptr, length);
    1696                 :       return;
    1697                 :    }
    1698                 : 
    1699                 :    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    1700                 :       truelen = 1;
    1701                 : 
    1702                 :    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
    1703                 :       truelen = 6;
    1704                 : 
    1705                 :    else
    1706                 :       truelen = 2;
    1707                 : 
    1708                 :    if (length != truelen)
    1709                 :    {
    1710                 :       png_warning(png_ptr, "Incorrect bKGD chunk length");
    1711                 :       png_crc_finish(png_ptr, length);
    1712                 :       return;
    1713                 :    }
    1714                 : 
    1715                 :    png_crc_read(png_ptr, buf, truelen);
    1716                 : 
    1717                 :    if (png_crc_finish(png_ptr, 0))
    1718                 :       return;
    1719                 : 
    1720                 :    /* We convert the index value into RGB components so that we can allow
    1721                 :     * arbitrary RGB values for background when we have transparency, and
    1722                 :     * so it is easy to determine the RGB values of the background color
    1723                 :     * from the info_ptr struct.
    1724                 :     */
    1725                 :    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    1726                 :    {
    1727                 :       background.index = buf[0];
    1728                 : 
    1729                 :       if (info_ptr && info_ptr->num_palette)
    1730                 :       {
    1731                 :          if (buf[0] >= info_ptr->num_palette)
    1732                 :          {
    1733                 :             png_warning(png_ptr, "Incorrect bKGD chunk index value");
    1734                 :             return;
    1735                 :          }
    1736                 : 
    1737                 :          background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
    1738                 :          background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
    1739                 :          background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
    1740                 :       }
    1741                 : 
    1742                 :       else
    1743                 :          background.red = background.green = background.blue = 0;
    1744                 : 
    1745                 :       background.gray = 0;
    1746                 :    }
    1747                 : 
    1748                 :    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
    1749                 :    {
    1750                 :       background.index = 0;
    1751                 :       background.red =
    1752                 :       background.green =
    1753                 :       background.blue =
    1754                 :       background.gray = png_get_uint_16(buf);
    1755                 :    }
    1756                 : 
    1757                 :    else
    1758                 :    {
    1759                 :       background.index = 0;
    1760                 :       background.red = png_get_uint_16(buf);
    1761                 :       background.green = png_get_uint_16(buf + 2);
    1762                 :       background.blue = png_get_uint_16(buf + 4);
    1763                 :       background.gray = 0;
    1764                 :    }
    1765                 : 
    1766                 :    png_set_bKGD(png_ptr, info_ptr, &background);
    1767                 : }
    1768                 : #endif
    1769                 : 
    1770                 : #ifdef PNG_READ_hIST_SUPPORTED
    1771                 : void /* PRIVATE */
    1772                 : png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1773                 : {
    1774                 :    unsigned int num, i;
    1775                 :    png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
    1776                 : 
    1777                 :    png_debug(1, "in png_handle_hIST");
    1778                 : 
    1779                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1780                 :       png_error(png_ptr, "Missing IHDR before hIST");
    1781                 : 
    1782                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1783                 :    {
    1784                 :       png_warning(png_ptr, "Invalid hIST after IDAT");
    1785                 :       png_crc_finish(png_ptr, length);
    1786                 :       return;
    1787                 :    }
    1788                 : 
    1789                 :    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
    1790                 :    {
    1791                 :       png_warning(png_ptr, "Missing PLTE before hIST");
    1792                 :       png_crc_finish(png_ptr, length);
    1793                 :       return;
    1794                 :    }
    1795                 : 
    1796                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
    1797                 :    {
    1798                 :       png_warning(png_ptr, "Duplicate hIST chunk");
    1799                 :       png_crc_finish(png_ptr, length);
    1800                 :       return;
    1801                 :    }
    1802                 : 
    1803                 :    num = length / 2 ;
    1804                 : 
    1805                 :    if (num != (unsigned int)png_ptr->num_palette || num >
    1806                 :        (unsigned int)PNG_MAX_PALETTE_LENGTH)
    1807                 :    {
    1808                 :       png_warning(png_ptr, "Incorrect hIST chunk length");
    1809                 :       png_crc_finish(png_ptr, length);
    1810                 :       return;
    1811                 :    }
    1812                 : 
    1813                 :    for (i = 0; i < num; i++)
    1814                 :    {
    1815                 :       png_byte buf[2];
    1816                 : 
    1817                 :       png_crc_read(png_ptr, buf, 2);
    1818                 :       readbuf[i] = png_get_uint_16(buf);
    1819                 :    }
    1820                 : 
    1821                 :    if (png_crc_finish(png_ptr, 0))
    1822                 :       return;
    1823                 : 
    1824                 :    png_set_hIST(png_ptr, info_ptr, readbuf);
    1825                 : }
    1826                 : #endif
    1827                 : 
    1828                 : #ifdef PNG_READ_pHYs_SUPPORTED
    1829                 : void /* PRIVATE */
    1830                 : png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1831                 : {
    1832                 :    png_byte buf[9];
    1833                 :    png_uint_32 res_x, res_y;
    1834                 :    int unit_type;
    1835                 : 
    1836                 :    png_debug(1, "in png_handle_pHYs");
    1837                 : 
    1838                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1839                 :       png_error(png_ptr, "Missing IHDR before pHYs");
    1840                 : 
    1841                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1842                 :    {
    1843                 :       png_warning(png_ptr, "Invalid pHYs after IDAT");
    1844                 :       png_crc_finish(png_ptr, length);
    1845                 :       return;
    1846                 :    }
    1847                 : 
    1848                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
    1849                 :    {
    1850                 :       png_warning(png_ptr, "Duplicate pHYs chunk");
    1851                 :       png_crc_finish(png_ptr, length);
    1852                 :       return;
    1853                 :    }
    1854                 : 
    1855                 :    if (length != 9)
    1856                 :    {
    1857                 :       png_warning(png_ptr, "Incorrect pHYs chunk length");
    1858                 :       png_crc_finish(png_ptr, length);
    1859                 :       return;
    1860                 :    }
    1861                 : 
    1862                 :    png_crc_read(png_ptr, buf, 9);
    1863                 : 
    1864                 :    if (png_crc_finish(png_ptr, 0))
    1865                 :       return;
    1866                 : 
    1867                 :    res_x = png_get_uint_32(buf);
    1868                 :    res_y = png_get_uint_32(buf + 4);
    1869                 :    unit_type = buf[8];
    1870                 :    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
    1871                 : }
    1872                 : #endif
    1873                 : 
    1874                 : #ifdef PNG_READ_oFFs_SUPPORTED
    1875                 : void /* PRIVATE */
    1876                 : png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1877                 : {
    1878                 :    png_byte buf[9];
    1879                 :    png_int_32 offset_x, offset_y;
    1880                 :    int unit_type;
    1881                 : 
    1882                 :    png_debug(1, "in png_handle_oFFs");
    1883                 : 
    1884                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1885                 :       png_error(png_ptr, "Missing IHDR before oFFs");
    1886                 : 
    1887                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1888                 :    {
    1889                 :       png_warning(png_ptr, "Invalid oFFs after IDAT");
    1890                 :       png_crc_finish(png_ptr, length);
    1891                 :       return;
    1892                 :    }
    1893                 : 
    1894                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
    1895                 :    {
    1896                 :       png_warning(png_ptr, "Duplicate oFFs chunk");
    1897                 :       png_crc_finish(png_ptr, length);
    1898                 :       return;
    1899                 :    }
    1900                 : 
    1901                 :    if (length != 9)
    1902                 :    {
    1903                 :       png_warning(png_ptr, "Incorrect oFFs chunk length");
    1904                 :       png_crc_finish(png_ptr, length);
    1905                 :       return;
    1906                 :    }
    1907                 : 
    1908                 :    png_crc_read(png_ptr, buf, 9);
    1909                 : 
    1910                 :    if (png_crc_finish(png_ptr, 0))
    1911                 :       return;
    1912                 : 
    1913                 :    offset_x = png_get_int_32(buf);
    1914                 :    offset_y = png_get_int_32(buf + 4);
    1915                 :    unit_type = buf[8];
    1916                 :    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
    1917                 : }
    1918                 : #endif
    1919                 : 
    1920                 : #ifdef PNG_READ_pCAL_SUPPORTED
    1921                 : /* Read the pCAL chunk (described in the PNG Extensions document) */
    1922                 : void /* PRIVATE */
    1923                 : png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    1924                 : {
    1925                 :    png_int_32 X0, X1;
    1926                 :    png_byte type, nparams;
    1927                 :    png_charp buf, units, endptr;
    1928                 :    png_charpp params;
    1929                 :    png_size_t slength;
    1930                 :    int i;
    1931                 : 
    1932                 :    png_debug(1, "in png_handle_pCAL");
    1933                 : 
    1934                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    1935                 :       png_error(png_ptr, "Missing IHDR before pCAL");
    1936                 : 
    1937                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    1938                 :    {
    1939                 :       png_warning(png_ptr, "Invalid pCAL after IDAT");
    1940                 :       png_crc_finish(png_ptr, length);
    1941                 :       return;
    1942                 :    }
    1943                 : 
    1944                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
    1945                 :    {
    1946                 :       png_warning(png_ptr, "Duplicate pCAL chunk");
    1947                 :       png_crc_finish(png_ptr, length);
    1948                 :       return;
    1949                 :    }
    1950                 : 
    1951                 :    png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
    1952                 :        length + 1);
    1953                 :    png_free(png_ptr, png_ptr->chunkdata);
    1954                 :    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    1955                 : 
    1956                 :    if (png_ptr->chunkdata == NULL)
    1957                 :    {
    1958                 :       png_warning(png_ptr, "No memory for pCAL purpose");
    1959                 :       return;
    1960                 :    }
    1961                 : 
    1962                 :    slength = length;
    1963                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    1964                 : 
    1965                 :    if (png_crc_finish(png_ptr, 0))
    1966                 :    {
    1967                 :       png_free(png_ptr, png_ptr->chunkdata);
    1968                 :       png_ptr->chunkdata = NULL;
    1969                 :       return;
    1970                 :    }
    1971                 : 
    1972                 :    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
    1973                 : 
    1974                 :    png_debug(3, "Finding end of pCAL purpose string");
    1975                 :    for (buf = png_ptr->chunkdata; *buf; buf++)
    1976                 :       /* Empty loop */ ;
    1977                 : 
    1978                 :    endptr = png_ptr->chunkdata + slength;
    1979                 : 
    1980                 :    /* We need to have at least 12 bytes after the purpose string
    1981                 :     * in order to get the parameter information.
    1982                 :     */
    1983                 :    if (endptr <= buf + 12)
    1984                 :    {
    1985                 :       png_warning(png_ptr, "Invalid pCAL data");
    1986                 :       png_free(png_ptr, png_ptr->chunkdata);
    1987                 :       png_ptr->chunkdata = NULL;
    1988                 :       return;
    1989                 :    }
    1990                 : 
    1991                 :    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
    1992                 :    X0 = png_get_int_32((png_bytep)buf+1);
    1993                 :    X1 = png_get_int_32((png_bytep)buf+5);
    1994                 :    type = buf[9];
    1995                 :    nparams = buf[10];
    1996                 :    units = buf + 11;
    1997                 : 
    1998                 :    png_debug(3, "Checking pCAL equation type and number of parameters");
    1999                 :    /* Check that we have the right number of parameters for known
    2000                 :     * equation types.
    2001                 :     */
    2002                 :    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
    2003                 :        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
    2004                 :        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
    2005                 :        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
    2006                 :    {
    2007                 :       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
    2008                 :       png_free(png_ptr, png_ptr->chunkdata);
    2009                 :       png_ptr->chunkdata = NULL;
    2010                 :       return;
    2011                 :    }
    2012                 : 
    2013                 :    else if (type >= PNG_EQUATION_LAST)
    2014                 :    {
    2015                 :       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
    2016                 :    }
    2017                 : 
    2018                 :    for (buf = units; *buf; buf++)
    2019                 :       /* Empty loop to move past the units string. */ ;
    2020                 : 
    2021                 :    png_debug(3, "Allocating pCAL parameters array");
    2022                 : 
    2023                 :    params = (png_charpp)png_malloc_warn(png_ptr,
    2024                 :        (png_size_t)(nparams * png_sizeof(png_charp)));
    2025                 : 
    2026                 :    if (params == NULL)
    2027                 :    {
    2028                 :       png_free(png_ptr, png_ptr->chunkdata);
    2029                 :       png_ptr->chunkdata = NULL;
    2030                 :       png_warning(png_ptr, "No memory for pCAL params");
    2031                 :       return;
    2032                 :    }
    2033                 : 
    2034                 :    /* Get pointers to the start of each parameter string. */
    2035                 :    for (i = 0; i < (int)nparams; i++)
    2036                 :    {
    2037                 :       buf++; /* Skip the null string terminator from previous parameter. */
    2038                 : 
    2039                 :       png_debug1(3, "Reading pCAL parameter %d", i);
    2040                 : 
    2041                 :       for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
    2042                 :          /* Empty loop to move past each parameter string */ ;
    2043                 : 
    2044                 :       /* Make sure we haven't run out of data yet */
    2045                 :       if (buf > endptr)
    2046                 :       {
    2047                 :          png_warning(png_ptr, "Invalid pCAL data");
    2048                 :          png_free(png_ptr, png_ptr->chunkdata);
    2049                 :          png_ptr->chunkdata = NULL;
    2050                 :          png_free(png_ptr, params);
    2051                 :          return;
    2052                 :       }
    2053                 :    }
    2054                 : 
    2055                 :    png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
    2056                 :       units, params);
    2057                 : 
    2058                 :    png_free(png_ptr, png_ptr->chunkdata);
    2059                 :    png_ptr->chunkdata = NULL;
    2060                 :    png_free(png_ptr, params);
    2061                 : }
    2062                 : #endif
    2063                 : 
    2064                 : #ifdef PNG_READ_sCAL_SUPPORTED
    2065                 : /* Read the sCAL chunk */
    2066                 : void /* PRIVATE */
    2067                 : png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2068                 : {
    2069                 :    png_size_t slength, i;
    2070                 :    int state;
    2071                 : 
    2072                 :    png_debug(1, "in png_handle_sCAL");
    2073                 : 
    2074                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2075                 :       png_error(png_ptr, "Missing IHDR before sCAL");
    2076                 : 
    2077                 :    else if (png_ptr->mode & PNG_HAVE_IDAT)
    2078                 :    {
    2079                 :       png_warning(png_ptr, "Invalid sCAL after IDAT");
    2080                 :       png_crc_finish(png_ptr, length);
    2081                 :       return;
    2082                 :    }
    2083                 : 
    2084                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
    2085                 :    {
    2086                 :       png_warning(png_ptr, "Duplicate sCAL chunk");
    2087                 :       png_crc_finish(png_ptr, length);
    2088                 :       return;
    2089                 :    }
    2090                 : 
    2091                 :    /* Need unit type, width, \0, height: minimum 4 bytes */
    2092                 :    else if (length < 4)
    2093                 :    {
    2094                 :       png_warning(png_ptr, "sCAL chunk too short");
    2095                 :       png_crc_finish(png_ptr, length);
    2096                 :       return;
    2097                 :    }
    2098                 : 
    2099                 :    png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
    2100                 :       length + 1);
    2101                 : 
    2102                 :    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    2103                 : 
    2104                 :    if (png_ptr->chunkdata == NULL)
    2105                 :    {
    2106                 :       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
    2107                 :       png_crc_finish(png_ptr, length);
    2108                 :       return;
    2109                 :    }
    2110                 : 
    2111                 :    slength = length;
    2112                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    2113                 :    png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
    2114                 : 
    2115                 :    if (png_crc_finish(png_ptr, 0))
    2116                 :    {
    2117                 :       png_free(png_ptr, png_ptr->chunkdata);
    2118                 :       png_ptr->chunkdata = NULL;
    2119                 :       return;
    2120                 :    }
    2121                 : 
    2122                 :    /* Validate the unit. */
    2123                 :    if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
    2124                 :    {
    2125                 :       png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
    2126                 :       png_free(png_ptr, png_ptr->chunkdata);
    2127                 :       png_ptr->chunkdata = NULL;
    2128                 :       return;
    2129                 :    }
    2130                 : 
    2131                 :    /* Validate the ASCII numbers, need two ASCII numbers separated by
    2132                 :     * a '\0' and they need to fit exactly in the chunk data.
    2133                 :     */
    2134                 :    i = 1;
    2135                 :    state = 0;
    2136                 : 
    2137                 :    if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
    2138                 :        i >= slength || png_ptr->chunkdata[i++] != 0)
    2139                 :       png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
    2140                 : 
    2141                 :    else if (!PNG_FP_IS_POSITIVE(state))
    2142                 :       png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");
    2143                 : 
    2144                 :    else
    2145                 :    {
    2146                 :       png_size_t heighti = i;
    2147                 : 
    2148                 :       state = 0;
    2149                 :       if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
    2150                 :           i != slength)
    2151                 :          png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
    2152                 : 
    2153                 :       else if (!PNG_FP_IS_POSITIVE(state))
    2154                 :          png_warning(png_ptr,
    2155                 :             "Invalid sCAL chunk ignored: non-positive height");
    2156                 : 
    2157                 :       else
    2158                 :          /* This is the (only) success case. */
    2159                 :          png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
    2160                 :             png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
    2161                 :    }
    2162                 : 
    2163                 :    /* Clean up - just free the temporarily allocated buffer. */
    2164                 :    png_free(png_ptr, png_ptr->chunkdata);
    2165                 :    png_ptr->chunkdata = NULL;
    2166                 : }
    2167                 : #endif
    2168                 : 
    2169                 : #ifdef PNG_READ_tIME_SUPPORTED
    2170                 : void /* PRIVATE */
    2171                 : png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2172                 : {
    2173                 :    png_byte buf[7];
    2174                 :    png_time mod_time;
    2175                 : 
    2176                 :    png_debug(1, "in png_handle_tIME");
    2177                 : 
    2178                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2179                 :       png_error(png_ptr, "Out of place tIME chunk");
    2180                 : 
    2181                 :    else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
    2182                 :    {
    2183                 :       png_warning(png_ptr, "Duplicate tIME chunk");
    2184                 :       png_crc_finish(png_ptr, length);
    2185                 :       return;
    2186                 :    }
    2187                 : 
    2188                 :    if (png_ptr->mode & PNG_HAVE_IDAT)
    2189                 :       png_ptr->mode |= PNG_AFTER_IDAT;
    2190                 : 
    2191                 :    if (length != 7)
    2192                 :    {
    2193                 :       png_warning(png_ptr, "Incorrect tIME chunk length");
    2194                 :       png_crc_finish(png_ptr, length);
    2195                 :       return;
    2196                 :    }
    2197                 : 
    2198                 :    png_crc_read(png_ptr, buf, 7);
    2199                 : 
    2200                 :    if (png_crc_finish(png_ptr, 0))
    2201                 :       return;
    2202                 : 
    2203                 :    mod_time.second = buf[6];
    2204                 :    mod_time.minute = buf[5];
    2205                 :    mod_time.hour = buf[4];
    2206                 :    mod_time.day = buf[3];
    2207                 :    mod_time.month = buf[2];
    2208                 :    mod_time.year = png_get_uint_16(buf);
    2209                 : 
    2210                 :    png_set_tIME(png_ptr, info_ptr, &mod_time);
    2211                 : }
    2212                 : #endif
    2213                 : 
    2214                 : #ifdef PNG_READ_tEXt_SUPPORTED
    2215                 : /* Note: this does not properly handle chunks that are > 64K under DOS */
    2216                 : void /* PRIVATE */
    2217                 : png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2218                 : {
    2219                 :    png_textp text_ptr;
    2220                 :    png_charp key;
    2221                 :    png_charp text;
    2222                 :    png_uint_32 skip = 0;
    2223                 :    png_size_t slength;
    2224                 :    int ret;
    2225                 : 
    2226                 :    png_debug(1, "in png_handle_tEXt");
    2227                 : 
    2228                 : #ifdef PNG_USER_LIMITS_SUPPORTED
    2229                 :    if (png_ptr->user_chunk_cache_max != 0)
    2230                 :    {
    2231                 :       if (png_ptr->user_chunk_cache_max == 1)
    2232                 :       {
    2233                 :          png_crc_finish(png_ptr, length);
    2234                 :          return;
    2235                 :       }
    2236                 : 
    2237                 :       if (--png_ptr->user_chunk_cache_max == 1)
    2238                 :       {
    2239                 :          png_warning(png_ptr, "No space in chunk cache for tEXt");
    2240                 :          png_crc_finish(png_ptr, length);
    2241                 :          return;
    2242                 :       }
    2243                 :    }
    2244                 : #endif
    2245                 : 
    2246                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2247                 :       png_error(png_ptr, "Missing IHDR before tEXt");
    2248                 : 
    2249                 :    if (png_ptr->mode & PNG_HAVE_IDAT)
    2250                 :       png_ptr->mode |= PNG_AFTER_IDAT;
    2251                 : 
    2252                 : #ifdef PNG_MAX_MALLOC_64K
    2253                 :    if (length > (png_uint_32)65535L)
    2254                 :    {
    2255                 :       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
    2256                 :       skip = length - (png_uint_32)65535L;
    2257                 :       length = (png_uint_32)65535L;
    2258                 :    }
    2259                 : #endif
    2260                 : 
    2261                 :    png_free(png_ptr, png_ptr->chunkdata);
    2262                 : 
    2263                 :    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    2264                 : 
    2265                 :    if (png_ptr->chunkdata == NULL)
    2266                 :    {
    2267                 :      png_warning(png_ptr, "No memory to process text chunk");
    2268                 :      return;
    2269                 :    }
    2270                 : 
    2271                 :    slength = length;
    2272                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    2273                 : 
    2274                 :    if (png_crc_finish(png_ptr, skip))
    2275                 :    {
    2276                 :       png_free(png_ptr, png_ptr->chunkdata);
    2277                 :       png_ptr->chunkdata = NULL;
    2278                 :       return;
    2279                 :    }
    2280                 : 
    2281                 :    key = png_ptr->chunkdata;
    2282                 : 
    2283                 :    key[slength] = 0x00;
    2284                 : 
    2285                 :    for (text = key; *text; text++)
    2286                 :       /* Empty loop to find end of key */ ;
    2287                 : 
    2288                 :    if (text != key + slength)
    2289                 :       text++;
    2290                 : 
    2291                 :    text_ptr = (png_textp)png_malloc_warn(png_ptr,
    2292                 :        png_sizeof(png_text));
    2293                 : 
    2294                 :    if (text_ptr == NULL)
    2295                 :    {
    2296                 :       png_warning(png_ptr, "Not enough memory to process text chunk");
    2297                 :       png_free(png_ptr, png_ptr->chunkdata);
    2298                 :       png_ptr->chunkdata = NULL;
    2299                 :       return;
    2300                 :    }
    2301                 : 
    2302                 :    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
    2303                 :    text_ptr->key = key;
    2304                 :    text_ptr->lang = NULL;
    2305                 :    text_ptr->lang_key = NULL;
    2306                 :    text_ptr->itxt_length = 0;
    2307                 :    text_ptr->text = text;
    2308                 :    text_ptr->text_length = png_strlen(text);
    2309                 : 
    2310                 :    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    2311                 : 
    2312                 :    png_free(png_ptr, png_ptr->chunkdata);
    2313                 :    png_ptr->chunkdata = NULL;
    2314                 :    png_free(png_ptr, text_ptr);
    2315                 : 
    2316                 :    if (ret)
    2317                 :       png_warning(png_ptr, "Insufficient memory to process text chunk");
    2318                 : }
    2319                 : #endif
    2320                 : 
    2321                 : #ifdef PNG_READ_zTXt_SUPPORTED
    2322                 : /* Note: this does not correctly handle chunks that are > 64K under DOS */
    2323                 : void /* PRIVATE */
    2324                 : png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2325                 : {
    2326                 :    png_textp text_ptr;
    2327                 :    png_charp text;
    2328                 :    int comp_type;
    2329                 :    int ret;
    2330                 :    png_size_t slength, prefix_len, data_len;
    2331                 : 
    2332                 :    png_debug(1, "in png_handle_zTXt");
    2333                 : 
    2334                 : #ifdef PNG_USER_LIMITS_SUPPORTED
    2335                 :    if (png_ptr->user_chunk_cache_max != 0)
    2336                 :    {
    2337                 :       if (png_ptr->user_chunk_cache_max == 1)
    2338                 :       {
    2339                 :          png_crc_finish(png_ptr, length);
    2340                 :          return;
    2341                 :       }
    2342                 : 
    2343                 :       if (--png_ptr->user_chunk_cache_max == 1)
    2344                 :       {
    2345                 :          png_warning(png_ptr, "No space in chunk cache for zTXt");
    2346                 :          png_crc_finish(png_ptr, length);
    2347                 :          return;
    2348                 :       }
    2349                 :    }
    2350                 : #endif
    2351                 : 
    2352                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2353                 :       png_error(png_ptr, "Missing IHDR before zTXt");
    2354                 : 
    2355                 :    if (png_ptr->mode & PNG_HAVE_IDAT)
    2356                 :       png_ptr->mode |= PNG_AFTER_IDAT;
    2357                 : 
    2358                 : #ifdef PNG_MAX_MALLOC_64K
    2359                 :    /* We will no doubt have problems with chunks even half this size, but
    2360                 :     * there is no hard and fast rule to tell us where to stop.
    2361                 :     */
    2362                 :    if (length > (png_uint_32)65535L)
    2363                 :    {
    2364                 :       png_warning(png_ptr, "zTXt chunk too large to fit in memory");
    2365                 :       png_crc_finish(png_ptr, length);
    2366                 :       return;
    2367                 :    }
    2368                 : #endif
    2369                 : 
    2370                 :    png_free(png_ptr, png_ptr->chunkdata);
    2371                 :    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    2372                 : 
    2373                 :    if (png_ptr->chunkdata == NULL)
    2374                 :    {
    2375                 :       png_warning(png_ptr, "Out of memory processing zTXt chunk");
    2376                 :       return;
    2377                 :    }
    2378                 : 
    2379                 :    slength = length;
    2380                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    2381                 : 
    2382                 :    if (png_crc_finish(png_ptr, 0))
    2383                 :    {
    2384                 :       png_free(png_ptr, png_ptr->chunkdata);
    2385                 :       png_ptr->chunkdata = NULL;
    2386                 :       return;
    2387                 :    }
    2388                 : 
    2389                 :    png_ptr->chunkdata[slength] = 0x00;
    2390                 : 
    2391                 :    for (text = png_ptr->chunkdata; *text; text++)
    2392                 :       /* Empty loop */ ;
    2393                 : 
    2394                 :    /* zTXt must have some text after the chunkdataword */
    2395                 :    if (text >= png_ptr->chunkdata + slength - 2)
    2396                 :    {
    2397                 :       png_warning(png_ptr, "Truncated zTXt chunk");
    2398                 :       png_free(png_ptr, png_ptr->chunkdata);
    2399                 :       png_ptr->chunkdata = NULL;
    2400                 :       return;
    2401                 :    }
    2402                 : 
    2403                 :    else
    2404                 :    {
    2405                 :        comp_type = *(++text);
    2406                 : 
    2407                 :        if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
    2408                 :        {
    2409                 :           png_warning(png_ptr, "Unknown compression type in zTXt chunk");
    2410                 :           comp_type = PNG_TEXT_COMPRESSION_zTXt;
    2411                 :        }
    2412                 : 
    2413                 :        text++;        /* Skip the compression_method byte */
    2414                 :    }
    2415                 : 
    2416                 :    prefix_len = text - png_ptr->chunkdata;
    2417                 : 
    2418                 :    png_decompress_chunk(png_ptr, comp_type,
    2419                 :        (png_size_t)length, prefix_len, &data_len);
    2420                 : 
    2421                 :    text_ptr = (png_textp)png_malloc_warn(png_ptr,
    2422                 :        png_sizeof(png_text));
    2423                 : 
    2424                 :    if (text_ptr == NULL)
    2425                 :    {
    2426                 :       png_warning(png_ptr, "Not enough memory to process zTXt chunk");
    2427                 :       png_free(png_ptr, png_ptr->chunkdata);
    2428                 :       png_ptr->chunkdata = NULL;
    2429                 :       return;
    2430                 :    }
    2431                 : 
    2432                 :    text_ptr->compression = comp_type;
    2433                 :    text_ptr->key = png_ptr->chunkdata;
    2434                 :    text_ptr->lang = NULL;
    2435                 :    text_ptr->lang_key = NULL;
    2436                 :    text_ptr->itxt_length = 0;
    2437                 :    text_ptr->text = png_ptr->chunkdata + prefix_len;
    2438                 :    text_ptr->text_length = data_len;
    2439                 : 
    2440                 :    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    2441                 : 
    2442                 :    png_free(png_ptr, text_ptr);
    2443                 :    png_free(png_ptr, png_ptr->chunkdata);
    2444                 :    png_ptr->chunkdata = NULL;
    2445                 : 
    2446                 :    if (ret)
    2447                 :       png_error(png_ptr, "Insufficient memory to store zTXt chunk");
    2448                 : }
    2449                 : #endif
    2450                 : 
    2451                 : #ifdef PNG_READ_iTXt_SUPPORTED
    2452                 : /* Note: this does not correctly handle chunks that are > 64K under DOS */
    2453                 : void /* PRIVATE */
    2454                 : png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2455                 : {
    2456                 :    png_textp text_ptr;
    2457                 :    png_charp key, lang, text, lang_key;
    2458                 :    int comp_flag;
    2459                 :    int comp_type = 0;
    2460                 :    int ret;
    2461                 :    png_size_t slength, prefix_len, data_len;
    2462                 : 
    2463                 :    png_debug(1, "in png_handle_iTXt");
    2464                 : 
    2465                 : #ifdef PNG_USER_LIMITS_SUPPORTED
    2466                 :    if (png_ptr->user_chunk_cache_max != 0)
    2467                 :    {
    2468                 :       if (png_ptr->user_chunk_cache_max == 1)
    2469                 :       {
    2470                 :          png_crc_finish(png_ptr, length);
    2471                 :          return;
    2472                 :       }
    2473                 : 
    2474                 :       if (--png_ptr->user_chunk_cache_max == 1)
    2475                 :       {
    2476                 :          png_warning(png_ptr, "No space in chunk cache for iTXt");
    2477                 :          png_crc_finish(png_ptr, length);
    2478                 :          return;
    2479                 :       }
    2480                 :    }
    2481                 : #endif
    2482                 : 
    2483                 :    if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2484                 :       png_error(png_ptr, "Missing IHDR before iTXt");
    2485                 : 
    2486                 :    if (png_ptr->mode & PNG_HAVE_IDAT)
    2487                 :       png_ptr->mode |= PNG_AFTER_IDAT;
    2488                 : 
    2489                 : #ifdef PNG_MAX_MALLOC_64K
    2490                 :    /* We will no doubt have problems with chunks even half this size, but
    2491                 :     * there is no hard and fast rule to tell us where to stop.
    2492                 :     */
    2493                 :    if (length > (png_uint_32)65535L)
    2494                 :    {
    2495                 :       png_warning(png_ptr, "iTXt chunk too large to fit in memory");
    2496                 :       png_crc_finish(png_ptr, length);
    2497                 :       return;
    2498                 :    }
    2499                 : #endif
    2500                 : 
    2501                 :    png_free(png_ptr, png_ptr->chunkdata);
    2502                 :    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    2503                 : 
    2504                 :    if (png_ptr->chunkdata == NULL)
    2505                 :    {
    2506                 :       png_warning(png_ptr, "No memory to process iTXt chunk");
    2507                 :       return;
    2508                 :    }
    2509                 : 
    2510                 :    slength = length;
    2511                 :    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
    2512                 : 
    2513                 :    if (png_crc_finish(png_ptr, 0))
    2514                 :    {
    2515                 :       png_free(png_ptr, png_ptr->chunkdata);
    2516                 :       png_ptr->chunkdata = NULL;
    2517                 :       return;
    2518                 :    }
    2519                 : 
    2520                 :    png_ptr->chunkdata[slength] = 0x00;
    2521                 : 
    2522                 :    for (lang = png_ptr->chunkdata; *lang; lang++)
    2523                 :       /* Empty loop */ ;
    2524                 : 
    2525                 :    lang++;        /* Skip NUL separator */
    2526                 : 
    2527                 :    /* iTXt must have a language tag (possibly empty), two compression bytes,
    2528                 :     * translated keyword (possibly empty), and possibly some text after the
    2529                 :     * keyword
    2530                 :     */
    2531                 : 
    2532                 :    if (lang >= png_ptr->chunkdata + slength - 3)
    2533                 :    {
    2534                 :       png_warning(png_ptr, "Truncated iTXt chunk");
    2535                 :       png_free(png_ptr, png_ptr->chunkdata);
    2536                 :       png_ptr->chunkdata = NULL;
    2537                 :       return;
    2538                 :    }
    2539                 : 
    2540                 :    else
    2541                 :    {
    2542                 :       comp_flag = *lang++;
    2543                 :       comp_type = *lang++;
    2544                 :    }
    2545                 : 
    2546                 :    if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt))
    2547                 :    {
    2548                 :       png_warning(png_ptr, "Unknown iTXt compression type or method");
    2549                 :       png_free(png_ptr, png_ptr->chunkdata);
    2550                 :       png_ptr->chunkdata = NULL;
    2551                 :       return;
    2552                 :    }
    2553                 : 
    2554                 :    for (lang_key = lang; *lang_key; lang_key++)
    2555                 :       /* Empty loop */ ;
    2556                 : 
    2557                 :    lang_key++;        /* Skip NUL separator */
    2558                 : 
    2559                 :    if (lang_key >= png_ptr->chunkdata + slength)
    2560                 :    {
    2561                 :       png_warning(png_ptr, "Truncated iTXt chunk");
    2562                 :       png_free(png_ptr, png_ptr->chunkdata);
    2563                 :       png_ptr->chunkdata = NULL;
    2564                 :       return;
    2565                 :    }
    2566                 : 
    2567                 :    for (text = lang_key; *text; text++)
    2568                 :       /* Empty loop */ ;
    2569                 : 
    2570                 :    text++;        /* Skip NUL separator */
    2571                 : 
    2572                 :    if (text >= png_ptr->chunkdata + slength)
    2573                 :    {
    2574                 :       png_warning(png_ptr, "Malformed iTXt chunk");
    2575                 :       png_free(png_ptr, png_ptr->chunkdata);
    2576                 :       png_ptr->chunkdata = NULL;
    2577                 :       return;
    2578                 :    }
    2579                 : 
    2580                 :    prefix_len = text - png_ptr->chunkdata;
    2581                 : 
    2582                 :    key=png_ptr->chunkdata;
    2583                 : 
    2584                 :    if (comp_flag)
    2585                 :       png_decompress_chunk(png_ptr, comp_type,
    2586                 :           (size_t)length, prefix_len, &data_len);
    2587                 : 
    2588                 :    else
    2589                 :       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
    2590                 : 
    2591                 :    text_ptr = (png_textp)png_malloc_warn(png_ptr,
    2592                 :        png_sizeof(png_text));
    2593                 : 
    2594                 :    if (text_ptr == NULL)
    2595                 :    {
    2596                 :       png_warning(png_ptr, "Not enough memory to process iTXt chunk");
    2597                 :       png_free(png_ptr, png_ptr->chunkdata);
    2598                 :       png_ptr->chunkdata = NULL;
    2599                 :       return;
    2600                 :    }
    2601                 : 
    2602                 :    text_ptr->compression = (int)comp_flag + 1;
    2603                 :    text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
    2604                 :    text_ptr->lang = png_ptr->chunkdata + (lang - key);
    2605                 :    text_ptr->itxt_length = data_len;
    2606                 :    text_ptr->text_length = 0;
    2607                 :    text_ptr->key = png_ptr->chunkdata;
    2608                 :    text_ptr->text = png_ptr->chunkdata + prefix_len;
    2609                 : 
    2610                 :    ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
    2611                 : 
    2612                 :    png_free(png_ptr, text_ptr);
    2613                 :    png_free(png_ptr, png_ptr->chunkdata);
    2614                 :    png_ptr->chunkdata = NULL;
    2615                 : 
    2616                 :    if (ret)
    2617                 :       png_error(png_ptr, "Insufficient memory to store iTXt chunk");
    2618                 : }
    2619                 : #endif
    2620                 : 
    2621                 : #ifdef PNG_READ_APNG_SUPPORTED
    2622                 : void /* PRIVATE */
    2623               0 : png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2624                 : {
    2625                 :     png_byte data[8];
    2626                 :     png_uint_32 num_frames;
    2627                 :     png_uint_32 num_plays;
    2628                 :     png_uint_32 didSet;
    2629                 : 
    2630                 :     png_debug(1, "in png_handle_acTL");
    2631                 : 
    2632               0 :     if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2633                 :     {
    2634               0 :         png_error(png_ptr, "Missing IHDR before acTL");
    2635                 :     }
    2636               0 :     else if (png_ptr->mode & PNG_HAVE_IDAT)
    2637                 :     {
    2638                 :         png_warning(png_ptr, "Invalid acTL after IDAT skipped");
    2639               0 :         png_crc_finish(png_ptr, length);
    2640               0 :         return;
    2641                 :     }
    2642               0 :     else if (png_ptr->mode & PNG_HAVE_acTL)
    2643                 :     {
    2644                 :         png_warning(png_ptr, "Duplicate acTL skipped");
    2645               0 :         png_crc_finish(png_ptr, length);
    2646               0 :         return;
    2647                 :     }
    2648               0 :     else if (length != 8)
    2649                 :     {
    2650                 :         png_warning(png_ptr, "acTL with invalid length skipped");
    2651               0 :         png_crc_finish(png_ptr, length);
    2652               0 :         return;
    2653                 :     }
    2654                 : 
    2655               0 :     png_crc_read(png_ptr, data, 8);
    2656               0 :     png_crc_finish(png_ptr, 0);
    2657                 : 
    2658               0 :     num_frames = png_get_uint_31(png_ptr, data);
    2659               0 :     num_plays = png_get_uint_31(png_ptr, data + 4);
    2660                 : 
    2661                 :     /* the set function will do error checking on num_frames */
    2662               0 :     didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
    2663               0 :     if(didSet)
    2664               0 :         png_ptr->mode |= PNG_HAVE_acTL;
    2665                 : }
    2666                 : 
    2667                 : void /* PRIVATE */
    2668               0 : png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2669                 : {
    2670                 :     png_byte data[22];
    2671                 :     png_uint_32 width;
    2672                 :     png_uint_32 height;
    2673                 :     png_uint_32 x_offset;
    2674                 :     png_uint_32 y_offset;
    2675                 :     png_uint_16 delay_num;
    2676                 :     png_uint_16 delay_den;
    2677                 :     png_byte dispose_op;
    2678                 :     png_byte blend_op;
    2679                 : 
    2680                 :     png_debug(1, "in png_handle_fcTL");
    2681                 : 
    2682               0 :     png_ensure_sequence_number(png_ptr, length);
    2683                 : 
    2684               0 :     if (!(png_ptr->mode & PNG_HAVE_IHDR))
    2685                 :     {
    2686               0 :         png_error(png_ptr, "Missing IHDR before fcTL");
    2687                 :     }
    2688               0 :     else if (png_ptr->mode & PNG_HAVE_IDAT)
    2689                 :     {
    2690                 :         /* for any frames other then the first this message may be misleading,
    2691                 :         * but correct. PNG_HAVE_IDAT is unset before the frame head is read
    2692                 :         * i can't think of a better message */
    2693                 :         png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
    2694               0 :         png_crc_finish(png_ptr, length-4);
    2695               0 :         return;
    2696                 :     }
    2697               0 :     else if (png_ptr->mode & PNG_HAVE_fcTL)
    2698                 :     {
    2699                 :         png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
    2700               0 :         png_crc_finish(png_ptr, length-4);
    2701               0 :         return;
    2702                 :     }
    2703               0 :     else if (length != 26)
    2704                 :     {
    2705                 :         png_warning(png_ptr, "fcTL with invalid length skipped");
    2706               0 :         png_crc_finish(png_ptr, length-4);
    2707               0 :         return;
    2708                 :     }
    2709                 : 
    2710               0 :     png_crc_read(png_ptr, data, 22);
    2711               0 :     png_crc_finish(png_ptr, 0);
    2712                 : 
    2713               0 :     width = png_get_uint_31(png_ptr, data);
    2714               0 :     height = png_get_uint_31(png_ptr, data + 4);
    2715               0 :     x_offset = png_get_uint_31(png_ptr, data + 8);
    2716               0 :     y_offset = png_get_uint_31(png_ptr, data + 12);
    2717               0 :     delay_num = png_get_uint_16(data + 16);
    2718               0 :     delay_den = png_get_uint_16(data + 18);
    2719               0 :     dispose_op = data[20];
    2720               0 :     blend_op = data[21];
    2721                 : 
    2722               0 :     if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
    2723                 :     {
    2724                 :         png_warning(png_ptr, "fcTL for the first frame must have zero offset");
    2725               0 :         return;
    2726                 :     }
    2727                 : 
    2728               0 :     if (info_ptr != NULL)
    2729                 :     {
    2730               0 :         if (png_ptr->num_frames_read == 0 &&
    2731               0 :             (width != info_ptr->width || height != info_ptr->height))
    2732                 :         {
    2733                 :             png_warning(png_ptr, "size in first frame's fcTL must match "
    2734                 :                                "the size in IHDR");
    2735               0 :             return;
    2736                 :         }
    2737                 : 
    2738                 :         /* The set function will do more error checking */
    2739               0 :         png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
    2740                 :                                 x_offset, y_offset, delay_num, delay_den,
    2741                 :                                 dispose_op, blend_op);
    2742                 : 
    2743               0 :         png_read_reinit(png_ptr, info_ptr);
    2744                 : 
    2745               0 :         png_ptr->mode |= PNG_HAVE_fcTL;
    2746                 :     }
    2747                 : }
    2748                 : 
    2749                 : void /* PRIVATE */
    2750               4 : png_have_info(png_structp png_ptr, png_infop info_ptr)
    2751                 : {
    2752               4 :     if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
    2753                 :     {
    2754               0 :         png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
    2755               0 :         info_ptr->num_frames++;
    2756                 :     }
    2757               4 : }
    2758                 : 
    2759                 : void /* PRIVATE */
    2760               0 : png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2761                 : {
    2762               0 :     png_ensure_sequence_number(png_ptr, length);
    2763                 : 
    2764                 :     /* This function is only called from png_read_end(), png_read_info(),
    2765                 :     * and png_push_read_chunk() which means that:
    2766                 :     * - the user doesn't want to read this frame
    2767                 :     * - or this is an out-of-place fdAT
    2768                 :     * in either case it is safe to ignore the chunk with a warning */
    2769                 :     png_warning(png_ptr, "ignoring fdAT chunk");
    2770               0 :     png_crc_finish(png_ptr, length - 4);
    2771                 :     PNG_UNUSED(info_ptr)
    2772               0 : }
    2773                 : 
    2774                 : void /* PRIVATE */
    2775               0 : png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
    2776                 : {
    2777                 :     png_byte data[4];
    2778                 :     png_uint_32 sequence_number;
    2779                 : 
    2780               0 :     if (length < 4)
    2781               0 :         png_error(png_ptr, "invalid fcTL or fdAT chunk found");
    2782                 : 
    2783               0 :     png_crc_read(png_ptr, data, 4);
    2784               0 :     sequence_number = png_get_uint_31(png_ptr, data);
    2785                 : 
    2786               0 :     if (sequence_number != png_ptr->next_seq_num)
    2787               0 :         png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
    2788                 :                            "number found");
    2789                 : 
    2790               0 :     png_ptr->next_seq_num++;
    2791               0 : }
    2792                 : #endif /* PNG_READ_APNG_SUPPORTED */
    2793                 : 
    2794                 : /* This function is called when we haven't found a handler for a
    2795                 :  * chunk.  If there isn't a problem with the chunk itself (ie bad
    2796                 :  * chunk name, CRC, or a critical chunk), the chunk is silently ignored
    2797                 :  * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
    2798                 :  * case it will be saved away to be written out later.
    2799                 :  */
    2800                 : void /* PRIVATE */
    2801               0 : png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
    2802                 : {
    2803               0 :    png_uint_32 skip = 0;
    2804                 : 
    2805                 :    png_debug(1, "in png_handle_unknown");
    2806                 : 
    2807                 : #ifdef PNG_USER_LIMITS_SUPPORTED
    2808                 :    if (png_ptr->user_chunk_cache_max != 0)
    2809                 :    {
    2810                 :       if (png_ptr->user_chunk_cache_max == 1)
    2811                 :       {
    2812                 :          png_crc_finish(png_ptr, length);
    2813                 :          return;
    2814                 :       }
    2815                 : 
    2816                 :       if (--png_ptr->user_chunk_cache_max == 1)
    2817                 :       {
    2818                 :          png_warning(png_ptr, "No space in chunk cache for unknown chunk");
    2819                 :          png_crc_finish(png_ptr, length);
    2820                 :          return;
    2821                 :       }
    2822                 :    }
    2823                 : #endif
    2824                 : 
    2825               0 :    if (png_ptr->mode & PNG_HAVE_IDAT)
    2826                 :    {
    2827               0 :       if (png_ptr->chunk_name != png_IDAT)
    2828               0 :          png_ptr->mode |= PNG_AFTER_IDAT;
    2829                 :    }
    2830                 : 
    2831               0 :    if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
    2832                 :    {
    2833                 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    2834                 :       if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
    2835                 :           PNG_HANDLE_CHUNK_ALWAYS
    2836                 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    2837                 :           && png_ptr->read_user_chunk_fn == NULL
    2838                 : #endif
    2839                 :           )
    2840                 : #endif
    2841               0 :          png_chunk_error(png_ptr, "unknown critical chunk");
    2842                 :    }
    2843                 : 
    2844                 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    2845                 :    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
    2846                 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    2847                 :        || (png_ptr->read_user_chunk_fn != NULL)
    2848                 : #endif
    2849                 :        )
    2850                 :    {
    2851                 : #ifdef PNG_MAX_MALLOC_64K
    2852                 :       if (length > 65535)
    2853                 :       {
    2854                 :          png_warning(png_ptr, "unknown chunk too large to fit in memory");
    2855                 :          skip = length - 65535;
    2856                 :          length = 65535;
    2857                 :       }
    2858                 : #endif
    2859                 : 
    2860                 :       /* TODO: this code is very close to the unknown handling in pngpread.c,
    2861                 :        * maybe it can be put into a common utility routine?
    2862                 :        * png_struct::unknown_chunk is just used as a temporary variable, along
    2863                 :        * with the data into which the chunk is read.  These can be eliminated.
    2864                 :        */
    2865                 :       PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
    2866                 :       png_ptr->unknown_chunk.size = (png_size_t)length;
    2867                 : 
    2868                 :       if (length == 0)
    2869                 :          png_ptr->unknown_chunk.data = NULL;
    2870                 : 
    2871                 :       else
    2872                 :       {
    2873                 :          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
    2874                 :          png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
    2875                 :       }
    2876                 : 
    2877                 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
    2878                 :       if (png_ptr->read_user_chunk_fn != NULL)
    2879                 :       {
    2880                 :          /* Callback to user unknown chunk handler */
    2881                 :          int ret;
    2882                 : 
    2883                 :          ret = (*(png_ptr->read_user_chunk_fn))
    2884                 :              (png_ptr, &png_ptr->unknown_chunk);
    2885                 : 
    2886                 :          if (ret < 0)
    2887                 :             png_chunk_error(png_ptr, "error in user chunk");
    2888                 : 
    2889                 :          if (ret == 0)
    2890                 :          {
    2891                 :             if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
    2892                 :             {
    2893                 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
    2894                 :                if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
    2895                 :                    PNG_HANDLE_CHUNK_ALWAYS)
    2896                 : #endif
    2897                 :                   png_chunk_error(png_ptr, "unknown critical chunk");
    2898                 :             }
    2899                 : 
    2900                 :             png_set_unknown_chunks(png_ptr, info_ptr,
    2901                 :                 &png_ptr->unknown_chunk, 1);
    2902                 :          }
    2903                 :       }
    2904                 : 
    2905                 :       else
    2906                 : #endif
    2907                 :          png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
    2908                 : 
    2909                 :       png_free(png_ptr, png_ptr->unknown_chunk.data);
    2910                 :       png_ptr->unknown_chunk.data = NULL;
    2911                 :    }
    2912                 : 
    2913                 :    else
    2914                 : #endif
    2915               0 :       skip = length;
    2916                 : 
    2917               0 :    png_crc_finish(png_ptr, skip);
    2918                 : 
    2919                 : #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
    2920                 :    PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
    2921                 : #endif
    2922               0 : }
    2923                 : 
    2924                 : /* This function is called to verify that a chunk name is valid.
    2925                 :  * This function can't have the "critical chunk check" incorporated
    2926                 :  * into it, since in the future we will need to be able to call user
    2927                 :  * functions to handle unknown critical chunks after we check that
    2928                 :  * the chunk name itself is valid.
    2929                 :  */
    2930                 : 
    2931                 : /* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
    2932                 :  *
    2933                 :  * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
    2934                 :  */
    2935                 : 
    2936                 : void /* PRIVATE */
    2937              10 : png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name)
    2938                 : {
    2939                 :    int i;
    2940                 : 
    2941                 :    png_debug(1, "in png_check_chunk_name");
    2942                 : 
    2943              50 :    for (i=1; i<=4; ++i)
    2944                 :    {
    2945              40 :       int c = chunk_name & 0xff;
    2946                 : 
    2947              40 :       if (c < 65 || c > 122 || (c > 90 && c < 97))
    2948               0 :          png_chunk_error(png_ptr, "invalid chunk type");
    2949                 : 
    2950              40 :       chunk_name >>= 8;
    2951                 :    }
    2952              10 : }
    2953                 : 
    2954                 : /* Combines the row recently read in with the existing pixels in the row.  This
    2955                 :  * routine takes care of alpha and transparency if requested.  This routine also
    2956                 :  * handles the two methods of progressive display of interlaced images,
    2957                 :  * depending on the 'display' value; if 'display' is true then the whole row
    2958                 :  * (dp) is filled from the start by replicating the available pixels.  If
    2959                 :  * 'display' is false only those pixels present in the pass are filled in.
    2960                 :  */
    2961                 : void /* PRIVATE */
    2962               0 : png_combine_row(png_structp png_ptr, png_bytep dp, int display)
    2963                 : {
    2964               0 :    unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
    2965               0 :    png_const_bytep sp = png_ptr->row_buf + 1;
    2966               0 :    png_uint_32 row_width = png_ptr->width;
    2967               0 :    unsigned int pass = png_ptr->pass;
    2968               0 :    png_bytep end_ptr = 0;
    2969               0 :    png_byte end_byte = 0;
    2970                 :    unsigned int end_mask;
    2971                 : 
    2972                 :    png_debug(1, "in png_combine_row");
    2973                 : 
    2974                 :    /* Added in 1.5.6: it should not be possible to enter this routine until at
    2975                 :     * least one row has been read from the PNG data and transformed.
    2976                 :     */
    2977               0 :    if (pixel_depth == 0)
    2978               0 :       png_error(png_ptr, "internal row logic error");
    2979                 : 
    2980                 :    /* Added in 1.5.4: the pixel depth should match the information returned by
    2981                 :     * any call to png_read_update_info at this point.  Do not continue if we got
    2982                 :     * this wrong.
    2983                 :     */
    2984               0 :    if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
    2985               0 :           PNG_ROWBYTES(pixel_depth, row_width))
    2986               0 :       png_error(png_ptr, "internal row size calculation error");
    2987                 : 
    2988                 :    /* Don't expect this to ever happen: */
    2989               0 :    if (row_width == 0)
    2990               0 :       png_error(png_ptr, "internal row width error");
    2991                 : 
    2992                 :    /* Preserve the last byte in cases where only part of it will be overwritten,
    2993                 :     * the multiply below may overflow, we don't care because ANSI-C guarantees
    2994                 :     * we get the low bits.
    2995                 :     */
    2996               0 :    end_mask = (pixel_depth * row_width) & 7;
    2997               0 :    if (end_mask != 0)
    2998                 :    {
    2999                 :       /* end_ptr == NULL is a flag to say do nothing */
    3000               0 :       end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
    3001               0 :       end_byte = *end_ptr;
    3002                 : #     ifdef PNG_READ_PACKSWAP_SUPPORTED
    3003                 :          if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
    3004                 :             end_mask = 0xff << end_mask;
    3005                 : 
    3006                 :          else /* big-endian byte */
    3007                 : #     endif
    3008               0 :          end_mask = 0xff >> end_mask;
    3009                 :       /* end_mask is now the bits to *keep* from the destination row */
    3010                 :    }
    3011                 : 
    3012                 :    /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
    3013                 :     * will also happen if interlacing isn't supported or if the application
    3014                 :     * does not call png_set_interlace_handling().  In the latter cases the
    3015                 :     * caller just gets a sequence of the unexpanded rows from each interlace
    3016                 :     * pass.
    3017                 :     */
    3018                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    3019               0 :    if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
    3020               0 :       pass < 6 && (display == 0 ||
    3021                 :       /* The following copies everything for 'display' on passes 0, 2 and 4. */
    3022               0 :       (display == 1 && (pass & 1) != 0)))
    3023                 :    {
    3024                 :       /* Narrow images may have no bits in a pass; the caller should handle
    3025                 :        * this, but this test is cheap:
    3026                 :        */
    3027               0 :       if (row_width <= PNG_PASS_START_COL(pass))
    3028               0 :          return;
    3029                 : 
    3030               0 :       if (pixel_depth < 8)
    3031                 :       {
    3032                 :          /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
    3033                 :           * into 32 bits, then a single loop over the bytes using the four byte
    3034                 :           * values in the 32-bit mask can be used.  For the 'display' option the
    3035                 :           * expanded mask may also not require any masking within a byte.  To
    3036                 :           * make this work the PACKSWAP option must be taken into account - it
    3037                 :           * simply requires the pixels to be reversed in each byte.
    3038                 :           *
    3039                 :           * The 'regular' case requires a mask for each of the first 6 passes,
    3040                 :           * the 'display' case does a copy for the even passes in the range
    3041                 :           * 0..6.  This has already been handled in the test above.
    3042                 :           *
    3043                 :           * The masks are arranged as four bytes with the first byte to use in
    3044                 :           * the lowest bits (little-endian) regardless of the order (PACKSWAP or
    3045                 :           * not) of the pixels in each byte.
    3046                 :           *
    3047                 :           * NOTE: the whole of this logic depends on the caller of this function
    3048                 :           * only calling it on rows appropriate to the pass.  This function only
    3049                 :           * understands the 'x' logic; the 'y' logic is handled by the caller.
    3050                 :           *
    3051                 :           * The following defines allow generation of compile time constant bit
    3052                 :           * masks for each pixel depth and each possibility of swapped or not
    3053                 :           * swapped bytes.  Pass 'p' is in the range 0..6; 'x', a pixel index,
    3054                 :           * is in the range 0..7; and the result is 1 if the pixel is to be
    3055                 :           * copied in the pass, 0 if not.  'S' is for the sparkle method, 'B'
    3056                 :           * for the block method.
    3057                 :           *
    3058                 :           * With some compilers a compile time expression of the general form:
    3059                 :           *
    3060                 :           *    (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
    3061                 :           *
    3062                 :           * Produces warnings with values of 'shift' in the range 33 to 63
    3063                 :           * because the right hand side of the ?: expression is evaluated by
    3064                 :           * the compiler even though it isn't used.  Microsoft Visual C (various
    3065                 :           * versions) and the Intel C compiler are known to do this.  To avoid
    3066                 :           * this the following macros are used in 1.5.6.  This is a temporary
    3067                 :           * solution to avoid destabilizing the code during the release process.
    3068                 :           */
    3069                 : #        if PNG_USE_COMPILE_TIME_MASKS
    3070                 : #           define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
    3071                 : #           define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
    3072                 : #        else
    3073                 : #           define PNG_LSR(x,s) ((x)>>(s))
    3074                 : #           define PNG_LSL(x,s) ((x)<<(s))
    3075                 : #        endif
    3076                 : #        define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
    3077                 :            PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
    3078                 : #        define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
    3079                 :            PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
    3080                 : 
    3081                 :          /* Return a mask for pass 'p' pixel 'x' at depth 'd'.  The mask is
    3082                 :           * little endian - the first pixel is at bit 0 - however the extra
    3083                 :           * parameter 's' can be set to cause the mask position to be swapped
    3084                 :           * within each byte, to match the PNG format.  This is done by XOR of
    3085                 :           * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
    3086                 :           */
    3087                 : #        define PIXEL_MASK(p,x,d,s) \
    3088                 :             (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
    3089                 : 
    3090                 :          /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
    3091                 :           */
    3092                 : #        define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
    3093                 : #        define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
    3094                 : 
    3095                 :          /* Combine 8 of these to get the full mask.  For the 1-bpp and 2-bpp
    3096                 :           * cases the result needs replicating, for the 4-bpp case the above
    3097                 :           * generates a full 32 bits.
    3098                 :           */
    3099                 : #        define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
    3100                 : 
    3101                 : #        define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
    3102                 :             S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
    3103                 :             S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
    3104                 : 
    3105                 : #        define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
    3106                 :             B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
    3107                 :             B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
    3108                 : 
    3109                 : #if PNG_USE_COMPILE_TIME_MASKS
    3110                 :          /* Utility macros to construct all the masks for a depth/swap
    3111                 :           * combination.  The 's' parameter says whether the format is PNG
    3112                 :           * (big endian bytes) or not.  Only the three odd-numbered passes are
    3113                 :           * required for the display/block algorithm.
    3114                 :           */
    3115                 : #        define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
    3116                 :             S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
    3117                 : 
    3118                 : #        define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
    3119                 : 
    3120                 : #        define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
    3121                 : 
    3122                 :          /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
    3123                 :           * then pass:
    3124                 :           */
    3125                 :          static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
    3126                 :          {
    3127                 :             /* Little-endian byte masks for PACKSWAP */
    3128                 :             { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
    3129                 :             /* Normal (big-endian byte) masks - PNG format */
    3130                 :             { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
    3131                 :          };
    3132                 : 
    3133                 :          /* display_mask has only three entries for the odd passes, so index by
    3134                 :           * pass>>1.
    3135                 :           */
    3136                 :          static PNG_CONST png_uint_32 display_mask[2][3][3] =
    3137                 :          {
    3138                 :             /* Little-endian byte masks for PACKSWAP */
    3139                 :             { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
    3140                 :             /* Normal (big-endian byte) masks - PNG format */
    3141                 :             { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
    3142                 :          };
    3143                 : 
    3144                 : #        define MASK(pass,depth,display,png)\
    3145                 :             ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
    3146                 :                row_mask[png][DEPTH_INDEX(depth)][pass])
    3147                 : 
    3148                 : #else /* !PNG_USE_COMPILE_TIME_MASKS */
    3149                 :          /* This is the runtime alternative: it seems unlikely that this will
    3150                 :           * ever be either smaller or faster than the compile time approach.
    3151                 :           */
    3152                 : #        define MASK(pass,depth,display,png)\
    3153                 :             ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
    3154                 : #endif /* !PNG_USE_COMPILE_TIME_MASKS */
    3155                 : 
    3156                 :          /* Use the appropriate mask to copy the required bits.  In some cases
    3157                 :           * the byte mask will be 0 or 0xff, optimize these cases.  row_width is
    3158                 :           * the number of pixels, but the code copies bytes, so it is necessary
    3159                 :           * to special case the end.
    3160                 :           */
    3161               0 :          png_uint_32 pixels_per_byte = 8 / pixel_depth;
    3162                 :          png_uint_32 mask;
    3163                 : 
    3164                 : #        ifdef PNG_READ_PACKSWAP_SUPPORTED
    3165                 :             if (png_ptr->transformations & PNG_PACKSWAP)
    3166                 :                mask = MASK(pass, pixel_depth, display, 0);
    3167                 : 
    3168                 :             else
    3169                 : #        endif
    3170               0 :             mask = MASK(pass, pixel_depth, display, 1);
    3171                 : 
    3172                 :          for (;;)
    3173                 :          {
    3174                 :             png_uint_32 m;
    3175                 : 
    3176                 :             /* It doesn't matter in the following if png_uint_32 has more than
    3177                 :              * 32 bits because the high bits always match those in m<<24; it is,
    3178                 :              * however, essential to use OR here, not +, because of this.
    3179                 :              */
    3180               0 :             m = mask;
    3181               0 :             mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
    3182               0 :             m &= 0xff;
    3183                 : 
    3184               0 :             if (m != 0) /* something to copy */
    3185                 :             {
    3186               0 :                if (m != 0xff)
    3187               0 :                   *dp = (png_byte)((*dp & ~m) | (*sp & m));
    3188                 :                else
    3189               0 :                   *dp = *sp;
    3190                 :             }
    3191                 : 
    3192                 :             /* NOTE: this may overwrite the last byte with garbage if the image
    3193                 :              * is not an exact number of bytes wide; libpng has always done
    3194                 :              * this.
    3195                 :              */
    3196               0 :             if (row_width <= pixels_per_byte)
    3197                 :                break; /* May need to restore part of the last byte */
    3198                 : 
    3199               0 :             row_width -= pixels_per_byte;
    3200               0 :             ++dp;
    3201               0 :             ++sp;
    3202               0 :          }
    3203                 :       }
    3204                 : 
    3205                 :       else /* pixel_depth >= 8 */
    3206                 :       {
    3207                 :          unsigned int bytes_to_copy, bytes_to_jump;
    3208                 : 
    3209                 :          /* Validate the depth - it must be a multiple of 8 */
    3210               0 :          if (pixel_depth & 7)
    3211               0 :             png_error(png_ptr, "invalid user transform pixel depth");
    3212                 : 
    3213               0 :          pixel_depth >>= 3; /* now in bytes */
    3214               0 :          row_width *= pixel_depth;
    3215                 : 
    3216                 :          /* Regardless of pass number the Adam 7 interlace always results in a
    3217                 :           * fixed number of pixels to copy then to skip.  There may be a
    3218                 :           * different number of pixels to skip at the start though.
    3219                 :           */
    3220                 :          {
    3221               0 :             unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
    3222                 : 
    3223               0 :             row_width -= offset;
    3224               0 :             dp += offset;
    3225               0 :             sp += offset;
    3226                 :          }
    3227                 : 
    3228                 :          /* Work out the bytes to copy. */
    3229               0 :          if (display)
    3230                 :          {
    3231                 :             /* When doing the 'block' algorithm the pixel in the pass gets
    3232                 :              * replicated to adjacent pixels.  This is why the even (0,2,4,6)
    3233                 :              * passes are skipped above - the entire expanded row is copied.
    3234                 :              */
    3235               0 :             bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
    3236                 : 
    3237                 :             /* But don't allow this number to exceed the actual row width. */
    3238               0 :             if (bytes_to_copy > row_width)
    3239               0 :                bytes_to_copy = row_width;
    3240                 :          }
    3241                 : 
    3242                 :          else /* normal row; Adam7 only ever gives us one pixel to copy. */
    3243               0 :             bytes_to_copy = pixel_depth;
    3244                 : 
    3245                 :          /* In Adam7 there is a constant offset between where the pixels go. */
    3246               0 :          bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
    3247                 : 
    3248                 :          /* And simply copy these bytes.  Some optimization is possible here,
    3249                 :           * depending on the value of 'bytes_to_copy'.  Special case the low
    3250                 :           * byte counts, which we know to be frequent.
    3251                 :           *
    3252                 :           * Notice that these cases all 'return' rather than 'break' - this
    3253                 :           * avoids an unnecessary test on whether to restore the last byte
    3254                 :           * below.
    3255                 :           */
    3256               0 :          switch (bytes_to_copy)
    3257                 :          {
    3258                 :             case 1:
    3259                 :                for (;;)
    3260                 :                {
    3261               0 :                   *dp = *sp;
    3262                 : 
    3263               0 :                   if (row_width <= bytes_to_jump)
    3264               0 :                      return;
    3265                 : 
    3266               0 :                   dp += bytes_to_jump;
    3267               0 :                   sp += bytes_to_jump;
    3268               0 :                   row_width -= bytes_to_jump;
    3269               0 :                }
    3270                 : 
    3271                 :             case 2:
    3272                 :                /* There is a possibility of a partial copy at the end here; this
    3273                 :                 * slows the code down somewhat.
    3274                 :                 */
    3275                 :                do
    3276                 :                {
    3277               0 :                   dp[0] = sp[0], dp[1] = sp[1];
    3278                 : 
    3279               0 :                   if (row_width <= bytes_to_jump)
    3280               0 :                      return;
    3281                 : 
    3282               0 :                   sp += bytes_to_jump;
    3283               0 :                   dp += bytes_to_jump;
    3284               0 :                   row_width -= bytes_to_jump;
    3285                 :                }
    3286               0 :                while (row_width > 1);
    3287                 : 
    3288                 :                /* And there can only be one byte left at this point: */
    3289               0 :                *dp = *sp;
    3290               0 :                return;
    3291                 : 
    3292                 :             case 3:
    3293                 :                /* This can only be the RGB case, so each copy is exactly one
    3294                 :                 * pixel and it is not necessary to check for a partial copy.
    3295                 :                 */
    3296                 :                for(;;)
    3297                 :                {
    3298               0 :                   dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
    3299                 : 
    3300               0 :                   if (row_width <= bytes_to_jump)
    3301               0 :                      return;
    3302                 : 
    3303               0 :                   sp += bytes_to_jump;
    3304               0 :                   dp += bytes_to_jump;
    3305               0 :                   row_width -= bytes_to_jump;
    3306               0 :                }
    3307                 : 
    3308                 :             default:
    3309                 : #if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
    3310                 :                /* Check for double byte alignment and, if possible, use a
    3311                 :                 * 16-bit copy.  Don't attempt this for narrow images - ones that
    3312                 :                 * are less than an interlace panel wide.  Don't attempt it for
    3313                 :                 * wide bytes_to_copy either - use the png_memcpy there.
    3314                 :                 */
    3315               0 :                if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
    3316               0 :                   png_isaligned(dp, png_uint_16) &&
    3317               0 :                   png_isaligned(sp, png_uint_16) &&
    3318               0 :                   bytes_to_copy % sizeof (png_uint_16) == 0 &&
    3319               0 :                   bytes_to_jump % sizeof (png_uint_16) == 0)
    3320                 :                {
    3321                 :                   /* Everything is aligned for png_uint_16 copies, but try for
    3322                 :                    * png_uint_32 first.
    3323                 :                    */
    3324               0 :                   if (png_isaligned(dp, png_uint_32) &&
    3325               0 :                      png_isaligned(sp, png_uint_32) &&
    3326               0 :                      bytes_to_copy % sizeof (png_uint_32) == 0 &&
    3327               0 :                      bytes_to_jump % sizeof (png_uint_32) == 0)
    3328                 :                   {
    3329               0 :                      png_uint_32p dp32 = (png_uint_32p)dp;
    3330               0 :                      png_const_uint_32p sp32 = (png_const_uint_32p)sp;
    3331               0 :                      unsigned int skip = (bytes_to_jump-bytes_to_copy) /
    3332                 :                         sizeof (png_uint_32);
    3333                 : 
    3334                 :                      do
    3335                 :                      {
    3336               0 :                         size_t c = bytes_to_copy;
    3337                 :                         do
    3338                 :                         {
    3339               0 :                            *dp32++ = *sp32++;
    3340               0 :                            c -= sizeof (png_uint_32);
    3341                 :                         }
    3342               0 :                         while (c > 0);
    3343                 : 
    3344               0 :                         if (row_width <= bytes_to_jump)
    3345               0 :                            return;
    3346                 : 
    3347               0 :                         dp32 += skip;
    3348               0 :                         sp32 += skip;
    3349               0 :                         row_width -= bytes_to_jump;
    3350                 :                      }
    3351               0 :                      while (bytes_to_copy <= row_width);
    3352                 : 
    3353                 :                      /* Get to here when the row_width truncates the final copy.
    3354                 :                       * There will be 1-3 bytes left to copy, so don't try the
    3355                 :                       * 16-bit loop below.
    3356                 :                       */
    3357               0 :                      dp = (png_bytep)dp32;
    3358               0 :                      sp = (png_const_bytep)sp32;
    3359                 :                      do
    3360               0 :                         *dp++ = *sp++;
    3361               0 :                      while (--row_width > 0);
    3362               0 :                      return;
    3363                 :                   }
    3364                 : 
    3365                 :                   /* Else do it in 16-bit quantities, but only if the size is
    3366                 :                    * not too large.
    3367                 :                    */
    3368                 :                   else
    3369                 :                   {
    3370               0 :                      png_uint_16p dp16 = (png_uint_16p)dp;
    3371               0 :                      png_const_uint_16p sp16 = (png_const_uint_16p)sp;
    3372               0 :                      unsigned int skip = (bytes_to_jump-bytes_to_copy) /
    3373                 :                         sizeof (png_uint_16);
    3374                 : 
    3375                 :                      do
    3376                 :                      {
    3377               0 :                         size_t c = bytes_to_copy;
    3378                 :                         do
    3379                 :                         {
    3380               0 :                            *dp16++ = *sp16++;
    3381               0 :                            c -= sizeof (png_uint_16);
    3382                 :                         }
    3383               0 :                         while (c > 0);
    3384                 : 
    3385               0 :                         if (row_width <= bytes_to_jump)
    3386               0 :                            return;
    3387                 : 
    3388               0 :                         dp16 += skip;
    3389               0 :                         sp16 += skip;
    3390               0 :                         row_width -= bytes_to_jump;
    3391                 :                      }
    3392               0 :                      while (bytes_to_copy <= row_width);
    3393                 : 
    3394                 :                      /* End of row - 1 byte left, bytes_to_copy > row_width: */
    3395               0 :                      dp = (png_bytep)dp16;
    3396               0 :                      sp = (png_const_bytep)sp16;
    3397                 :                      do
    3398               0 :                         *dp++ = *sp++;
    3399               0 :                      while (--row_width > 0);
    3400               0 :                      return;
    3401                 :                   }
    3402                 :                }
    3403                 : #endif /* PNG_ALIGN_ code */
    3404                 : 
    3405                 :                /* The true default - use a png_memcpy: */
    3406                 :                for (;;)
    3407                 :                {
    3408               0 :                   png_memcpy(dp, sp, bytes_to_copy);
    3409                 : 
    3410               0 :                   if (row_width <= bytes_to_jump)
    3411               0 :                      return;
    3412                 : 
    3413               0 :                   sp += bytes_to_jump;
    3414               0 :                   dp += bytes_to_jump;
    3415               0 :                   row_width -= bytes_to_jump;
    3416               0 :                   if (bytes_to_copy > row_width)
    3417               0 :                      bytes_to_copy = row_width;
    3418               0 :                }
    3419                 :          }
    3420                 : 
    3421                 :          /* NOT REACHED*/
    3422                 :       } /* pixel_depth >= 8 */
    3423                 : 
    3424                 :       /* Here if pixel_depth < 8 to check 'end_ptr' below. */
    3425                 :    }
    3426                 :    else
    3427                 : #endif
    3428                 : 
    3429                 :    /* If here then the switch above wasn't used so just png_memcpy the whole row
    3430                 :     * from the temporary row buffer (notice that this overwrites the end of the
    3431                 :     * destination row if it is a partial byte.)
    3432                 :     */
    3433               0 :    png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
    3434                 : 
    3435                 :    /* Restore the overwritten bits from the last byte if necessary. */
    3436               0 :    if (end_ptr != NULL)
    3437               0 :       *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
    3438                 : }
    3439                 : 
    3440                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    3441                 : void /* PRIVATE */
    3442               0 : png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
    3443                 :    png_uint_32 transformations /* Because these may affect the byte layout */)
    3444                 : {
    3445                 :    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    3446                 :    /* Offset to next interlace block */
    3447                 :    static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    3448                 : 
    3449                 :    png_debug(1, "in png_do_read_interlace");
    3450               0 :    if (row != NULL && row_info != NULL)
    3451                 :    {
    3452                 :       png_uint_32 final_width;
    3453                 : 
    3454               0 :       final_width = row_info->width * png_pass_inc[pass];
    3455                 : 
    3456               0 :       switch (row_info->pixel_depth)
    3457                 :       {
    3458                 :          case 1:
    3459                 :          {
    3460               0 :             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
    3461               0 :             png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
    3462                 :             int sshift, dshift;
    3463                 :             int s_start, s_end, s_inc;
    3464               0 :             int jstop = png_pass_inc[pass];
    3465                 :             png_byte v;
    3466                 :             png_uint_32 i;
    3467                 :             int j;
    3468                 : 
    3469                 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
    3470                 :             if (transformations & PNG_PACKSWAP)
    3471                 :             {
    3472                 :                 sshift = (int)((row_info->width + 7) & 0x07);
    3473                 :                 dshift = (int)((final_width + 7) & 0x07);
    3474                 :                 s_start = 7;
    3475                 :                 s_end = 0;
    3476                 :                 s_inc = -1;
    3477                 :             }
    3478                 : 
    3479                 :             else
    3480                 : #endif
    3481                 :             {
    3482               0 :                 sshift = 7 - (int)((row_info->width + 7) & 0x07);
    3483               0 :                 dshift = 7 - (int)((final_width + 7) & 0x07);
    3484               0 :                 s_start = 0;
    3485               0 :                 s_end = 7;
    3486               0 :                 s_inc = 1;
    3487                 :             }
    3488                 : 
    3489               0 :             for (i = 0; i < row_info->width; i++)
    3490                 :             {
    3491               0 :                v = (png_byte)((*sp >> sshift) & 0x01);
    3492               0 :                for (j = 0; j < jstop; j++)
    3493                 :                {
    3494               0 :                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
    3495               0 :                   *dp |= (png_byte)(v << dshift);
    3496                 : 
    3497               0 :                   if (dshift == s_end)
    3498                 :                   {
    3499               0 :                      dshift = s_start;
    3500               0 :                      dp--;
    3501                 :                   }
    3502                 : 
    3503                 :                   else
    3504               0 :                      dshift += s_inc;
    3505                 :                }
    3506                 : 
    3507               0 :                if (sshift == s_end)
    3508                 :                {
    3509               0 :                   sshift = s_start;
    3510               0 :                   sp--;
    3511                 :                }
    3512                 : 
    3513                 :                else
    3514               0 :                   sshift += s_inc;
    3515                 :             }
    3516               0 :             break;
    3517                 :          }
    3518                 : 
    3519                 :          case 2:
    3520                 :          {
    3521               0 :             png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
    3522               0 :             png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
    3523                 :             int sshift, dshift;
    3524                 :             int s_start, s_end, s_inc;
    3525               0 :             int jstop = png_pass_inc[pass];
    3526                 :             png_uint_32 i;
    3527                 : 
    3528                 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
    3529                 :             if (transformations & PNG_PACKSWAP)
    3530                 :             {
    3531                 :                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
    3532                 :                dshift = (int)(((final_width + 3) & 0x03) << 1);
    3533                 :                s_start = 6;
    3534                 :                s_end = 0;
    3535                 :                s_inc = -2;
    3536                 :             }
    3537                 : 
    3538                 :             else
    3539                 : #endif
    3540                 :             {
    3541               0 :                sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
    3542               0 :                dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
    3543               0 :                s_start = 0;
    3544               0 :                s_end = 6;
    3545               0 :                s_inc = 2;
    3546                 :             }
    3547                 : 
    3548               0 :             for (i = 0; i < row_info->width; i++)
    3549                 :             {
    3550                 :                png_byte v;
    3551                 :                int j;
    3552                 : 
    3553               0 :                v = (png_byte)((*sp >> sshift) & 0x03);
    3554               0 :                for (j = 0; j < jstop; j++)
    3555                 :                {
    3556               0 :                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
    3557               0 :                   *dp |= (png_byte)(v << dshift);
    3558                 : 
    3559               0 :                   if (dshift == s_end)
    3560                 :                   {
    3561               0 :                      dshift = s_start;
    3562               0 :                      dp--;
    3563                 :                   }
    3564                 : 
    3565                 :                   else
    3566               0 :                      dshift += s_inc;
    3567                 :                }
    3568                 : 
    3569               0 :                if (sshift == s_end)
    3570                 :                {
    3571               0 :                   sshift = s_start;
    3572               0 :                   sp--;
    3573                 :                }
    3574                 : 
    3575                 :                else
    3576               0 :                   sshift += s_inc;
    3577                 :             }
    3578               0 :             break;
    3579                 :          }
    3580                 : 
    3581                 :          case 4:
    3582                 :          {
    3583               0 :             png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
    3584               0 :             png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
    3585                 :             int sshift, dshift;
    3586                 :             int s_start, s_end, s_inc;
    3587                 :             png_uint_32 i;
    3588               0 :             int jstop = png_pass_inc[pass];
    3589                 : 
    3590                 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
    3591                 :             if (transformations & PNG_PACKSWAP)
    3592                 :             {
    3593                 :                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
    3594                 :                dshift = (int)(((final_width + 1) & 0x01) << 2);
    3595                 :                s_start = 4;
    3596                 :                s_end = 0;
    3597                 :                s_inc = -4;
    3598                 :             }
    3599                 : 
    3600                 :             else
    3601                 : #endif
    3602                 :             {
    3603               0 :                sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
    3604               0 :                dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
    3605               0 :                s_start = 0;
    3606               0 :                s_end = 4;
    3607               0 :                s_inc = 4;
    3608                 :             }
    3609                 : 
    3610               0 :             for (i = 0; i < row_info->width; i++)
    3611                 :             {
    3612               0 :                png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
    3613                 :                int j;
    3614                 : 
    3615               0 :                for (j = 0; j < jstop; j++)
    3616                 :                {
    3617               0 :                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
    3618               0 :                   *dp |= (png_byte)(v << dshift);
    3619                 : 
    3620               0 :                   if (dshift == s_end)
    3621                 :                   {
    3622               0 :                      dshift = s_start;
    3623               0 :                      dp--;
    3624                 :                   }
    3625                 : 
    3626                 :                   else
    3627               0 :                      dshift += s_inc;
    3628                 :                }
    3629                 : 
    3630               0 :                if (sshift == s_end)
    3631                 :                {
    3632               0 :                   sshift = s_start;
    3633               0 :                   sp--;
    3634                 :                }
    3635                 : 
    3636                 :                else
    3637               0 :                   sshift += s_inc;
    3638                 :             }
    3639               0 :             break;
    3640                 :          }
    3641                 : 
    3642                 :          default:
    3643                 :          {
    3644               0 :             png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
    3645                 : 
    3646               0 :             png_bytep sp = row + (png_size_t)(row_info->width - 1)
    3647                 :                 * pixel_bytes;
    3648                 : 
    3649               0 :             png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
    3650                 : 
    3651               0 :             int jstop = png_pass_inc[pass];
    3652                 :             png_uint_32 i;
    3653                 : 
    3654               0 :             for (i = 0; i < row_info->width; i++)
    3655                 :             {
    3656                 :                png_byte v[8];
    3657                 :                int j;
    3658                 : 
    3659               0 :                png_memcpy(v, sp, pixel_bytes);
    3660                 : 
    3661               0 :                for (j = 0; j < jstop; j++)
    3662                 :                {
    3663               0 :                   png_memcpy(dp, v, pixel_bytes);
    3664               0 :                   dp -= pixel_bytes;
    3665                 :                }
    3666                 : 
    3667               0 :                sp -= pixel_bytes;
    3668                 :             }
    3669               0 :             break;
    3670                 :          }
    3671                 :       }
    3672                 : 
    3673               0 :       row_info->width = final_width;
    3674               0 :       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
    3675                 :    }
    3676                 : #ifndef PNG_READ_PACKSWAP_SUPPORTED
    3677                 :    PNG_UNUSED(transformations)  /* Silence compiler warning */
    3678                 : #endif
    3679               0 : }
    3680                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    3681                 : 
    3682                 : static void
    3683              28 : png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
    3684                 :    png_const_bytep prev_row)
    3685                 : {
    3686                 :    png_size_t i;
    3687              28 :    png_size_t istop = row_info->rowbytes;
    3688              28 :    unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    3689              28 :    png_bytep rp = row + bpp;
    3690                 : 
    3691                 :    PNG_UNUSED(prev_row)
    3692                 : 
    3693            7084 :    for (i = bpp; i < istop; i++)
    3694                 :    {
    3695            7056 :       *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
    3696            7056 :       rp++;
    3697                 :    }
    3698              28 : }
    3699                 : 
    3700                 : static void
    3701              17 : png_read_filter_row_up(png_row_infop row_info, png_bytep row,
    3702                 :    png_const_bytep prev_row)
    3703                 : {
    3704                 :    png_size_t i;
    3705              17 :    png_size_t istop = row_info->rowbytes;
    3706              17 :    png_bytep rp = row;
    3707              17 :    png_const_bytep pp = prev_row;
    3708                 : 
    3709            4369 :    for (i = 0; i < istop; i++)
    3710                 :    {
    3711            4352 :       *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
    3712            4352 :       rp++;
    3713                 :    }
    3714              17 : }
    3715                 : 
    3716                 : static void
    3717              69 : png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
    3718                 :    png_const_bytep prev_row)
    3719                 : {
    3720                 :    png_size_t i;
    3721              69 :    png_bytep rp = row;
    3722              69 :    png_const_bytep pp = prev_row;
    3723              69 :    unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
    3724              69 :    png_size_t istop = row_info->rowbytes - bpp;
    3725                 : 
    3726             345 :    for (i = 0; i < bpp; i++)
    3727                 :    {
    3728             552 :       *rp = (png_byte)(((int)(*rp) +
    3729             552 :          ((int)(*pp++) / 2 )) & 0xff);
    3730                 : 
    3731             276 :       rp++;
    3732                 :    }
    3733                 : 
    3734           17457 :    for (i = 0; i < istop; i++)
    3735                 :    {
    3736           34776 :       *rp = (png_byte)(((int)(*rp) +
    3737           34776 :          (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
    3738                 : 
    3739           17388 :       rp++;
    3740                 :    }
    3741              69 : }
    3742                 : 
    3743                 : static void
    3744               0 : png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
    3745                 :    png_const_bytep prev_row)
    3746                 : {
    3747               0 :    png_bytep rp_end = row + row_info->rowbytes;
    3748                 :    int a, c;
    3749                 : 
    3750                 :    /* First pixel/byte */
    3751               0 :    c = *prev_row++;
    3752               0 :    a = *row + c;
    3753               0 :    *row++ = (png_byte)a;
    3754                 : 
    3755                 :    /* Remainder */
    3756               0 :    while (row < rp_end)
    3757                 :    {
    3758                 :       int b, pa, pb, pc, p;
    3759                 : 
    3760               0 :       a &= 0xff; /* From previous iteration or start */
    3761               0 :       b = *prev_row++;
    3762                 : 
    3763               0 :       p = b - c;
    3764               0 :       pc = a - c;
    3765                 : 
    3766                 : #     ifdef PNG_USE_ABS
    3767                 :          pa = abs(p);
    3768                 :          pb = abs(pc);
    3769                 :          pc = abs(p + pc);
    3770                 : #     else
    3771               0 :          pa = p < 0 ? -p : p;
    3772               0 :          pb = pc < 0 ? -pc : pc;
    3773               0 :          pc = (p + pc) < 0 ? -(p + pc) : p + pc;
    3774                 : #     endif
    3775                 : 
    3776                 :       /* Find the best predictor, the least of pa, pb, pc favoring the earlier
    3777                 :        * ones in the case of a tie.
    3778                 :        */
    3779               0 :       if (pb < pa) pa = pb, a = b;
    3780               0 :       if (pc < pa) a = c;
    3781                 : 
    3782                 :       /* Calculate the current pixel in a, and move the previous row pixel to c
    3783                 :        * for the next time round the loop
    3784                 :        */
    3785               0 :       c = b;
    3786               0 :       a += *row;
    3787               0 :       *row++ = (png_byte)a;
    3788                 :    }
    3789               0 : }
    3790                 : 
    3791                 : static void
    3792              78 : png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
    3793                 :    png_const_bytep prev_row)
    3794                 : {
    3795              78 :    int bpp = (row_info->pixel_depth + 7) >> 3;
    3796              78 :    png_bytep rp_end = row + bpp;
    3797                 : 
    3798                 :    /* Process the first pixel in the row completely (this is the same as 'up'
    3799                 :     * because there is only one candidate predictor for the first row).
    3800                 :     */
    3801             468 :    while (row < rp_end)
    3802                 :    {
    3803             312 :       int a = *row + *prev_row++;
    3804             312 :       *row++ = (png_byte)a;
    3805                 :    }
    3806                 : 
    3807                 :    /* Remainder */
    3808              78 :    rp_end += row_info->rowbytes - bpp;
    3809                 : 
    3810           19812 :    while (row < rp_end)
    3811                 :    {
    3812                 :       int a, b, c, pa, pb, pc, p;
    3813                 : 
    3814           19656 :       c = *(prev_row - bpp);
    3815           19656 :       a = *(row - bpp);
    3816           19656 :       b = *prev_row++;
    3817                 : 
    3818           19656 :       p = b - c;
    3819           19656 :       pc = a - c;
    3820                 : 
    3821                 : #     ifdef PNG_USE_ABS
    3822                 :          pa = abs(p);
    3823                 :          pb = abs(pc);
    3824                 :          pc = abs(p + pc);
    3825                 : #     else
    3826           19656 :          pa = p < 0 ? -p : p;
    3827           19656 :          pb = pc < 0 ? -pc : pc;
    3828           19656 :          pc = (p + pc) < 0 ? -(p + pc) : p + pc;
    3829                 : #     endif
    3830                 : 
    3831           19656 :       if (pb < pa) pa = pb, a = b;
    3832           19656 :       if (pc < pa) a = c;
    3833                 : 
    3834           19656 :       c = b;
    3835           19656 :       a += *row;
    3836           19656 :       *row++ = (png_byte)a;
    3837                 :    }
    3838              78 : }
    3839                 : 
    3840                 : #ifdef PNG_ARM_NEON
    3841                 : 
    3842                 : #ifdef __linux__
    3843                 : #include <stdio.h>
    3844                 : #include <elf.h>
    3845                 : #include <asm/hwcap.h>
    3846                 : 
    3847                 : static int png_have_hwcap(unsigned cap)
    3848                 : {
    3849                 :    FILE *f = fopen("/proc/self/auxv", "r");
    3850                 :    Elf32_auxv_t aux;
    3851                 :    int have_cap = 0;
    3852                 : 
    3853                 :    if (!f)
    3854                 :       return 0;
    3855                 : 
    3856                 :    while (fread(&aux, sizeof(aux), 1, f) > 0)
    3857                 :    {
    3858                 :       if (aux.a_type == AT_HWCAP &&
    3859                 :           aux.a_un.a_val & cap)
    3860                 :       {
    3861                 :          have_cap = 1;
    3862                 :          break;
    3863                 :       }
    3864                 :    }
    3865                 : 
    3866                 :    fclose(f);
    3867                 : 
    3868                 :    return have_cap;
    3869                 : }
    3870                 : #endif /* __linux__ */
    3871                 : 
    3872                 : static void
    3873                 : png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
    3874                 : {
    3875                 : #ifdef __linux__
    3876                 :    if (!png_have_hwcap(HWCAP_NEON))
    3877                 :       return;
    3878                 : #endif
    3879                 : 
    3880                 :    pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
    3881                 : 
    3882                 :    if (bpp == 3)
    3883                 :    {
    3884                 :       pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
    3885                 :       pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
    3886                 :       pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 
    3887                 :          png_read_filter_row_paeth3_neon;
    3888                 :    }
    3889                 : 
    3890                 :    else if (bpp == 4)
    3891                 :    {
    3892                 :       pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
    3893                 :       pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
    3894                 :       pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
    3895                 :           png_read_filter_row_paeth4_neon;
    3896                 :    }
    3897                 : }
    3898                 : #endif /* PNG_ARM_NEON */
    3899                 : 
    3900                 : static void
    3901               3 : png_init_filter_functions(png_structp pp)
    3902                 : {
    3903               3 :    unsigned int bpp = (pp->pixel_depth + 7) >> 3;
    3904                 : 
    3905               3 :    pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
    3906               3 :    pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
    3907               3 :    pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
    3908               3 :    if (bpp == 1)
    3909               0 :       pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
    3910                 :          png_read_filter_row_paeth_1byte_pixel;
    3911                 :    else
    3912               3 :       pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
    3913                 :          png_read_filter_row_paeth_multibyte_pixel;
    3914                 : 
    3915                 : #ifdef PNG_ARM_NEON
    3916                 :    png_init_filter_functions_neon(pp, bpp);
    3917                 : #endif
    3918               3 : }
    3919                 : 
    3920                 : void /* PRIVATE */
    3921             192 : png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row,
    3922                 :    png_const_bytep prev_row, int filter)
    3923                 : {
    3924             192 :    if (pp->read_filter[0] == NULL)
    3925               3 :       png_init_filter_functions(pp);
    3926             192 :    if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
    3927             192 :       pp->read_filter[filter-1](row_info, row, prev_row);
    3928             192 : }
    3929                 : 
    3930                 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
    3931                 : void /* PRIVATE */
    3932                 : png_read_finish_row(png_structp png_ptr)
    3933                 : {
    3934                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    3935                 :    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    3936                 : 
    3937                 :    /* Start of interlace block */
    3938                 :    static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
    3939                 : 
    3940                 :    /* Offset to next interlace block */
    3941                 :    static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    3942                 : 
    3943                 :    /* Start of interlace block in the y direction */
    3944                 :    static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
    3945                 : 
    3946                 :    /* Offset to next interlace block in the y direction */
    3947                 :    static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
    3948                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    3949                 : 
    3950                 :    png_debug(1, "in png_read_finish_row");
    3951                 :    png_ptr->row_number++;
    3952                 :    if (png_ptr->row_number < png_ptr->num_rows)
    3953                 :       return;
    3954                 : 
    3955                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    3956                 :    if (png_ptr->interlaced)
    3957                 :    {
    3958                 :       png_ptr->row_number = 0;
    3959                 : 
    3960                 :       /* TO DO: don't do this if prev_row isn't needed (requires
    3961                 :        * read-ahead of the next row's filter byte.
    3962                 :        */
    3963                 :       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
    3964                 : 
    3965                 :       do
    3966                 :       {
    3967                 :          png_ptr->pass++;
    3968                 : 
    3969                 :          if (png_ptr->pass >= 7)
    3970                 :             break;
    3971                 : 
    3972                 :          png_ptr->iwidth = (png_ptr->width +
    3973                 :             png_pass_inc[png_ptr->pass] - 1 -
    3974                 :             png_pass_start[png_ptr->pass]) /
    3975                 :             png_pass_inc[png_ptr->pass];
    3976                 : 
    3977                 :          if (!(png_ptr->transformations & PNG_INTERLACE))
    3978                 :          {
    3979                 :             png_ptr->num_rows = (png_ptr->height +
    3980                 :                 png_pass_yinc[png_ptr->pass] - 1 -
    3981                 :                 png_pass_ystart[png_ptr->pass]) /
    3982                 :                 png_pass_yinc[png_ptr->pass];
    3983                 :          }
    3984                 : 
    3985                 :          else  /* if (png_ptr->transformations & PNG_INTERLACE) */
    3986                 :             break; /* libpng deinterlacing sees every row */
    3987                 : 
    3988                 :       } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
    3989                 : 
    3990                 :       if (png_ptr->pass < 7)
    3991                 :          return;
    3992                 :    }
    3993                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    3994                 : 
    3995                 :    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    3996                 :    {
    3997                 :       char extra;
    3998                 :       int ret;
    3999                 : 
    4000                 :       png_ptr->zstream.next_out = (Byte *)&extra;
    4001                 :       png_ptr->zstream.avail_out = (uInt)1;
    4002                 : 
    4003                 :       for (;;)
    4004                 :       {
    4005                 :          if (!(png_ptr->zstream.avail_in))
    4006                 :          {
    4007                 :             while (!png_ptr->idat_size)
    4008                 :             {
    4009                 :                png_crc_finish(png_ptr, 0);
    4010                 :                png_ptr->idat_size = png_read_chunk_header(png_ptr);
    4011                 :                if (png_ptr->chunk_name != png_IDAT)
    4012                 :                   png_error(png_ptr, "Not enough image data");
    4013                 :             }
    4014                 : 
    4015                 :             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
    4016                 :             png_ptr->zstream.next_in = png_ptr->zbuf;
    4017                 : 
    4018                 :             if (png_ptr->zbuf_size > png_ptr->idat_size)
    4019                 :                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
    4020                 : 
    4021                 :             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
    4022                 :             png_ptr->idat_size -= png_ptr->zstream.avail_in;
    4023                 :          }
    4024                 : 
    4025                 :          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
    4026                 : 
    4027                 :          if (ret == Z_STREAM_END)
    4028                 :          {
    4029                 :             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
    4030                 :                 png_ptr->idat_size)
    4031                 :                png_warning(png_ptr, "Extra compressed data");
    4032                 : 
    4033                 :             png_ptr->mode |= PNG_AFTER_IDAT;
    4034                 :             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    4035                 :             break;
    4036                 :          }
    4037                 : 
    4038                 :          if (ret != Z_OK)
    4039                 :             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
    4040                 :                 "Decompression Error");
    4041                 : 
    4042                 :          if (!(png_ptr->zstream.avail_out))
    4043                 :          {
    4044                 :             png_warning(png_ptr, "Extra compressed data");
    4045                 :             png_ptr->mode |= PNG_AFTER_IDAT;
    4046                 :             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    4047                 :             break;
    4048                 :          }
    4049                 : 
    4050                 :       }
    4051                 :       png_ptr->zstream.avail_out = 0;
    4052                 :    }
    4053                 : 
    4054                 :    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
    4055                 :       png_warning(png_ptr, "Extra compression data");
    4056                 : 
    4057                 :    inflateReset(&png_ptr->zstream);
    4058                 : 
    4059                 :    png_ptr->mode |= PNG_AFTER_IDAT;
    4060                 : }
    4061                 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
    4062                 : 
    4063                 : void /* PRIVATE */
    4064               4 : png_read_start_row(png_structp png_ptr)
    4065                 : {
    4066                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    4067                 :    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    4068                 : 
    4069                 :    /* Start of interlace block */
    4070                 :    static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
    4071                 : 
    4072                 :    /* Offset to next interlace block */
    4073                 :    static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
    4074                 : 
    4075                 :    /* Start of interlace block in the y direction */
    4076                 :    static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
    4077                 : 
    4078                 :    /* Offset to next interlace block in the y direction */
    4079                 :    static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
    4080                 : #endif
    4081                 : 
    4082                 :    int max_pixel_depth;
    4083                 :    png_size_t row_bytes;
    4084                 : 
    4085                 :    png_debug(1, "in png_read_start_row");
    4086               4 :    png_ptr->zstream.avail_in = 0;
    4087                 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
    4088               4 :    png_init_read_transformations(png_ptr);
    4089                 : #endif
    4090                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    4091               4 :    if (png_ptr->interlaced)
    4092                 :    {
    4093               0 :       if (!(png_ptr->transformations & PNG_INTERLACE))
    4094               0 :          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
    4095               0 :              png_pass_ystart[0]) / png_pass_yinc[0];
    4096                 : 
    4097                 :       else
    4098               0 :          png_ptr->num_rows = png_ptr->height;
    4099                 : 
    4100               0 :       png_ptr->iwidth = (png_ptr->width +
    4101               0 :           png_pass_inc[png_ptr->pass] - 1 -
    4102               0 :           png_pass_start[png_ptr->pass]) /
    4103               0 :           png_pass_inc[png_ptr->pass];
    4104                 :    }
    4105                 : 
    4106                 :    else
    4107                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    4108                 :    {
    4109               4 :       png_ptr->num_rows = png_ptr->height;
    4110               4 :       png_ptr->iwidth = png_ptr->width;
    4111                 :    }
    4112                 : 
    4113               4 :    max_pixel_depth = png_ptr->pixel_depth;
    4114                 : 
    4115                 :    /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
    4116                 :     * calculations to calculate the final pixel depth, then
    4117                 :     * png_do_read_transforms actually does the transforms.  This means that the
    4118                 :     * code which effectively calculates this value is actually repeated in three
    4119                 :     * separate places.  They must all match.  Innocent changes to the order of
    4120                 :     * transformations can and will break libpng in a way that causes memory
    4121                 :     * overwrites.
    4122                 :     *
    4123                 :     * TODO: fix this.
    4124                 :     */
    4125                 : #ifdef PNG_READ_PACK_SUPPORTED
    4126                 :    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
    4127                 :       max_pixel_depth = 8;
    4128                 : #endif
    4129                 : 
    4130                 : #ifdef PNG_READ_EXPAND_SUPPORTED
    4131               4 :    if (png_ptr->transformations & PNG_EXPAND)
    4132                 :    {
    4133               4 :       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    4134                 :       {
    4135               0 :          if (png_ptr->num_trans)
    4136               0 :             max_pixel_depth = 32;
    4137                 : 
    4138                 :          else
    4139               0 :             max_pixel_depth = 24;
    4140                 :       }
    4141                 : 
    4142               4 :       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    4143                 :       {
    4144               0 :          if (max_pixel_depth < 8)
    4145               0 :             max_pixel_depth = 8;
    4146                 : 
    4147               0 :          if (png_ptr->num_trans)
    4148               0 :             max_pixel_depth *= 2;
    4149                 :       }
    4150                 : 
    4151               4 :       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
    4152                 :       {
    4153               1 :          if (png_ptr->num_trans)
    4154                 :          {
    4155               0 :             max_pixel_depth *= 4;
    4156               0 :             max_pixel_depth /= 3;
    4157                 :          }
    4158                 :       }
    4159                 :    }
    4160                 : #endif
    4161                 : 
    4162                 : #ifdef PNG_READ_EXPAND_16_SUPPORTED
    4163                 :    if (png_ptr->transformations & PNG_EXPAND_16)
    4164                 :    {
    4165                 : #     ifdef PNG_READ_EXPAND_SUPPORTED
    4166                 :          /* In fact it is an error if it isn't supported, but checking is
    4167                 :           * the safe way.
    4168                 :           */
    4169                 :          if (png_ptr->transformations & PNG_EXPAND)
    4170                 :          {
    4171                 :             if (png_ptr->bit_depth < 16)
    4172                 :                max_pixel_depth *= 2;
    4173                 :          }
    4174                 :          else
    4175                 : #     endif
    4176                 :          png_ptr->transformations &= ~PNG_EXPAND_16;
    4177                 :    }
    4178                 : #endif
    4179                 : 
    4180                 : #ifdef PNG_READ_FILLER_SUPPORTED
    4181                 :    if (png_ptr->transformations & (PNG_FILLER))
    4182                 :    {
    4183                 :       if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
    4184                 :       {
    4185                 :          if (max_pixel_depth <= 8)
    4186                 :             max_pixel_depth = 16;
    4187                 : 
    4188                 :          else
    4189                 :             max_pixel_depth = 32;
    4190                 :       }
    4191                 : 
    4192                 :       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
    4193                 :          png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    4194                 :       {
    4195                 :          if (max_pixel_depth <= 32)
    4196                 :             max_pixel_depth = 32;
    4197                 : 
    4198                 :          else
    4199                 :             max_pixel_depth = 64;
    4200                 :       }
    4201                 :    }
    4202                 : #endif
    4203                 : 
    4204                 : #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    4205               4 :    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
    4206                 :    {
    4207               4 :       if (
    4208                 : #ifdef PNG_READ_EXPAND_SUPPORTED
    4209               8 :           (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
    4210                 : #endif
    4211                 : #ifdef PNG_READ_FILLER_SUPPORTED
    4212                 :           (png_ptr->transformations & (PNG_FILLER)) ||
    4213                 : #endif
    4214               4 :           png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    4215                 :       {
    4216               0 :          if (max_pixel_depth <= 16)
    4217               0 :             max_pixel_depth = 32;
    4218                 : 
    4219                 :          else
    4220               0 :             max_pixel_depth = 64;
    4221                 :       }
    4222                 : 
    4223                 :       else
    4224                 :       {
    4225               4 :          if (max_pixel_depth <= 8)
    4226                 :          {
    4227               0 :             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    4228               0 :                max_pixel_depth = 32;
    4229                 : 
    4230                 :             else
    4231               0 :                max_pixel_depth = 24;
    4232                 :          }
    4233                 : 
    4234               4 :          else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    4235               3 :             max_pixel_depth = 64;
    4236                 : 
    4237                 :          else
    4238               1 :             max_pixel_depth = 48;
    4239                 :       }
    4240                 :    }
    4241                 : #endif
    4242                 : 
    4243                 : #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
    4244                 : defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
    4245                 :    if (png_ptr->transformations & PNG_USER_TRANSFORM)
    4246                 :    {
    4247                 :       int user_pixel_depth = png_ptr->user_transform_depth *
    4248                 :          png_ptr->user_transform_channels;
    4249                 : 
    4250                 :       if (user_pixel_depth > max_pixel_depth)
    4251                 :          max_pixel_depth = user_pixel_depth;
    4252                 :    }
    4253                 : #endif
    4254                 : 
    4255                 :    /* This value is stored in png_struct and double checked in the row read
    4256                 :     * code.
    4257                 :     */
    4258               4 :    png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
    4259               4 :    png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
    4260                 : 
    4261                 :    /* Align the width on the next larger 8 pixels.  Mainly used
    4262                 :     * for interlacing
    4263                 :     */
    4264               4 :    row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
    4265                 :    /* Calculate the maximum bytes needed, adding a byte and a pixel
    4266                 :     * for safety's sake
    4267                 :     */
    4268               8 :    row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
    4269               4 :        1 + ((max_pixel_depth + 7) >> 3);
    4270                 : 
    4271                 : #ifdef PNG_MAX_MALLOC_64K
    4272                 :    if (row_bytes > (png_uint_32)65536L)
    4273                 :       png_error(png_ptr, "This image requires a row greater than 64KB");
    4274                 : #endif
    4275                 : 
    4276               4 :    if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
    4277                 :    {
    4278               4 :      png_free(png_ptr, png_ptr->big_row_buf);
    4279               4 :      png_free(png_ptr, png_ptr->big_prev_row);
    4280                 : 
    4281               4 :      if (png_ptr->interlaced)
    4282               0 :         png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
    4283                 :             row_bytes + 48);
    4284                 : 
    4285                 :      else
    4286               4 :         png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
    4287                 : 
    4288               4 :      png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
    4289                 : 
    4290                 : #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
    4291                 :      /* Use 16-byte aligned memory for row_buf with at least 16 bytes
    4292                 :       * of padding before and after row_buf; treat prev_row similarly.
    4293                 :       * NOTE: the alignment is to the start of the pixels, one beyond the start
    4294                 :       * of the buffer, because of the filter byte.  Prior to libpng 1.5.6 this
    4295                 :       * was incorrect; the filter byte was aligned, which had the exact
    4296                 :       * opposite effect of that intended.
    4297                 :       */
    4298                 :      {
    4299                 :         png_bytep temp = png_ptr->big_row_buf + 32;
    4300                 :         int extra = (int)((temp - (png_bytep)0) & 0x0f);
    4301                 :         png_ptr->row_buf = temp - extra - 1/*filter byte*/;
    4302                 : 
    4303                 :         temp = png_ptr->big_prev_row + 32;
    4304                 :         extra = (int)((temp - (png_bytep)0) & 0x0f);
    4305                 :         png_ptr->prev_row = temp - extra - 1/*filter byte*/;
    4306                 :      }
    4307                 : 
    4308                 : #else
    4309                 :      /* Use 31 bytes of padding before and 17 bytes after row_buf. */
    4310               4 :      png_ptr->row_buf = png_ptr->big_row_buf + 31;
    4311               4 :      png_ptr->prev_row = png_ptr->big_prev_row + 31;
    4312                 : #endif
    4313               4 :      png_ptr->old_big_row_buf_size = row_bytes + 48;
    4314                 :    }
    4315                 : 
    4316                 : #ifdef PNG_MAX_MALLOC_64K
    4317                 :    if (png_ptr->rowbytes > 65535)
    4318                 :       png_error(png_ptr, "This image requires a row greater than 64KB");
    4319                 : 
    4320                 : #endif
    4321               4 :    if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
    4322               0 :       png_error(png_ptr, "Row has too many bytes to allocate in memory");
    4323                 : 
    4324               4 :    png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
    4325                 : 
    4326                 :    png_debug1(3, "width = %u,", png_ptr->width);
    4327                 :    png_debug1(3, "height = %u,", png_ptr->height);
    4328                 :    png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
    4329                 :    png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
    4330                 :    png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
    4331                 :    png_debug1(3, "irowbytes = %lu",
    4332                 :        (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
    4333                 : 
    4334               4 :    png_ptr->flags |= PNG_FLAG_ROW_INIT;
    4335               4 : }
    4336                 : 
    4337                 : #ifdef PNG_READ_APNG_SUPPORTED
    4338                 : /* This function is to be called after the main IDAT set has been read and
    4339                 :  * before a new IDAT is read. It resets some parts of png_ptr
    4340                 :  * to make them usable by the read functions again */
    4341                 : void /* PRIVATE */
    4342               0 : png_read_reset(png_structp png_ptr)
    4343                 : {
    4344               0 :     png_ptr->mode &= ~PNG_HAVE_IDAT;
    4345               0 :     png_ptr->mode &= ~PNG_AFTER_IDAT;
    4346               0 :     png_ptr->row_number = 0;
    4347               0 :     png_ptr->pass = 0;
    4348               0 :     png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
    4349               0 : }
    4350                 : 
    4351                 : void /* PRIVATE */
    4352               0 : png_read_reinit(png_structp png_ptr, png_infop info_ptr)
    4353                 : {
    4354               0 :     png_ptr->width = info_ptr->next_frame_width;
    4355               0 :     png_ptr->height = info_ptr->next_frame_height;
    4356               0 :     png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
    4357               0 :     png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
    4358                 :         png_ptr->width);
    4359               0 :     if (png_ptr->prev_row)
    4360               0 :         png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
    4361               0 : }
    4362                 : 
    4363                 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
    4364                 : /* same as png_read_reset() but for the progressive reader */
    4365                 : void /* PRIVATE */
    4366               0 : png_progressive_read_reset(png_structp png_ptr)
    4367                 : {
    4368                 : #ifdef PNG_READ_INTERLACING_SUPPORTED
    4369                 :    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    4370                 : 
    4371                 :    /* Start of interlace block */
    4372               0 :     const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
    4373                 : 
    4374                 :     /* Offset to next interlace block */
    4375               0 :     const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
    4376                 : 
    4377                 :     /* Start of interlace block in the y direction */
    4378                 :     const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
    4379                 : 
    4380                 :     /* Offset to next interlace block in the y direction */
    4381                 :     const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
    4382                 : 
    4383               0 :     if (png_ptr->interlaced)
    4384                 :     {
    4385               0 :         if (!(png_ptr->transformations & PNG_INTERLACE))
    4386               0 :             png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
    4387               0 :                                 png_pass_ystart[0]) / png_pass_yinc[0];
    4388                 :         else
    4389               0 :             png_ptr->num_rows = png_ptr->height;
    4390                 : 
    4391               0 :         png_ptr->iwidth = (png_ptr->width +
    4392               0 :                            png_pass_inc[png_ptr->pass] - 1 -
    4393               0 :                            png_pass_start[png_ptr->pass]) /
    4394               0 :                            png_pass_inc[png_ptr->pass];
    4395                 :     }
    4396                 :     else
    4397                 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
    4398                 :     {
    4399               0 :         png_ptr->num_rows = png_ptr->height;
    4400               0 :         png_ptr->iwidth = png_ptr->width;
    4401                 :     }
    4402               0 :     png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED;
    4403               0 :     if (inflateReset(&(png_ptr->zstream)) != Z_OK)
    4404               0 :         png_error(png_ptr, "inflateReset failed");
    4405               0 :     png_ptr->zstream.avail_in = 0;
    4406               0 :     png_ptr->zstream.next_in = 0;
    4407               0 :     png_ptr->zstream.next_out = png_ptr->row_buf;
    4408               0 :     png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
    4409               0 :         png_ptr->iwidth) + 1;
    4410               0 : }
    4411                 : #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
    4412                 : #endif /* PNG_READ_APNG_SUPPORTED */
    4413                 : #endif /* PNG_READ_SUPPORTED */

Generated by: LCOV version 1.7