LCOV - code coverage report
Current view: top level - media/libpng - png.c (source / functions) Hit Total Coverage
Test: output.info Lines: 184 772 23.8 %
Date: 2017-07-14 16:53:18 Functions: 21 64 32.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /* png.c - location for general purpose libpng functions
       3             :  *
       4             :  * Last changed in libpng 1.6.29 [March 16, 2017]
       5             :  * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
       6             :  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
       7             :  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
       8             :  *
       9             :  * This code is released under the libpng license.
      10             :  * For conditions of distribution and use, see the disclaimer
      11             :  * and license in png.h
      12             :  */
      13             : 
      14             : #include "pngpriv.h"
      15             : 
      16             : /* Generate a compiler error if there is an old png.h in the search path. */
      17             : typedef png_libpng_version_1_6_29 Your_png_h_is_not_version_1_6_29;
      18             : 
      19             : /* Tells libpng that we have already handled the first "num_bytes" bytes
      20             :  * of the PNG file signature.  If the PNG data is embedded into another
      21             :  * stream we can set num_bytes = 8 so that libpng will not attempt to read
      22             :  * or write any of the magic bytes before it starts on the IHDR.
      23             :  */
      24             : 
      25             : #ifdef PNG_READ_SUPPORTED
      26             : void PNGAPI
      27           0 : png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
      28             : {
      29           0 :    unsigned int nb = (unsigned int)num_bytes;
      30             : 
      31             :    png_debug(1, "in png_set_sig_bytes");
      32             : 
      33           0 :    if (png_ptr == NULL)
      34           0 :       return;
      35             : 
      36           0 :    if (num_bytes < 0)
      37           0 :       nb = 0;
      38             : 
      39           0 :    if (nb > 8)
      40           0 :       png_error(png_ptr, "Too many bytes for PNG signature");
      41             : 
      42           0 :    png_ptr->sig_bytes = (png_byte)nb;
      43             : }
      44             : 
      45             : /* Checks whether the supplied bytes match the PNG signature.  We allow
      46             :  * checking less than the full 8-byte signature so that those apps that
      47             :  * already read the first few bytes of a file to determine the file type
      48             :  * can simply check the remaining bytes for extra assurance.  Returns
      49             :  * an integer less than, equal to, or greater than zero if sig is found,
      50             :  * respectively, to be less than, to match, or be greater than the correct
      51             :  * PNG signature (this is the same behavior as strcmp, memcmp, etc).
      52             :  */
      53             : int PNGAPI
      54          31 : png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
      55             : {
      56          31 :    png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
      57             : 
      58          31 :    if (num_to_check > 8)
      59           0 :       num_to_check = 8;
      60             : 
      61          31 :    else if (num_to_check < 1)
      62           0 :       return (-1);
      63             : 
      64          31 :    if (start > 7)
      65           0 :       return (-1);
      66             : 
      67          31 :    if (start + num_to_check > 8)
      68           0 :       num_to_check = 8 - start;
      69             : 
      70          31 :    return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
      71             : }
      72             : 
      73             : #endif /* READ */
      74             : 
      75             : #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
      76             : /* Function to allocate memory for zlib */
      77          44 : PNG_FUNCTION(voidpf /* PRIVATE */,
      78             : png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
      79             : {
      80          44 :    png_alloc_size_t num_bytes = size;
      81             : 
      82          44 :    if (png_ptr == NULL)
      83           0 :       return NULL;
      84             : 
      85          44 :    if (items >= (~(png_alloc_size_t)0)/size)
      86             :    {
      87           0 :       png_warning (png_voidcast(png_structrp, png_ptr),
      88             :           "Potential overflow in png_zalloc()");
      89           0 :       return NULL;
      90             :    }
      91             : 
      92          44 :    num_bytes *= items;
      93          44 :    return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
      94             : }
      95             : 
      96             : /* Function to free memory for zlib */
      97             : void /* PRIVATE */
      98          44 : png_zfree(voidpf png_ptr, voidpf ptr)
      99             : {
     100          44 :    png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
     101          44 : }
     102             : 
     103             : /* Reset the CRC variable to 32 bits of 1's.  Care must be taken
     104             :  * in case CRC is > 32 bits to leave the top bits 0.
     105             :  */
     106             : void /* PRIVATE */
     107         206 : png_reset_crc(png_structrp png_ptr)
     108             : {
     109             :    /* The cast is safe because the crc is a 32-bit value. */
     110         206 :    png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
     111         206 : }
     112             : 
     113             : /* Calculate the CRC over a section of data.  We can only pass as
     114             :  * much data to this routine as the largest single buffer size.  We
     115             :  * also check that this data will actually be used before going to the
     116             :  * trouble of calculating it.
     117             :  */
     118             : void /* PRIVATE */
     119         561 : png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
     120             : {
     121         561 :    int need_crc = 1;
     122             : 
     123         561 :    if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
     124             :    {
     125         330 :       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
     126             :           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
     127           0 :          need_crc = 0;
     128             :    }
     129             : 
     130             :    else /* critical */
     131             :    {
     132         231 :       if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
     133           0 :          need_crc = 0;
     134             :    }
     135             : 
     136             :    /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
     137             :     * systems it is a 64-bit value.  crc32, however, returns 32 bits so the
     138             :     * following cast is safe.  'uInt' may be no more than 16 bits, so it is
     139             :     * necessary to perform a loop here.
     140             :     */
     141         561 :    if (need_crc != 0 && length > 0)
     142             :    {
     143         561 :       uLong crc = png_ptr->crc; /* Should never issue a warning */
     144             : 
     145             :       do
     146             :       {
     147         561 :          uInt safe_length = (uInt)length;
     148             : #ifndef __COVERITY__
     149         561 :          if (safe_length == 0)
     150           0 :             safe_length = (uInt)-1; /* evil, but safe */
     151             : #endif
     152             : 
     153         561 :          crc = crc32(crc, ptr, safe_length);
     154             : 
     155             :          /* The following should never issue compiler warnings; if they do the
     156             :           * target system has characteristics that will probably violate other
     157             :           * assumptions within the libpng code.
     158             :           */
     159         561 :          ptr += safe_length;
     160         561 :          length -= safe_length;
     161             :       }
     162         561 :       while (length > 0);
     163             : 
     164             :       /* And the following is always safe because the crc is only 32 bits. */
     165         561 :       png_ptr->crc = (png_uint_32)crc;
     166             :    }
     167         561 : }
     168             : 
     169             : /* Check a user supplied version number, called from both read and write
     170             :  * functions that create a png_struct.
     171             :  */
     172             : int
     173          31 : png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
     174             : {
     175             :    /* Libpng versions 1.0.0 and later are binary compatible if the version
     176             :     * string matches through the second '.'; we must recompile any
     177             :     * applications that use any older library version.
     178             :     */
     179             : 
     180          31 :    if (user_png_ver != NULL)
     181             :    {
     182          31 :       int i = -1;
     183          31 :       int found_dots = 0;
     184             : 
     185             :       do
     186             :       {
     187         124 :          i++;
     188         124 :          if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
     189           0 :             png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
     190         124 :          if (user_png_ver[i] == '.')
     191          62 :             found_dots++;
     192         186 :       } while (found_dots < 2 && user_png_ver[i] != 0 &&
     193         217 :             PNG_LIBPNG_VER_STRING[i] != 0);
     194             :    }
     195             : 
     196             :    else
     197           0 :       png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
     198             : 
     199          31 :    if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
     200             :    {
     201             : #ifdef PNG_WARNINGS_SUPPORTED
     202           0 :       size_t pos = 0;
     203             :       char m[128];
     204             : 
     205           0 :       pos = png_safecat(m, (sizeof m), pos,
     206             :           "Application built with libpng-");
     207           0 :       pos = png_safecat(m, (sizeof m), pos, user_png_ver);
     208           0 :       pos = png_safecat(m, (sizeof m), pos, " but running with ");
     209           0 :       pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
     210             :       PNG_UNUSED(pos)
     211             : 
     212           0 :       png_warning(png_ptr, m);
     213             : #endif
     214             : 
     215             : #ifdef PNG_ERROR_NUMBERS_SUPPORTED
     216             :       png_ptr->flags = 0;
     217             : #endif
     218             : 
     219           0 :       return 0;
     220             :    }
     221             : 
     222             :    /* Success return. */
     223          31 :    return 1;
     224             : }
     225             : 
     226             : /* Generic function to create a png_struct for either read or write - this
     227             :  * contains the common initialization.
     228             :  */
     229          31 : PNG_FUNCTION(png_structp /* PRIVATE */,
     230             : png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
     231             :     png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
     232             :     png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
     233             : {
     234             :    png_struct create_struct;
     235             : #  ifdef PNG_SETJMP_SUPPORTED
     236             :       jmp_buf create_jmp_buf;
     237             : #  endif
     238             : 
     239             :    /* This temporary stack-allocated structure is used to provide a place to
     240             :     * build enough context to allow the user provided memory allocator (if any)
     241             :     * to be called.
     242             :     */
     243          31 :    memset(&create_struct, 0, (sizeof create_struct));
     244             : 
     245             :    /* Added at libpng-1.2.6 */
     246             : #  ifdef PNG_USER_LIMITS_SUPPORTED
     247          31 :       create_struct.user_width_max = PNG_USER_WIDTH_MAX;
     248          31 :       create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
     249             : 
     250             : #     ifdef PNG_USER_CHUNK_CACHE_MAX
     251             :       /* Added at libpng-1.2.43 and 1.4.0 */
     252          31 :       create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
     253             : #     endif
     254             : 
     255             : #     ifdef PNG_USER_CHUNK_MALLOC_MAX
     256             :       /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
     257             :        * in png_struct regardless.
     258             :        */
     259          31 :       create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
     260             : #     endif
     261             : #  endif
     262             : 
     263             :    /* The following two API calls simply set fields in png_struct, so it is safe
     264             :     * to do them now even though error handling is not yet set up.
     265             :     */
     266             : #  ifdef PNG_USER_MEM_SUPPORTED
     267             :       png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
     268             : #  else
     269             :       PNG_UNUSED(mem_ptr)
     270             :       PNG_UNUSED(malloc_fn)
     271             :       PNG_UNUSED(free_fn)
     272             : #  endif
     273             : 
     274             :    /* (*error_fn) can return control to the caller after the error_ptr is set,
     275             :     * this will result in a memory leak unless the error_fn does something
     276             :     * extremely sophisticated.  The design lacks merit but is implicit in the
     277             :     * API.
     278             :     */
     279          31 :    png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
     280             : 
     281             : #  ifdef PNG_SETJMP_SUPPORTED
     282          31 :       if (!setjmp(create_jmp_buf))
     283             : #  endif
     284             :       {
     285             : #  ifdef PNG_SETJMP_SUPPORTED
     286             :          /* Temporarily fake out the longjmp information until we have
     287             :           * successfully completed this function.  This only works if we have
     288             :           * setjmp() support compiled in, but it is safe - this stuff should
     289             :           * never happen.
     290             :           */
     291          31 :          create_struct.jmp_buf_ptr = &create_jmp_buf;
     292          31 :          create_struct.jmp_buf_size = 0; /*stack allocation*/
     293          31 :          create_struct.longjmp_fn = longjmp;
     294             : #  endif
     295             :          /* Call the general version checker (shared with read and write code):
     296             :           */
     297          31 :          if (png_user_version_check(&create_struct, user_png_ver) != 0)
     298             :          {
     299          31 :             png_structrp png_ptr = png_voidcast(png_structrp,
     300             :                 png_malloc_warn(&create_struct, (sizeof *png_ptr)));
     301             : 
     302          31 :             if (png_ptr != NULL)
     303             :             {
     304             :                /* png_ptr->zstream holds a back-pointer to the png_struct, so
     305             :                 * this can only be done now:
     306             :                 */
     307          31 :                create_struct.zstream.zalloc = png_zalloc;
     308          31 :                create_struct.zstream.zfree = png_zfree;
     309          31 :                create_struct.zstream.opaque = png_ptr;
     310             : 
     311             : #              ifdef PNG_SETJMP_SUPPORTED
     312             :                /* Eliminate the local error handling: */
     313          31 :                create_struct.jmp_buf_ptr = NULL;
     314          31 :                create_struct.jmp_buf_size = 0;
     315          31 :                create_struct.longjmp_fn = 0;
     316             : #              endif
     317             : 
     318          31 :                *png_ptr = create_struct;
     319             : 
     320             :                /* This is the successful return point */
     321          31 :                return png_ptr;
     322             :             }
     323             :          }
     324             :       }
     325             : 
     326             :    /* A longjmp because of a bug in the application storage allocator or a
     327             :     * simple failure to allocate the png_struct.
     328             :     */
     329           0 :    return NULL;
     330             : }
     331             : 
     332             : /* Allocate the memory for an info_struct for the application. */
     333          31 : PNG_FUNCTION(png_infop,PNGAPI
     334             : png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
     335             : {
     336             :    png_inforp info_ptr;
     337             : 
     338             :    png_debug(1, "in png_create_info_struct");
     339             : 
     340          31 :    if (png_ptr == NULL)
     341           0 :       return NULL;
     342             : 
     343             :    /* Use the internal API that does not (or at least should not) error out, so
     344             :     * that this call always returns ok.  The application typically sets up the
     345             :     * error handling *after* creating the info_struct because this is the way it
     346             :     * has always been done in 'example.c'.
     347             :     */
     348          31 :    info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
     349             :        (sizeof *info_ptr)));
     350             : 
     351          31 :    if (info_ptr != NULL)
     352          31 :       memset(info_ptr, 0, (sizeof *info_ptr));
     353             : 
     354          31 :    return info_ptr;
     355             : }
     356             : 
     357             : /* This function frees the memory associated with a single info struct.
     358             :  * Normally, one would use either png_destroy_read_struct() or
     359             :  * png_destroy_write_struct() to free an info struct, but this may be
     360             :  * useful for some applications.  From libpng 1.6.0 this function is also used
     361             :  * internally to implement the png_info release part of the 'struct' destroy
     362             :  * APIs.  This ensures that all possible approaches free the same data (all of
     363             :  * it).
     364             :  */
     365             : void PNGAPI
     366          62 : png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
     367             : {
     368          62 :    png_inforp info_ptr = NULL;
     369             : 
     370             :    png_debug(1, "in png_destroy_info_struct");
     371             : 
     372          62 :    if (png_ptr == NULL)
     373           0 :       return;
     374             : 
     375          62 :    if (info_ptr_ptr != NULL)
     376          31 :       info_ptr = *info_ptr_ptr;
     377             : 
     378          62 :    if (info_ptr != NULL)
     379             :    {
     380             :       /* Do this first in case of an error below; if the app implements its own
     381             :        * memory management this can lead to png_free calling png_error, which
     382             :        * will abort this routine and return control to the app error handler.
     383             :        * An infinite loop may result if it then tries to free the same info
     384             :        * ptr.
     385             :        */
     386          31 :       *info_ptr_ptr = NULL;
     387             : 
     388          31 :       png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
     389          31 :       memset(info_ptr, 0, (sizeof *info_ptr));
     390          31 :       png_free(png_ptr, info_ptr);
     391             :    }
     392             : }
     393             : 
     394             : /* Initialize the info structure.  This is now an internal function (0.89)
     395             :  * and applications using it are urged to use png_create_info_struct()
     396             :  * instead.  Use deprecated in 1.6.0, internal use removed (used internally it
     397             :  * is just a memset).
     398             :  *
     399             :  * NOTE: it is almost inconceivable that this API is used because it bypasses
     400             :  * the user-memory mechanism and the user error handling/warning mechanisms in
     401             :  * those cases where it does anything other than a memset.
     402             :  */
     403           0 : PNG_FUNCTION(void,PNGAPI
     404             : png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
     405             :     PNG_DEPRECATED)
     406             : {
     407           0 :    png_inforp info_ptr = *ptr_ptr;
     408             : 
     409             :    png_debug(1, "in png_info_init_3");
     410             : 
     411           0 :    if (info_ptr == NULL)
     412           0 :       return;
     413             : 
     414           0 :    if ((sizeof (png_info)) > png_info_struct_size)
     415             :    {
     416           0 :       *ptr_ptr = NULL;
     417             :       /* The following line is why this API should not be used: */
     418           0 :       free(info_ptr);
     419           0 :       info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
     420             :           (sizeof *info_ptr)));
     421           0 :       if (info_ptr == NULL)
     422           0 :          return;
     423           0 :       *ptr_ptr = info_ptr;
     424             :    }
     425             : 
     426             :    /* Set everything to 0 */
     427           0 :    memset(info_ptr, 0, (sizeof *info_ptr));
     428             : }
     429             : 
     430             : /* The following API is not called internally */
     431             : void PNGAPI
     432           0 : png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
     433             :     int freer, png_uint_32 mask)
     434             : {
     435             :    png_debug(1, "in png_data_freer");
     436             : 
     437           0 :    if (png_ptr == NULL || info_ptr == NULL)
     438           0 :       return;
     439             : 
     440           0 :    if (freer == PNG_DESTROY_WILL_FREE_DATA)
     441           0 :       info_ptr->free_me |= mask;
     442             : 
     443           0 :    else if (freer == PNG_USER_WILL_FREE_DATA)
     444           0 :       info_ptr->free_me &= ~mask;
     445             : 
     446             :    else
     447           0 :       png_error(png_ptr, "Unknown freer parameter in png_data_freer");
     448             : }
     449             : 
     450             : void PNGAPI
     451          35 : png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
     452             :     int num)
     453             : {
     454             :    png_debug(1, "in png_free_data");
     455             : 
     456          35 :    if (png_ptr == NULL || info_ptr == NULL)
     457           0 :       return;
     458             : 
     459             : #ifdef PNG_TEXT_SUPPORTED
     460             :    /* Free text item num or (if num == -1) all text items */
     461             :    if (info_ptr->text != NULL &&
     462             :        ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
     463             :    {
     464             :       if (num != -1)
     465             :       {
     466             :          png_free(png_ptr, info_ptr->text[num].key);
     467             :          info_ptr->text[num].key = NULL;
     468             :       }
     469             : 
     470             :       else
     471             :       {
     472             :          int i;
     473             : 
     474             :          for (i = 0; i < info_ptr->num_text; i++)
     475             :             png_free(png_ptr, info_ptr->text[i].key);
     476             : 
     477             :          png_free(png_ptr, info_ptr->text);
     478             :          info_ptr->text = NULL;
     479             :          info_ptr->num_text = 0;
     480             :          info_ptr->max_text = 0;
     481             :       }
     482             :    }
     483             : #endif
     484             : 
     485             : #ifdef PNG_tRNS_SUPPORTED
     486             :    /* Free any tRNS entry */
     487          35 :    if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
     488             :    {
     489           2 :       info_ptr->valid &= ~PNG_INFO_tRNS;
     490           2 :       png_free(png_ptr, info_ptr->trans_alpha);
     491           2 :       info_ptr->trans_alpha = NULL;
     492           2 :       info_ptr->num_trans = 0;
     493             :    }
     494             : #endif
     495             : 
     496             : #ifdef PNG_sCAL_SUPPORTED
     497             :    /* Free any sCAL entry */
     498             :    if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
     499             :    {
     500             :       png_free(png_ptr, info_ptr->scal_s_width);
     501             :       png_free(png_ptr, info_ptr->scal_s_height);
     502             :       info_ptr->scal_s_width = NULL;
     503             :       info_ptr->scal_s_height = NULL;
     504             :       info_ptr->valid &= ~PNG_INFO_sCAL;
     505             :    }
     506             : #endif
     507             : 
     508             : #ifdef PNG_pCAL_SUPPORTED
     509             :    /* Free any pCAL entry */
     510             :    if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
     511             :    {
     512             :       png_free(png_ptr, info_ptr->pcal_purpose);
     513             :       png_free(png_ptr, info_ptr->pcal_units);
     514             :       info_ptr->pcal_purpose = NULL;
     515             :       info_ptr->pcal_units = NULL;
     516             : 
     517             :       if (info_ptr->pcal_params != NULL)
     518             :          {
     519             :             int i;
     520             : 
     521             :             for (i = 0; i < info_ptr->pcal_nparams; i++)
     522             :                png_free(png_ptr, info_ptr->pcal_params[i]);
     523             : 
     524             :             png_free(png_ptr, info_ptr->pcal_params);
     525             :             info_ptr->pcal_params = NULL;
     526             :          }
     527             :       info_ptr->valid &= ~PNG_INFO_pCAL;
     528             :    }
     529             : #endif
     530             : 
     531             : #ifdef PNG_iCCP_SUPPORTED
     532             :    /* Free any profile entry */
     533          35 :    if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
     534             :    {
     535           0 :       png_free(png_ptr, info_ptr->iccp_name);
     536           0 :       png_free(png_ptr, info_ptr->iccp_profile);
     537           0 :       info_ptr->iccp_name = NULL;
     538           0 :       info_ptr->iccp_profile = NULL;
     539           0 :       info_ptr->valid &= ~PNG_INFO_iCCP;
     540             :    }
     541             : #endif
     542             : 
     543             : #ifdef PNG_sPLT_SUPPORTED
     544             :    /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
     545             :    if (info_ptr->splt_palettes != NULL &&
     546             :        ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
     547             :    {
     548             :       if (num != -1)
     549             :       {
     550             :          png_free(png_ptr, info_ptr->splt_palettes[num].name);
     551             :          png_free(png_ptr, info_ptr->splt_palettes[num].entries);
     552             :          info_ptr->splt_palettes[num].name = NULL;
     553             :          info_ptr->splt_palettes[num].entries = NULL;
     554             :       }
     555             : 
     556             :       else
     557             :       {
     558             :          int i;
     559             : 
     560             :          for (i = 0; i < info_ptr->splt_palettes_num; i++)
     561             :          {
     562             :             png_free(png_ptr, info_ptr->splt_palettes[i].name);
     563             :             png_free(png_ptr, info_ptr->splt_palettes[i].entries);
     564             :          }
     565             : 
     566             :          png_free(png_ptr, info_ptr->splt_palettes);
     567             :          info_ptr->splt_palettes = NULL;
     568             :          info_ptr->splt_palettes_num = 0;
     569             :          info_ptr->valid &= ~PNG_INFO_sPLT;
     570             :       }
     571             :    }
     572             : #endif
     573             : 
     574             : #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
     575             :    if (info_ptr->unknown_chunks != NULL &&
     576             :        ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
     577             :    {
     578             :       if (num != -1)
     579             :       {
     580             :           png_free(png_ptr, info_ptr->unknown_chunks[num].data);
     581             :           info_ptr->unknown_chunks[num].data = NULL;
     582             :       }
     583             : 
     584             :       else
     585             :       {
     586             :          int i;
     587             : 
     588             :          for (i = 0; i < info_ptr->unknown_chunks_num; i++)
     589             :             png_free(png_ptr, info_ptr->unknown_chunks[i].data);
     590             : 
     591             :          png_free(png_ptr, info_ptr->unknown_chunks);
     592             :          info_ptr->unknown_chunks = NULL;
     593             :          info_ptr->unknown_chunks_num = 0;
     594             :       }
     595             :    }
     596             : #endif
     597             : 
     598             : #ifdef PNG_hIST_SUPPORTED
     599             :    /* Free any hIST entry */
     600             :    if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
     601             :    {
     602             :       png_free(png_ptr, info_ptr->hist);
     603             :       info_ptr->hist = NULL;
     604             :       info_ptr->valid &= ~PNG_INFO_hIST;
     605             :    }
     606             : #endif
     607             : 
     608             :    /* Free any PLTE entry that was internally allocated */
     609          35 :    if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
     610             :    {
     611           2 :       png_free(png_ptr, info_ptr->palette);
     612           2 :       info_ptr->palette = NULL;
     613           2 :       info_ptr->valid &= ~PNG_INFO_PLTE;
     614           2 :       info_ptr->num_palette = 0;
     615             :    }
     616             : 
     617             : #ifdef PNG_INFO_IMAGE_SUPPORTED
     618             :    /* Free any image bits attached to the info structure */
     619             :    if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
     620             :    {
     621             :       if (info_ptr->row_pointers != NULL)
     622             :       {
     623             :          png_uint_32 row;
     624             :          for (row = 0; row < info_ptr->height; row++)
     625             :             png_free(png_ptr, info_ptr->row_pointers[row]);
     626             : 
     627             :          png_free(png_ptr, info_ptr->row_pointers);
     628             :          info_ptr->row_pointers = NULL;
     629             :       }
     630             :       info_ptr->valid &= ~PNG_INFO_IDAT;
     631             :    }
     632             : #endif
     633             : 
     634          35 :    if (num != -1)
     635           4 :       mask &= ~PNG_FREE_MUL;
     636             : 
     637          35 :    info_ptr->free_me &= ~mask;
     638             : }
     639             : #endif /* READ || WRITE */
     640             : 
     641             : /* This function returns a pointer to the io_ptr associated with the user
     642             :  * functions.  The application should free any memory associated with this
     643             :  * pointer before png_write_destroy() or png_read_destroy() are called.
     644             :  */
     645             : png_voidp PNGAPI
     646           0 : png_get_io_ptr(png_const_structrp png_ptr)
     647             : {
     648           0 :    if (png_ptr == NULL)
     649           0 :       return (NULL);
     650             : 
     651           0 :    return (png_ptr->io_ptr);
     652             : }
     653             : 
     654             : #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
     655             : #  ifdef PNG_STDIO_SUPPORTED
     656             : /* Initialize the default input/output functions for the PNG file.  If you
     657             :  * use your own read or write routines, you can call either png_set_read_fn()
     658             :  * or png_set_write_fn() instead of png_init_io().  If you have defined
     659             :  * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
     660             :  * function of your own because "FILE *" isn't necessarily available.
     661             :  */
     662             : void PNGAPI
     663           0 : png_init_io(png_structrp png_ptr, png_FILE_p fp)
     664             : {
     665             :    png_debug(1, "in png_init_io");
     666             : 
     667           0 :    if (png_ptr == NULL)
     668           0 :       return;
     669             : 
     670           0 :    png_ptr->io_ptr = (png_voidp)fp;
     671             : }
     672             : #  endif
     673             : 
     674             : #  ifdef PNG_SAVE_INT_32_SUPPORTED
     675             : /* PNG signed integers are saved in 32-bit 2's complement format.  ANSI C-90
     676             :  * defines a cast of a signed integer to an unsigned integer either to preserve
     677             :  * the value, if it is positive, or to calculate:
     678             :  *
     679             :  *     (UNSIGNED_MAX+1) + integer
     680             :  *
     681             :  * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
     682             :  * negative integral value is added the result will be an unsigned value
     683             :  * correspnding to the 2's complement representation.
     684             :  */
     685             : void PNGAPI
     686             : png_save_int_32(png_bytep buf, png_int_32 i)
     687             : {
     688             :    png_save_uint_32(buf, (png_uint_32)i);
     689             : }
     690             : #  endif
     691             : 
     692             : #  ifdef PNG_TIME_RFC1123_SUPPORTED
     693             : /* Convert the supplied time into an RFC 1123 string suitable for use in
     694             :  * a "Creation Time" or other text-based time string.
     695             :  */
     696             : int PNGAPI
     697             : png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
     698             : {
     699             :    static PNG_CONST char short_months[12][4] =
     700             :         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
     701             :          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
     702             : 
     703             :    if (out == NULL)
     704             :       return 0;
     705             : 
     706             :    if (ptime->year > 9999 /* RFC1123 limitation */ ||
     707             :        ptime->month == 0    ||  ptime->month > 12  ||
     708             :        ptime->day   == 0    ||  ptime->day   > 31  ||
     709             :        ptime->hour  > 23    ||  ptime->minute > 59 ||
     710             :        ptime->second > 60)
     711             :       return 0;
     712             : 
     713             :    {
     714             :       size_t pos = 0;
     715             :       char number_buf[5]; /* enough for a four-digit year */
     716             : 
     717             : #     define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
     718             : #     define APPEND_NUMBER(format, value)\
     719             :          APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
     720             : #     define APPEND(ch) if (pos < 28) out[pos++] = (ch)
     721             : 
     722             :       APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
     723             :       APPEND(' ');
     724             :       APPEND_STRING(short_months[(ptime->month - 1)]);
     725             :       APPEND(' ');
     726             :       APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
     727             :       APPEND(' ');
     728             :       APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
     729             :       APPEND(':');
     730             :       APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
     731             :       APPEND(':');
     732             :       APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
     733             :       APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
     734             :       PNG_UNUSED (pos)
     735             : 
     736             : #     undef APPEND
     737             : #     undef APPEND_NUMBER
     738             : #     undef APPEND_STRING
     739             :    }
     740             : 
     741             :    return 1;
     742             : }
     743             : 
     744             : #    if PNG_LIBPNG_VER < 10700
     745             : /* To do: remove the following from libpng-1.7 */
     746             : /* Original API that uses a private buffer in png_struct.
     747             :  * Deprecated because it causes png_struct to carry a spurious temporary
     748             :  * buffer (png_struct::time_buffer), better to have the caller pass this in.
     749             :  */
     750             : png_const_charp PNGAPI
     751             : png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
     752             : {
     753             :    if (png_ptr != NULL)
     754             :    {
     755             :       /* The only failure above if png_ptr != NULL is from an invalid ptime */
     756             :       if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
     757             :          png_warning(png_ptr, "Ignoring invalid time value");
     758             : 
     759             :       else
     760             :          return png_ptr->time_buffer;
     761             :    }
     762             : 
     763             :    return NULL;
     764             : }
     765             : #    endif /* LIBPNG_VER < 10700 */
     766             : #  endif /* TIME_RFC1123 */
     767             : 
     768             : #endif /* READ || WRITE */
     769             : 
     770             : png_const_charp PNGAPI
     771           0 : png_get_copyright(png_const_structrp png_ptr)
     772             : {
     773             :    PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
     774             : #ifdef PNG_STRING_COPYRIGHT
     775             :    return PNG_STRING_COPYRIGHT
     776             : #else
     777             : #  ifdef __STDC__
     778           0 :    return PNG_STRING_NEWLINE \
     779             :       "libpng version 1.6.29+apng - March 16, 2017" PNG_STRING_NEWLINE \
     780             :       "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
     781             :       PNG_STRING_NEWLINE \
     782             :       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
     783             :       "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
     784             :       PNG_STRING_NEWLINE \
     785             :       "Portions Copyright (c) 2006-2007 Andrew Smith" PNG_STRING_NEWLINE \
     786             :       "Portions Copyright (c) 2008-2017 Max Stepin" PNG_STRING_NEWLINE ;
     787             : #  else
     788             :    return "libpng version 1.6.29+apng - March 16, 2017\
     789             :       Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
     790             :       Copyright (c) 1996-1997 Andreas Dilger\
     791             :       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\
     792             :       Portions Copyright (c) 2006-2007 Andrew Smith\
     793             :       Portions Copyright (c) 2008-2017 Max Stepin";
     794             : #  endif
     795             : #endif
     796             : }
     797             : 
     798             : /* The following return the library version as a short string in the
     799             :  * format 1.0.0 through 99.99.99zz.  To get the version of *.h files
     800             :  * used with your application, print out PNG_LIBPNG_VER_STRING, which
     801             :  * is defined in png.h.
     802             :  * Note: now there is no difference between png_get_libpng_ver() and
     803             :  * png_get_header_ver().  Due to the version_nn_nn_nn typedef guard,
     804             :  * it is guaranteed that png.c uses the correct version of png.h.
     805             :  */
     806             : png_const_charp PNGAPI
     807           0 : png_get_libpng_ver(png_const_structrp png_ptr)
     808             : {
     809             :    /* Version of *.c files used when building libpng */
     810           0 :    return png_get_header_ver(png_ptr);
     811             : }
     812             : 
     813             : png_const_charp PNGAPI
     814           0 : png_get_header_ver(png_const_structrp png_ptr)
     815             : {
     816             :    /* Version of *.h files used when building libpng */
     817             :    PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
     818           0 :    return PNG_LIBPNG_VER_STRING;
     819             : }
     820             : 
     821             : png_const_charp PNGAPI
     822           0 : png_get_header_version(png_const_structrp png_ptr)
     823             : {
     824             :    /* Returns longer string containing both version and date */
     825             :    PNG_UNUSED(png_ptr)  /* Silence compiler warning about unused png_ptr */
     826             : #ifdef __STDC__
     827           0 :    return PNG_HEADER_VERSION_STRING
     828             : #  ifndef PNG_READ_SUPPORTED
     829             :       " (NO READ SUPPORT)"
     830             : #  endif
     831             :       PNG_STRING_NEWLINE;
     832             : #else
     833             :    return PNG_HEADER_VERSION_STRING;
     834             : #endif
     835             : }
     836             : 
     837             : #ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
     838             : /* NOTE: this routine is not used internally! */
     839             : /* Build a grayscale palette.  Palette is assumed to be 1 << bit_depth
     840             :  * large of png_color.  This lets grayscale images be treated as
     841             :  * paletted.  Most useful for gamma correction and simplification
     842             :  * of code.  This API is not used internally.
     843             :  */
     844             : void PNGAPI
     845             : png_build_grayscale_palette(int bit_depth, png_colorp palette)
     846             : {
     847             :    int num_palette;
     848             :    int color_inc;
     849             :    int i;
     850             :    int v;
     851             : 
     852             :    png_debug(1, "in png_do_build_grayscale_palette");
     853             : 
     854             :    if (palette == NULL)
     855             :       return;
     856             : 
     857             :    switch (bit_depth)
     858             :    {
     859             :       case 1:
     860             :          num_palette = 2;
     861             :          color_inc = 0xff;
     862             :          break;
     863             : 
     864             :       case 2:
     865             :          num_palette = 4;
     866             :          color_inc = 0x55;
     867             :          break;
     868             : 
     869             :       case 4:
     870             :          num_palette = 16;
     871             :          color_inc = 0x11;
     872             :          break;
     873             : 
     874             :       case 8:
     875             :          num_palette = 256;
     876             :          color_inc = 1;
     877             :          break;
     878             : 
     879             :       default:
     880             :          num_palette = 0;
     881             :          color_inc = 0;
     882             :          break;
     883             :    }
     884             : 
     885             :    for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
     886             :    {
     887             :       palette[i].red = (png_byte)(v & 0xff);
     888             :       palette[i].green = (png_byte)(v & 0xff);
     889             :       palette[i].blue = (png_byte)(v & 0xff);
     890             :    }
     891             : }
     892             : #endif
     893             : 
     894             : #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
     895             : int PNGAPI
     896             : png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
     897             : {
     898             :    /* Check chunk_name and return "keep" value if it's on the list, else 0 */
     899             :    png_const_bytep p, p_end;
     900             : 
     901             :    if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
     902             :       return PNG_HANDLE_CHUNK_AS_DEFAULT;
     903             : 
     904             :    p_end = png_ptr->chunk_list;
     905             :    p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
     906             : 
     907             :    /* The code is the fifth byte after each four byte string.  Historically this
     908             :     * code was always searched from the end of the list, this is no longer
     909             :     * necessary because the 'set' routine handles duplicate entries correcty.
     910             :     */
     911             :    do /* num_chunk_list > 0, so at least one */
     912             :    {
     913             :       p -= 5;
     914             : 
     915             :       if (memcmp(chunk_name, p, 4) == 0)
     916             :          return p[4];
     917             :    }
     918             :    while (p > p_end);
     919             : 
     920             :    /* This means that known chunks should be processed and unknown chunks should
     921             :     * be handled according to the value of png_ptr->unknown_default; this can be
     922             :     * confusing because, as a result, there are two levels of defaulting for
     923             :     * unknown chunks.
     924             :     */
     925             :    return PNG_HANDLE_CHUNK_AS_DEFAULT;
     926             : }
     927             : 
     928             : #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
     929             :    defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
     930             : int /* PRIVATE */
     931             : png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
     932             : {
     933             :    png_byte chunk_string[5];
     934             : 
     935             :    PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
     936             :    return png_handle_as_unknown(png_ptr, chunk_string);
     937             : }
     938             : #endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
     939             : #endif /* SET_UNKNOWN_CHUNKS */
     940             : 
     941             : #ifdef PNG_READ_SUPPORTED
     942             : /* This function, added to libpng-1.0.6g, is untested. */
     943             : int PNGAPI
     944           0 : png_reset_zstream(png_structrp png_ptr)
     945             : {
     946           0 :    if (png_ptr == NULL)
     947           0 :       return Z_STREAM_ERROR;
     948             : 
     949             :    /* WARNING: this resets the window bits to the maximum! */
     950           0 :    return (inflateReset(&png_ptr->zstream));
     951             : }
     952             : #endif /* READ */
     953             : 
     954             : /* This function was added to libpng-1.0.7 */
     955             : png_uint_32 PNGAPI
     956           0 : png_access_version_number(void)
     957             : {
     958             :    /* Version of *.c files used when building libpng */
     959           0 :    return((png_uint_32)PNG_LIBPNG_VER);
     960             : }
     961             : 
     962             : #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
     963             : /* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
     964             :  * If it doesn't 'ret' is used to set it to something appropriate, even in cases
     965             :  * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
     966             :  */
     967             : void /* PRIVATE */
     968           0 : png_zstream_error(png_structrp png_ptr, int ret)
     969             : {
     970             :    /* Translate 'ret' into an appropriate error string, priority is given to the
     971             :     * one in zstream if set.  This always returns a string, even in cases like
     972             :     * Z_OK or Z_STREAM_END where the error code is a success code.
     973             :     */
     974           0 :    if (png_ptr->zstream.msg == NULL) switch (ret)
     975             :    {
     976             :       default:
     977             :       case Z_OK:
     978           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
     979           0 :          break;
     980             : 
     981             :       case Z_STREAM_END:
     982             :          /* Normal exit */
     983           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
     984           0 :          break;
     985             : 
     986             :       case Z_NEED_DICT:
     987             :          /* This means the deflate stream did not have a dictionary; this
     988             :           * indicates a bogus PNG.
     989             :           */
     990           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
     991           0 :          break;
     992             : 
     993             :       case Z_ERRNO:
     994             :          /* gz APIs only: should not happen */
     995           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
     996           0 :          break;
     997             : 
     998             :       case Z_STREAM_ERROR:
     999             :          /* internal libpng error */
    1000           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
    1001           0 :          break;
    1002             : 
    1003             :       case Z_DATA_ERROR:
    1004           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
    1005           0 :          break;
    1006             : 
    1007             :       case Z_MEM_ERROR:
    1008           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
    1009           0 :          break;
    1010             : 
    1011             :       case Z_BUF_ERROR:
    1012             :          /* End of input or output; not a problem if the caller is doing
    1013             :           * incremental read or write.
    1014             :           */
    1015           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
    1016           0 :          break;
    1017             : 
    1018             :       case Z_VERSION_ERROR:
    1019           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
    1020           0 :          break;
    1021             : 
    1022             :       case PNG_UNEXPECTED_ZLIB_RETURN:
    1023             :          /* Compile errors here mean that zlib now uses the value co-opted in
    1024             :           * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
    1025             :           * and change pngpriv.h.  Note that this message is "... return",
    1026             :           * whereas the default/Z_OK one is "... return code".
    1027             :           */
    1028           0 :          png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
    1029           0 :          break;
    1030             :    }
    1031           0 : }
    1032             : 
    1033             : /* png_convert_size: a PNGAPI but no longer in png.h, so deleted
    1034             :  * at libpng 1.5.5!
    1035             :  */
    1036             : 
    1037             : /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
    1038             : #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
    1039             : static int
    1040           8 : png_colorspace_check_gamma(png_const_structrp png_ptr,
    1041             :     png_colorspacerp colorspace, png_fixed_point gAMA, int from)
    1042             :    /* This is called to check a new gamma value against an existing one.  The
    1043             :     * routine returns false if the new gamma value should not be written.
    1044             :     *
    1045             :     * 'from' says where the new gamma value comes from:
    1046             :     *
    1047             :     *    0: the new gamma value is the libpng estimate for an ICC profile
    1048             :     *    1: the new gamma value comes from a gAMA chunk
    1049             :     *    2: the new gamma value comes from an sRGB chunk
    1050             :     */
    1051             : {
    1052             :    png_fixed_point gtest;
    1053             : 
    1054           8 :    if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
    1055           0 :        (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0  ||
    1056           0 :       png_gamma_significant(gtest) != 0))
    1057             :    {
    1058             :       /* Either this is an sRGB image, in which case the calculated gamma
    1059             :        * approximation should match, or this is an image with a profile and the
    1060             :        * value libpng calculates for the gamma of the profile does not match the
    1061             :        * value recorded in the file.  The former, sRGB, case is an error, the
    1062             :        * latter is just a warning.
    1063             :        */
    1064           0 :       if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
    1065             :       {
    1066           0 :          png_chunk_report(png_ptr, "gamma value does not match sRGB",
    1067             :              PNG_CHUNK_ERROR);
    1068             :          /* Do not overwrite an sRGB value */
    1069           0 :          return from == 2;
    1070             :       }
    1071             : 
    1072             :       else /* sRGB tag not involved */
    1073             :       {
    1074           0 :          png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
    1075             :              PNG_CHUNK_WARNING);
    1076           0 :          return from == 1;
    1077             :       }
    1078             :    }
    1079             : 
    1080           8 :    return 1;
    1081             : }
    1082             : 
    1083             : void /* PRIVATE */
    1084           0 : png_colorspace_set_gamma(png_const_structrp png_ptr,
    1085             :     png_colorspacerp colorspace, png_fixed_point gAMA)
    1086             : {
    1087             :    /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
    1088             :     * occur.  Since the fixed point representation is asymetrical it is
    1089             :     * possible for 1/gamma to overflow the limit of 21474 and this means the
    1090             :     * gamma value must be at least 5/100000 and hence at most 20000.0.  For
    1091             :     * safety the limits here are a little narrower.  The values are 0.00016 to
    1092             :     * 6250.0, which are truly ridiculous gamma values (and will produce
    1093             :     * displays that are all black or all white.)
    1094             :     *
    1095             :     * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
    1096             :     * handling code, which only required the value to be >0.
    1097             :     */
    1098             :    png_const_charp errmsg;
    1099             : 
    1100           0 :    if (gAMA < 16 || gAMA > 625000000)
    1101           0 :       errmsg = "gamma value out of range";
    1102             : 
    1103             : #  ifdef PNG_READ_gAMA_SUPPORTED
    1104             :    /* Allow the application to set the gamma value more than once */
    1105           0 :    else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
    1106           0 :       (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
    1107           0 :       errmsg = "duplicate";
    1108             : #  endif
    1109             : 
    1110             :    /* Do nothing if the colorspace is already invalid */
    1111           0 :    else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
    1112           0 :       return;
    1113             : 
    1114             :    else
    1115             :    {
    1116           0 :       if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
    1117             :           1/*from gAMA*/) != 0)
    1118             :       {
    1119             :          /* Store this gamma value. */
    1120           0 :          colorspace->gamma = gAMA;
    1121           0 :          colorspace->flags |=
    1122             :             (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
    1123             :       }
    1124             : 
    1125             :       /* At present if the check_gamma test fails the gamma of the colorspace is
    1126             :        * not updated however the colorspace is not invalidated.  This
    1127             :        * corresponds to the case where the existing gamma comes from an sRGB
    1128             :        * chunk or profile.  An error message has already been output.
    1129             :        */
    1130           0 :       return;
    1131             :    }
    1132             : 
    1133             :    /* Error exit - errmsg has been set. */
    1134           0 :    colorspace->flags |= PNG_COLORSPACE_INVALID;
    1135           0 :    png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
    1136             : }
    1137             : 
    1138             : void /* PRIVATE */
    1139           8 : png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
    1140             : {
    1141           8 :    if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
    1142             :    {
    1143             :       /* Everything is invalid */
    1144           0 :       info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
    1145             :          PNG_INFO_iCCP);
    1146             : 
    1147             : #     ifdef PNG_COLORSPACE_SUPPORTED
    1148             :       /* Clean up the iCCP profile now if it won't be used. */
    1149           0 :       png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
    1150             : #     else
    1151             :       PNG_UNUSED(png_ptr)
    1152             : #     endif
    1153             :    }
    1154             : 
    1155             :    else
    1156             :    {
    1157             : #     ifdef PNG_COLORSPACE_SUPPORTED
    1158             :       /* Leave the INFO_iCCP flag set if the pngset.c code has already set
    1159             :        * it; this allows a PNG to contain a profile which matches sRGB and
    1160             :        * yet still have that profile retrievable by the application.
    1161             :        */
    1162           8 :       if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
    1163           8 :          info_ptr->valid |= PNG_INFO_sRGB;
    1164             : 
    1165             :       else
    1166           0 :          info_ptr->valid &= ~PNG_INFO_sRGB;
    1167             : 
    1168           8 :       if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    1169           8 :          info_ptr->valid |= PNG_INFO_cHRM;
    1170             : 
    1171             :       else
    1172           0 :          info_ptr->valid &= ~PNG_INFO_cHRM;
    1173             : #     endif
    1174             : 
    1175           8 :       if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
    1176           8 :          info_ptr->valid |= PNG_INFO_gAMA;
    1177             : 
    1178             :       else
    1179           0 :          info_ptr->valid &= ~PNG_INFO_gAMA;
    1180             :    }
    1181           8 : }
    1182             : 
    1183             : #ifdef PNG_READ_SUPPORTED
    1184             : void /* PRIVATE */
    1185           8 : png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
    1186             : {
    1187           8 :    if (info_ptr == NULL) /* reduce code size; check here not in the caller */
    1188           0 :       return;
    1189             : 
    1190           8 :    info_ptr->colorspace = png_ptr->colorspace;
    1191           8 :    png_colorspace_sync_info(png_ptr, info_ptr);
    1192             : }
    1193             : #endif
    1194             : #endif /* GAMMA */
    1195             : 
    1196             : #ifdef PNG_COLORSPACE_SUPPORTED
    1197             : /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
    1198             :  * cHRM, as opposed to using chromaticities.  These internal APIs return
    1199             :  * non-zero on a parameter error.  The X, Y and Z values are required to be
    1200             :  * positive and less than 1.0.
    1201             :  */
    1202             : static int
    1203           0 : png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
    1204             : {
    1205             :    png_int_32 d, dwhite, whiteX, whiteY;
    1206             : 
    1207           0 :    d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
    1208           0 :    if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
    1209           0 :       return 1;
    1210           0 :    if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
    1211           0 :       return 1;
    1212           0 :    dwhite = d;
    1213           0 :    whiteX = XYZ->red_X;
    1214           0 :    whiteY = XYZ->red_Y;
    1215             : 
    1216           0 :    d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
    1217           0 :    if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
    1218           0 :       return 1;
    1219           0 :    if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
    1220           0 :       return 1;
    1221           0 :    dwhite += d;
    1222           0 :    whiteX += XYZ->green_X;
    1223           0 :    whiteY += XYZ->green_Y;
    1224             : 
    1225           0 :    d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
    1226           0 :    if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
    1227           0 :       return 1;
    1228           0 :    if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
    1229           0 :       return 1;
    1230           0 :    dwhite += d;
    1231           0 :    whiteX += XYZ->blue_X;
    1232           0 :    whiteY += XYZ->blue_Y;
    1233             : 
    1234             :    /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
    1235             :     * thus:
    1236             :     */
    1237           0 :    if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
    1238           0 :       return 1;
    1239           0 :    if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
    1240           0 :       return 1;
    1241             : 
    1242           0 :    return 0;
    1243             : }
    1244             : 
    1245             : static int
    1246           0 : png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
    1247             : {
    1248             :    png_fixed_point red_inverse, green_inverse, blue_scale;
    1249             :    png_fixed_point left, right, denominator;
    1250             : 
    1251             :    /* Check xy and, implicitly, z.  Note that wide gamut color spaces typically
    1252             :     * have end points with 0 tristimulus values (these are impossible end
    1253             :     * points, but they are used to cover the possible colors).  We check
    1254             :     * xy->whitey against 5, not 0, to avoid a possible integer overflow.
    1255             :     */
    1256           0 :    if (xy->redx   < 0 || xy->redx > PNG_FP_1) return 1;
    1257           0 :    if (xy->redy   < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
    1258           0 :    if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
    1259           0 :    if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
    1260           0 :    if (xy->bluex  < 0 || xy->bluex > PNG_FP_1) return 1;
    1261           0 :    if (xy->bluey  < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
    1262           0 :    if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
    1263           0 :    if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
    1264             : 
    1265             :    /* The reverse calculation is more difficult because the original tristimulus
    1266             :     * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
    1267             :     * derived values were recorded in the cHRM chunk;
    1268             :     * (red,green,blue,white)x(x,y).  This loses one degree of freedom and
    1269             :     * therefore an arbitrary ninth value has to be introduced to undo the
    1270             :     * original transformations.
    1271             :     *
    1272             :     * Think of the original end-points as points in (X,Y,Z) space.  The
    1273             :     * chromaticity values (c) have the property:
    1274             :     *
    1275             :     *           C
    1276             :     *   c = ---------
    1277             :     *       X + Y + Z
    1278             :     *
    1279             :     * For each c (x,y,z) from the corresponding original C (X,Y,Z).  Thus the
    1280             :     * three chromaticity values (x,y,z) for each end-point obey the
    1281             :     * relationship:
    1282             :     *
    1283             :     *   x + y + z = 1
    1284             :     *
    1285             :     * This describes the plane in (X,Y,Z) space that intersects each axis at the
    1286             :     * value 1.0; call this the chromaticity plane.  Thus the chromaticity
    1287             :     * calculation has scaled each end-point so that it is on the x+y+z=1 plane
    1288             :     * and chromaticity is the intersection of the vector from the origin to the
    1289             :     * (X,Y,Z) value with the chromaticity plane.
    1290             :     *
    1291             :     * To fully invert the chromaticity calculation we would need the three
    1292             :     * end-point scale factors, (red-scale, green-scale, blue-scale), but these
    1293             :     * were not recorded.  Instead we calculated the reference white (X,Y,Z) and
    1294             :     * recorded the chromaticity of this.  The reference white (X,Y,Z) would have
    1295             :     * given all three of the scale factors since:
    1296             :     *
    1297             :     *    color-C = color-c * color-scale
    1298             :     *    white-C = red-C + green-C + blue-C
    1299             :     *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
    1300             :     *
    1301             :     * But cHRM records only white-x and white-y, so we have lost the white scale
    1302             :     * factor:
    1303             :     *
    1304             :     *    white-C = white-c*white-scale
    1305             :     *
    1306             :     * To handle this the inverse transformation makes an arbitrary assumption
    1307             :     * about white-scale:
    1308             :     *
    1309             :     *    Assume: white-Y = 1.0
    1310             :     *    Hence:  white-scale = 1/white-y
    1311             :     *    Or:     red-Y + green-Y + blue-Y = 1.0
    1312             :     *
    1313             :     * Notice the last statement of the assumption gives an equation in three of
    1314             :     * the nine values we want to calculate.  8 more equations come from the
    1315             :     * above routine as summarised at the top above (the chromaticity
    1316             :     * calculation):
    1317             :     *
    1318             :     *    Given: color-x = color-X / (color-X + color-Y + color-Z)
    1319             :     *    Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
    1320             :     *
    1321             :     * This is 9 simultaneous equations in the 9 variables "color-C" and can be
    1322             :     * solved by Cramer's rule.  Cramer's rule requires calculating 10 9x9 matrix
    1323             :     * determinants, however this is not as bad as it seems because only 28 of
    1324             :     * the total of 90 terms in the various matrices are non-zero.  Nevertheless
    1325             :     * Cramer's rule is notoriously numerically unstable because the determinant
    1326             :     * calculation involves the difference of large, but similar, numbers.  It is
    1327             :     * difficult to be sure that the calculation is stable for real world values
    1328             :     * and it is certain that it becomes unstable where the end points are close
    1329             :     * together.
    1330             :     *
    1331             :     * So this code uses the perhaps slightly less optimal but more
    1332             :     * understandable and totally obvious approach of calculating color-scale.
    1333             :     *
    1334             :     * This algorithm depends on the precision in white-scale and that is
    1335             :     * (1/white-y), so we can immediately see that as white-y approaches 0 the
    1336             :     * accuracy inherent in the cHRM chunk drops off substantially.
    1337             :     *
    1338             :     * libpng arithmetic: a simple inversion of the above equations
    1339             :     * ------------------------------------------------------------
    1340             :     *
    1341             :     *    white_scale = 1/white-y
    1342             :     *    white-X = white-x * white-scale
    1343             :     *    white-Y = 1.0
    1344             :     *    white-Z = (1 - white-x - white-y) * white_scale
    1345             :     *
    1346             :     *    white-C = red-C + green-C + blue-C
    1347             :     *            = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
    1348             :     *
    1349             :     * This gives us three equations in (red-scale,green-scale,blue-scale) where
    1350             :     * all the coefficients are now known:
    1351             :     *
    1352             :     *    red-x*red-scale + green-x*green-scale + blue-x*blue-scale
    1353             :     *       = white-x/white-y
    1354             :     *    red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
    1355             :     *    red-z*red-scale + green-z*green-scale + blue-z*blue-scale
    1356             :     *       = (1 - white-x - white-y)/white-y
    1357             :     *
    1358             :     * In the last equation color-z is (1 - color-x - color-y) so we can add all
    1359             :     * three equations together to get an alternative third:
    1360             :     *
    1361             :     *    red-scale + green-scale + blue-scale = 1/white-y = white-scale
    1362             :     *
    1363             :     * So now we have a Cramer's rule solution where the determinants are just
    1364             :     * 3x3 - far more tractible.  Unfortunately 3x3 determinants still involve
    1365             :     * multiplication of three coefficients so we can't guarantee to avoid
    1366             :     * overflow in the libpng fixed point representation.  Using Cramer's rule in
    1367             :     * floating point is probably a good choice here, but it's not an option for
    1368             :     * fixed point.  Instead proceed to simplify the first two equations by
    1369             :     * eliminating what is likely to be the largest value, blue-scale:
    1370             :     *
    1371             :     *    blue-scale = white-scale - red-scale - green-scale
    1372             :     *
    1373             :     * Hence:
    1374             :     *
    1375             :     *    (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
    1376             :     *                (white-x - blue-x)*white-scale
    1377             :     *
    1378             :     *    (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
    1379             :     *                1 - blue-y*white-scale
    1380             :     *
    1381             :     * And now we can trivially solve for (red-scale,green-scale):
    1382             :     *
    1383             :     *    green-scale =
    1384             :     *                (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
    1385             :     *                -----------------------------------------------------------
    1386             :     *                                  green-x - blue-x
    1387             :     *
    1388             :     *    red-scale =
    1389             :     *                1 - blue-y*white-scale - (green-y - blue-y) * green-scale
    1390             :     *                ---------------------------------------------------------
    1391             :     *                                  red-y - blue-y
    1392             :     *
    1393             :     * Hence:
    1394             :     *
    1395             :     *    red-scale =
    1396             :     *          ( (green-x - blue-x) * (white-y - blue-y) -
    1397             :     *            (green-y - blue-y) * (white-x - blue-x) ) / white-y
    1398             :     * -------------------------------------------------------------------------
    1399             :     *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
    1400             :     *
    1401             :     *    green-scale =
    1402             :     *          ( (red-y - blue-y) * (white-x - blue-x) -
    1403             :     *            (red-x - blue-x) * (white-y - blue-y) ) / white-y
    1404             :     * -------------------------------------------------------------------------
    1405             :     *  (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
    1406             :     *
    1407             :     * Accuracy:
    1408             :     * The input values have 5 decimal digits of accuracy.  The values are all in
    1409             :     * the range 0 < value < 1, so simple products are in the same range but may
    1410             :     * need up to 10 decimal digits to preserve the original precision and avoid
    1411             :     * underflow.  Because we are using a 32-bit signed representation we cannot
    1412             :     * match this; the best is a little over 9 decimal digits, less than 10.
    1413             :     *
    1414             :     * The approach used here is to preserve the maximum precision within the
    1415             :     * signed representation.  Because the red-scale calculation above uses the
    1416             :     * difference between two products of values that must be in the range -1..+1
    1417             :     * it is sufficient to divide the product by 7; ceil(100,000/32767*2).  The
    1418             :     * factor is irrelevant in the calculation because it is applied to both
    1419             :     * numerator and denominator.
    1420             :     *
    1421             :     * Note that the values of the differences of the products of the
    1422             :     * chromaticities in the above equations tend to be small, for example for
    1423             :     * the sRGB chromaticities they are:
    1424             :     *
    1425             :     * red numerator:    -0.04751
    1426             :     * green numerator:  -0.08788
    1427             :     * denominator:      -0.2241 (without white-y multiplication)
    1428             :     *
    1429             :     *  The resultant Y coefficients from the chromaticities of some widely used
    1430             :     *  color space definitions are (to 15 decimal places):
    1431             :     *
    1432             :     *  sRGB
    1433             :     *    0.212639005871510 0.715168678767756 0.072192315360734
    1434             :     *  Kodak ProPhoto
    1435             :     *    0.288071128229293 0.711843217810102 0.000085653960605
    1436             :     *  Adobe RGB
    1437             :     *    0.297344975250536 0.627363566255466 0.075291458493998
    1438             :     *  Adobe Wide Gamut RGB
    1439             :     *    0.258728243040113 0.724682314948566 0.016589442011321
    1440             :     */
    1441             :    /* By the argument, above overflow should be impossible here. The return
    1442             :     * value of 2 indicates an internal error to the caller.
    1443             :     */
    1444           0 :    if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
    1445           0 :       return 2;
    1446           0 :    if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
    1447           0 :       return 2;
    1448           0 :    denominator = left - right;
    1449             : 
    1450             :    /* Now find the red numerator. */
    1451           0 :    if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
    1452           0 :       return 2;
    1453           0 :    if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
    1454           0 :       return 2;
    1455             : 
    1456             :    /* Overflow is possible here and it indicates an extreme set of PNG cHRM
    1457             :     * chunk values.  This calculation actually returns the reciprocal of the
    1458             :     * scale value because this allows us to delay the multiplication of white-y
    1459             :     * into the denominator, which tends to produce a small number.
    1460             :     */
    1461           0 :    if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
    1462           0 :        red_inverse <= xy->whitey /* r+g+b scales = white scale */)
    1463           0 :       return 1;
    1464             : 
    1465             :    /* Similarly for green_inverse: */
    1466           0 :    if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
    1467           0 :       return 2;
    1468           0 :    if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
    1469           0 :       return 2;
    1470           0 :    if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
    1471           0 :        green_inverse <= xy->whitey)
    1472           0 :       return 1;
    1473             : 
    1474             :    /* And the blue scale, the checks above guarantee this can't overflow but it
    1475             :     * can still produce 0 for extreme cHRM values.
    1476             :     */
    1477           0 :    blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
    1478           0 :        png_reciprocal(green_inverse);
    1479           0 :    if (blue_scale <= 0)
    1480           0 :       return 1;
    1481             : 
    1482             : 
    1483             :    /* And fill in the png_XYZ: */
    1484           0 :    if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
    1485           0 :       return 1;
    1486           0 :    if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
    1487           0 :       return 1;
    1488           0 :    if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
    1489             :        red_inverse) == 0)
    1490           0 :       return 1;
    1491             : 
    1492           0 :    if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
    1493           0 :       return 1;
    1494           0 :    if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
    1495           0 :       return 1;
    1496           0 :    if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
    1497             :        green_inverse) == 0)
    1498           0 :       return 1;
    1499             : 
    1500           0 :    if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
    1501           0 :       return 1;
    1502           0 :    if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
    1503           0 :       return 1;
    1504           0 :    if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
    1505             :        PNG_FP_1) == 0)
    1506           0 :       return 1;
    1507             : 
    1508           0 :    return 0; /*success*/
    1509             : }
    1510             : 
    1511             : static int
    1512           0 : png_XYZ_normalize(png_XYZ *XYZ)
    1513             : {
    1514             :    png_int_32 Y;
    1515             : 
    1516           0 :    if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
    1517           0 :       XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
    1518           0 :       XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
    1519           0 :       return 1;
    1520             : 
    1521             :    /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
    1522             :     * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
    1523             :     * relying on addition of two positive values producing a negative one is not
    1524             :     * safe.
    1525             :     */
    1526           0 :    Y = XYZ->red_Y;
    1527           0 :    if (0x7fffffff - Y < XYZ->green_X)
    1528           0 :       return 1;
    1529           0 :    Y += XYZ->green_Y;
    1530           0 :    if (0x7fffffff - Y < XYZ->blue_X)
    1531           0 :       return 1;
    1532           0 :    Y += XYZ->blue_Y;
    1533             : 
    1534           0 :    if (Y != PNG_FP_1)
    1535             :    {
    1536           0 :       if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
    1537           0 :          return 1;
    1538           0 :       if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
    1539           0 :          return 1;
    1540           0 :       if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
    1541           0 :          return 1;
    1542             : 
    1543           0 :       if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
    1544           0 :          return 1;
    1545           0 :       if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
    1546           0 :          return 1;
    1547           0 :       if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
    1548           0 :          return 1;
    1549             : 
    1550           0 :       if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
    1551           0 :          return 1;
    1552           0 :       if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
    1553           0 :          return 1;
    1554           0 :       if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
    1555           0 :          return 1;
    1556             :    }
    1557             : 
    1558           0 :    return 0;
    1559             : }
    1560             : 
    1561             : static int
    1562           0 : png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
    1563             : {
    1564             :    /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
    1565           0 :    if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
    1566           0 :        PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
    1567           0 :        PNG_OUT_OF_RANGE(xy1->redx,   xy2->redx,  delta) ||
    1568           0 :        PNG_OUT_OF_RANGE(xy1->redy,   xy2->redy,  delta) ||
    1569           0 :        PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
    1570           0 :        PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
    1571           0 :        PNG_OUT_OF_RANGE(xy1->bluex,  xy2->bluex, delta) ||
    1572           0 :        PNG_OUT_OF_RANGE(xy1->bluey,  xy2->bluey, delta))
    1573           0 :       return 0;
    1574           0 :    return 1;
    1575             : }
    1576             : 
    1577             : /* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
    1578             :  * chunk chromaticities.  Earlier checks used to simply look for the overflow
    1579             :  * condition (where the determinant of the matrix to solve for XYZ ends up zero
    1580             :  * because the chromaticity values are not all distinct.)  Despite this it is
    1581             :  * theoretically possible to produce chromaticities that are apparently valid
    1582             :  * but that rapidly degrade to invalid, potentially crashing, sets because of
    1583             :  * arithmetic inaccuracies when calculations are performed on them.  The new
    1584             :  * check is to round-trip xy -> XYZ -> xy and then check that the result is
    1585             :  * within a small percentage of the original.
    1586             :  */
    1587             : static int
    1588           0 : png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
    1589             : {
    1590             :    int result;
    1591             :    png_xy xy_test;
    1592             : 
    1593             :    /* As a side-effect this routine also returns the XYZ endpoints. */
    1594           0 :    result = png_XYZ_from_xy(XYZ, xy);
    1595           0 :    if (result != 0)
    1596           0 :       return result;
    1597             : 
    1598           0 :    result = png_xy_from_XYZ(&xy_test, XYZ);
    1599           0 :    if (result != 0)
    1600           0 :       return result;
    1601             : 
    1602           0 :    if (png_colorspace_endpoints_match(xy, &xy_test,
    1603             :        5/*actually, the math is pretty accurate*/) != 0)
    1604           0 :       return 0;
    1605             : 
    1606             :    /* Too much slip */
    1607           0 :    return 1;
    1608             : }
    1609             : 
    1610             : /* This is the check going the other way.  The XYZ is modified to normalize it
    1611             :  * (another side-effect) and the xy chromaticities are returned.
    1612             :  */
    1613             : static int
    1614           0 : png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
    1615             : {
    1616             :    int result;
    1617             :    png_XYZ XYZtemp;
    1618             : 
    1619           0 :    result = png_XYZ_normalize(XYZ);
    1620           0 :    if (result != 0)
    1621           0 :       return result;
    1622             : 
    1623           0 :    result = png_xy_from_XYZ(xy, XYZ);
    1624           0 :    if (result != 0)
    1625           0 :       return result;
    1626             : 
    1627           0 :    XYZtemp = *XYZ;
    1628           0 :    return png_colorspace_check_xy(&XYZtemp, xy);
    1629             : }
    1630             : 
    1631             : /* Used to check for an endpoint match against sRGB */
    1632             : static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
    1633             : {
    1634             :    /* color      x       y */
    1635             :    /* red   */ 64000, 33000,
    1636             :    /* green */ 30000, 60000,
    1637             :    /* blue  */ 15000,  6000,
    1638             :    /* white */ 31270, 32900
    1639             : };
    1640             : 
    1641             : static int
    1642           0 : png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
    1643             :     png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
    1644             :     int preferred)
    1645             : {
    1646           0 :    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
    1647           0 :       return 0;
    1648             : 
    1649             :    /* The consistency check is performed on the chromaticities; this factors out
    1650             :     * variations because of the normalization (or not) of the end point Y
    1651             :     * values.
    1652             :     */
    1653           0 :    if (preferred < 2 &&
    1654           0 :        (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    1655             :    {
    1656             :       /* The end points must be reasonably close to any we already have.  The
    1657             :        * following allows an error of up to +/-.001
    1658             :        */
    1659           0 :       if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
    1660             :           100) == 0)
    1661             :       {
    1662           0 :          colorspace->flags |= PNG_COLORSPACE_INVALID;
    1663           0 :          png_benign_error(png_ptr, "inconsistent chromaticities");
    1664           0 :          return 0; /* failed */
    1665             :       }
    1666             : 
    1667             :       /* Only overwrite with preferred values */
    1668           0 :       if (preferred == 0)
    1669           0 :          return 1; /* ok, but no change */
    1670             :    }
    1671             : 
    1672           0 :    colorspace->end_points_xy = *xy;
    1673           0 :    colorspace->end_points_XYZ = *XYZ;
    1674           0 :    colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
    1675             : 
    1676             :    /* The end points are normally quoted to two decimal digits, so allow +/-0.01
    1677             :     * on this test.
    1678             :     */
    1679           0 :    if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
    1680           0 :       colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
    1681             : 
    1682             :    else
    1683           0 :       colorspace->flags &= PNG_COLORSPACE_CANCEL(
    1684             :          PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
    1685             : 
    1686           0 :    return 2; /* ok and changed */
    1687             : }
    1688             : 
    1689             : int /* PRIVATE */
    1690           0 : png_colorspace_set_chromaticities(png_const_structrp png_ptr,
    1691             :     png_colorspacerp colorspace, const png_xy *xy, int preferred)
    1692             : {
    1693             :    /* We must check the end points to ensure they are reasonable - in the past
    1694             :     * color management systems have crashed as a result of getting bogus
    1695             :     * colorant values, while this isn't the fault of libpng it is the
    1696             :     * responsibility of libpng because PNG carries the bomb and libpng is in a
    1697             :     * position to protect against it.
    1698             :     */
    1699             :    png_XYZ XYZ;
    1700             : 
    1701           0 :    switch (png_colorspace_check_xy(&XYZ, xy))
    1702             :    {
    1703             :       case 0: /* success */
    1704           0 :          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
    1705             :              preferred);
    1706             : 
    1707             :       case 1:
    1708             :          /* We can't invert the chromaticities so we can't produce value XYZ
    1709             :           * values.  Likely as not a color management system will fail too.
    1710             :           */
    1711           0 :          colorspace->flags |= PNG_COLORSPACE_INVALID;
    1712           0 :          png_benign_error(png_ptr, "invalid chromaticities");
    1713           0 :          break;
    1714             : 
    1715             :       default:
    1716             :          /* libpng is broken; this should be a warning but if it happens we
    1717             :           * want error reports so for the moment it is an error.
    1718             :           */
    1719           0 :          colorspace->flags |= PNG_COLORSPACE_INVALID;
    1720           0 :          png_error(png_ptr, "internal error checking chromaticities");
    1721             :    }
    1722             : 
    1723           0 :    return 0; /* failed */
    1724             : }
    1725             : 
    1726             : int /* PRIVATE */
    1727           0 : png_colorspace_set_endpoints(png_const_structrp png_ptr,
    1728             :     png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
    1729             : {
    1730           0 :    png_XYZ XYZ = *XYZ_in;
    1731             :    png_xy xy;
    1732             : 
    1733           0 :    switch (png_colorspace_check_XYZ(&xy, &XYZ))
    1734             :    {
    1735             :       case 0:
    1736           0 :          return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
    1737             :              preferred);
    1738             : 
    1739             :       case 1:
    1740             :          /* End points are invalid. */
    1741           0 :          colorspace->flags |= PNG_COLORSPACE_INVALID;
    1742           0 :          png_benign_error(png_ptr, "invalid end points");
    1743           0 :          break;
    1744             : 
    1745             :       default:
    1746           0 :          colorspace->flags |= PNG_COLORSPACE_INVALID;
    1747           0 :          png_error(png_ptr, "internal error checking chromaticities");
    1748             :    }
    1749             : 
    1750           0 :    return 0; /* failed */
    1751             : }
    1752             : 
    1753             : #if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
    1754             : /* Error message generation */
    1755             : static char
    1756           0 : png_icc_tag_char(png_uint_32 byte)
    1757             : {
    1758           0 :    byte &= 0xff;
    1759           0 :    if (byte >= 32 && byte <= 126)
    1760           0 :       return (char)byte;
    1761             :    else
    1762           0 :       return '?';
    1763             : }
    1764             : 
    1765             : static void
    1766           0 : png_icc_tag_name(char *name, png_uint_32 tag)
    1767             : {
    1768           0 :    name[0] = '\'';
    1769           0 :    name[1] = png_icc_tag_char(tag >> 24);
    1770           0 :    name[2] = png_icc_tag_char(tag >> 16);
    1771           0 :    name[3] = png_icc_tag_char(tag >>  8);
    1772           0 :    name[4] = png_icc_tag_char(tag      );
    1773           0 :    name[5] = '\'';
    1774           0 : }
    1775             : 
    1776             : static int
    1777           0 : is_ICC_signature_char(png_alloc_size_t it)
    1778             : {
    1779           0 :    return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
    1780           0 :       (it >= 97 && it <= 122);
    1781             : }
    1782             : 
    1783             : static int
    1784           0 : is_ICC_signature(png_alloc_size_t it)
    1785             : {
    1786           0 :    return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
    1787           0 :       is_ICC_signature_char((it >> 16) & 0xff) &&
    1788           0 :       is_ICC_signature_char((it >> 8) & 0xff) &&
    1789           0 :       is_ICC_signature_char(it & 0xff);
    1790             : }
    1791             : 
    1792             : static int
    1793           0 : png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
    1794             :     png_const_charp name, png_alloc_size_t value, png_const_charp reason)
    1795             : {
    1796             :    size_t pos;
    1797             :    char message[196]; /* see below for calculation */
    1798             : 
    1799           0 :    if (colorspace != NULL)
    1800           0 :       colorspace->flags |= PNG_COLORSPACE_INVALID;
    1801             : 
    1802           0 :    pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
    1803           0 :    pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
    1804           0 :    pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
    1805           0 :    if (is_ICC_signature(value) != 0)
    1806             :    {
    1807             :       /* So 'value' is at most 4 bytes and the following cast is safe */
    1808           0 :       png_icc_tag_name(message+pos, (png_uint_32)value);
    1809           0 :       pos += 6; /* total +8; less than the else clause */
    1810           0 :       message[pos++] = ':';
    1811           0 :       message[pos++] = ' ';
    1812             :    }
    1813             : #  ifdef PNG_WARNINGS_SUPPORTED
    1814             :    else
    1815             :       {
    1816             :          char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
    1817             : 
    1818           0 :          pos = png_safecat(message, (sizeof message), pos,
    1819           0 :              png_format_number(number, number+(sizeof number),
    1820             :              PNG_NUMBER_FORMAT_x, value));
    1821           0 :          pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
    1822             :       }
    1823             : #  endif
    1824             :    /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
    1825           0 :    pos = png_safecat(message, (sizeof message), pos, reason);
    1826             :    PNG_UNUSED(pos)
    1827             : 
    1828             :    /* This is recoverable, but make it unconditionally an app_error on write to
    1829             :     * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
    1830             :     * on read, with a warning, but on write unless the app turns off
    1831             :     * application errors the PNG won't be written.)
    1832             :     */
    1833           0 :    png_chunk_report(png_ptr, message,
    1834             :        (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
    1835             : 
    1836           0 :    return 0;
    1837             : }
    1838             : #endif /* sRGB || iCCP */
    1839             : 
    1840             : #ifdef PNG_sRGB_SUPPORTED
    1841             : int /* PRIVATE */
    1842           8 : png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
    1843             :     int intent)
    1844             : {
    1845             :    /* sRGB sets known gamma, end points and (from the chunk) intent. */
    1846             :    /* IMPORTANT: these are not necessarily the values found in an ICC profile
    1847             :     * because ICC profiles store values adapted to a D50 environment; it is
    1848             :     * expected that the ICC profile mediaWhitePointTag will be D50; see the
    1849             :     * checks and code elsewhere to understand this better.
    1850             :     *
    1851             :     * These XYZ values, which are accurate to 5dp, produce rgb to gray
    1852             :     * coefficients of (6968,23435,2366), which are reduced (because they add up
    1853             :     * to 32769 not 32768) to (6968,23434,2366).  These are the values that
    1854             :     * libpng has traditionally used (and are the best values given the 15bit
    1855             :     * algorithm used by the rgb to gray code.)
    1856             :     */
    1857             :    static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
    1858             :    {
    1859             :       /* color      X      Y      Z */
    1860             :       /* red   */ 41239, 21264,  1933,
    1861             :       /* green */ 35758, 71517, 11919,
    1862             :       /* blue  */ 18048,  7219, 95053
    1863             :    };
    1864             : 
    1865             :    /* Do nothing if the colorspace is already invalidated. */
    1866           8 :    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
    1867           0 :       return 0;
    1868             : 
    1869             :    /* Check the intent, then check for existing settings.  It is valid for the
    1870             :     * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
    1871             :     * be consistent with the correct values.  If, however, this function is
    1872             :     * called below because an iCCP chunk matches sRGB then it is quite
    1873             :     * conceivable that an older app recorded incorrect gAMA and cHRM because of
    1874             :     * an incorrect calculation based on the values in the profile - this does
    1875             :     * *not* invalidate the profile (though it still produces an error, which can
    1876             :     * be ignored.)
    1877             :     */
    1878           8 :    if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
    1879           0 :       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
    1880           0 :           (unsigned)intent, "invalid sRGB rendering intent");
    1881             : 
    1882           8 :    if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
    1883           0 :        colorspace->rendering_intent != intent)
    1884           0 :       return png_icc_profile_error(png_ptr, colorspace, "sRGB",
    1885           0 :          (unsigned)intent, "inconsistent rendering intents");
    1886             : 
    1887           8 :    if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
    1888             :    {
    1889           0 :       png_benign_error(png_ptr, "duplicate sRGB information ignored");
    1890           0 :       return 0;
    1891             :    }
    1892             : 
    1893             :    /* If the standard sRGB cHRM chunk does not match the one from the PNG file
    1894             :     * warn but overwrite the value with the correct one.
    1895             :     */
    1896           8 :    if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
    1897           0 :        !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
    1898             :        100))
    1899           0 :       png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
    1900             :          PNG_CHUNK_ERROR);
    1901             : 
    1902             :    /* This check is just done for the error reporting - the routine always
    1903             :     * returns true when the 'from' argument corresponds to sRGB (2).
    1904             :     */
    1905           8 :    (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
    1906             :        2/*from sRGB*/);
    1907             : 
    1908             :    /* intent: bugs in GCC force 'int' to be used as the parameter type. */
    1909           8 :    colorspace->rendering_intent = (png_uint_16)intent;
    1910           8 :    colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
    1911             : 
    1912             :    /* endpoints */
    1913           8 :    colorspace->end_points_xy = sRGB_xy;
    1914           8 :    colorspace->end_points_XYZ = sRGB_XYZ;
    1915           8 :    colorspace->flags |=
    1916             :       (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
    1917             : 
    1918             :    /* gamma */
    1919           8 :    colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
    1920           8 :    colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
    1921             : 
    1922             :    /* Finally record that we have an sRGB profile */
    1923           8 :    colorspace->flags |=
    1924             :       (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
    1925             : 
    1926           8 :    return 1; /* set */
    1927             : }
    1928             : #endif /* sRGB */
    1929             : 
    1930             : #ifdef PNG_iCCP_SUPPORTED
    1931             : /* Encoded value of D50 as an ICC XYZNumber.  From the ICC 2010 spec the value
    1932             :  * is XYZ(0.9642,1.0,0.8249), which scales to:
    1933             :  *
    1934             :  *    (63189.8112, 65536, 54060.6464)
    1935             :  */
    1936             : static const png_byte D50_nCIEXYZ[12] =
    1937             :    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
    1938             : 
    1939             : static int /* bool */
    1940           0 : icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    1941             :     png_const_charp name, png_uint_32 profile_length)
    1942             : {
    1943           0 :    if (profile_length < 132)
    1944           0 :       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    1945             :           "too short");
    1946             : 
    1947           0 :    return 1;
    1948             : }
    1949             : 
    1950             : #ifdef PNG_READ_iCCP_SUPPORTED
    1951             : int /* PRIVATE */
    1952           0 : png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    1953             :     png_const_charp name, png_uint_32 profile_length)
    1954             : {
    1955           0 :    if (!icc_check_length(png_ptr, colorspace, name, profile_length))
    1956           0 :       return 0;
    1957             : 
    1958             :    /* This needs to be here because the 'normal' check is in
    1959             :     * png_decompress_chunk, yet this happens after the attempt to
    1960             :     * png_malloc_base the required data.  We only need this on read; on write
    1961             :     * the caller supplies the profile buffer so libpng doesn't allocate it.  See
    1962             :     * the call to icc_check_length below (the write case).
    1963             :     */
    1964             : #  ifdef PNG_SET_USER_LIMITS_SUPPORTED
    1965           0 :       else if (png_ptr->user_chunk_malloc_max > 0 &&
    1966           0 :                png_ptr->user_chunk_malloc_max < profile_length)
    1967           0 :          return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    1968             :              "exceeds application limits");
    1969             : #  elif PNG_USER_CHUNK_MALLOC_MAX > 0
    1970             :       else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
    1971             :          return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    1972             :              "exceeds libpng limits");
    1973             : #  else /* !SET_USER_LIMITS */
    1974             :       /* This will get compiled out on all 32-bit and better systems. */
    1975             :       else if (PNG_SIZE_MAX < profile_length)
    1976             :          return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    1977             :              "exceeds system limits");
    1978             : #  endif /* !SET_USER_LIMITS */
    1979             : 
    1980           0 :    return 1;
    1981             : }
    1982             : #endif /* READ_iCCP */
    1983             : 
    1984             : int /* PRIVATE */
    1985           0 : png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    1986             :     png_const_charp name, png_uint_32 profile_length,
    1987             :     png_const_bytep profile/* first 132 bytes only */, int color_type)
    1988             : {
    1989             :    png_uint_32 temp;
    1990             : 
    1991             :    /* Length check; this cannot be ignored in this code because profile_length
    1992             :     * is used later to check the tag table, so even if the profile seems over
    1993             :     * long profile_length from the caller must be correct.  The caller can fix
    1994             :     * this up on read or write by just passing in the profile header length.
    1995             :     */
    1996           0 :    temp = png_get_uint_32(profile);
    1997           0 :    if (temp != profile_length)
    1998           0 :       return png_icc_profile_error(png_ptr, colorspace, name, temp,
    1999             :           "length does not match profile");
    2000             : 
    2001           0 :    temp = (png_uint_32) (*(profile+8));
    2002           0 :    if (temp > 3 && (profile_length & 3))
    2003           0 :       return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
    2004             :           "invalid length");
    2005             : 
    2006           0 :    temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
    2007           0 :    if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
    2008           0 :       profile_length < 132+12*temp) /* truncated tag table */
    2009           0 :       return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2010             :           "tag count too large");
    2011             : 
    2012             :    /* The 'intent' must be valid or we can't store it, ICC limits the intent to
    2013             :     * 16 bits.
    2014             :     */
    2015           0 :    temp = png_get_uint_32(profile+64);
    2016           0 :    if (temp >= 0xffff) /* The ICC limit */
    2017           0 :       return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2018             :           "invalid rendering intent");
    2019             : 
    2020             :    /* This is just a warning because the profile may be valid in future
    2021             :     * versions.
    2022             :     */
    2023           0 :    if (temp >= PNG_sRGB_INTENT_LAST)
    2024           0 :       (void)png_icc_profile_error(png_ptr, NULL, name, temp,
    2025             :           "intent outside defined range");
    2026             : 
    2027             :    /* At this point the tag table can't be checked because it hasn't necessarily
    2028             :     * been loaded; however, various header fields can be checked.  These checks
    2029             :     * are for values permitted by the PNG spec in an ICC profile; the PNG spec
    2030             :     * restricts the profiles that can be passed in an iCCP chunk (they must be
    2031             :     * appropriate to processing PNG data!)
    2032             :     */
    2033             : 
    2034             :    /* Data checks (could be skipped).  These checks must be independent of the
    2035             :     * version number; however, the version number doesn't accomodate changes in
    2036             :     * the header fields (just the known tags and the interpretation of the
    2037             :     * data.)
    2038             :     */
    2039           0 :    temp = png_get_uint_32(profile+36); /* signature 'ascp' */
    2040           0 :    if (temp != 0x61637370)
    2041           0 :       return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2042             :           "invalid signature");
    2043             : 
    2044             :    /* Currently the PCS illuminant/adopted white point (the computational
    2045             :     * white point) are required to be D50,
    2046             :     * however the profile contains a record of the illuminant so perhaps ICC
    2047             :     * expects to be able to change this in the future (despite the rationale in
    2048             :     * the introduction for using a fixed PCS adopted white.)  Consequently the
    2049             :     * following is just a warning.
    2050             :     */
    2051           0 :    if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
    2052           0 :       (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
    2053             :           "PCS illuminant is not D50");
    2054             : 
    2055             :    /* The PNG spec requires this:
    2056             :     * "If the iCCP chunk is present, the image samples conform to the colour
    2057             :     * space represented by the embedded ICC profile as defined by the
    2058             :     * International Color Consortium [ICC]. The colour space of the ICC profile
    2059             :     * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
    2060             :     * 6), or a greyscale colour space for greyscale images (PNG colour types 0
    2061             :     * and 4)."
    2062             :     *
    2063             :     * This checking code ensures the embedded profile (on either read or write)
    2064             :     * conforms to the specification requirements.  Notice that an ICC 'gray'
    2065             :     * color-space profile contains the information to transform the monochrome
    2066             :     * data to XYZ or L*a*b (according to which PCS the profile uses) and this
    2067             :     * should be used in preference to the standard libpng K channel replication
    2068             :     * into R, G and B channels.
    2069             :     *
    2070             :     * Previously it was suggested that an RGB profile on grayscale data could be
    2071             :     * handled.  However it it is clear that using an RGB profile in this context
    2072             :     * must be an error - there is no specification of what it means.  Thus it is
    2073             :     * almost certainly more correct to ignore the profile.
    2074             :     */
    2075           0 :    temp = png_get_uint_32(profile+16); /* data colour space field */
    2076           0 :    switch (temp)
    2077             :    {
    2078             :       case 0x52474220: /* 'RGB ' */
    2079           0 :          if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
    2080           0 :             return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2081             :                 "RGB color space not permitted on grayscale PNG");
    2082           0 :          break;
    2083             : 
    2084             :       case 0x47524159: /* 'GRAY' */
    2085           0 :          if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
    2086           0 :             return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2087             :                 "Gray color space not permitted on RGB PNG");
    2088           0 :          break;
    2089             : 
    2090             :       default:
    2091           0 :          return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2092             :              "invalid ICC profile color space");
    2093             :    }
    2094             : 
    2095             :    /* It is up to the application to check that the profile class matches the
    2096             :     * application requirements; the spec provides no guidance, but it's pretty
    2097             :     * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
    2098             :     * ('prtr') or 'spac' (for generic color spaces).  Issue a warning in these
    2099             :     * cases.  Issue an error for device link or abstract profiles - these don't
    2100             :     * contain the records necessary to transform the color-space to anything
    2101             :     * other than the target device (and not even that for an abstract profile).
    2102             :     * Profiles of these classes may not be embedded in images.
    2103             :     */
    2104           0 :    temp = png_get_uint_32(profile+12); /* profile/device class */
    2105           0 :    switch (temp)
    2106             :    {
    2107             :       case 0x73636e72: /* 'scnr' */
    2108             :       case 0x6d6e7472: /* 'mntr' */
    2109             :       case 0x70727472: /* 'prtr' */
    2110             :       case 0x73706163: /* 'spac' */
    2111             :          /* All supported */
    2112           0 :          break;
    2113             : 
    2114             :       case 0x61627374: /* 'abst' */
    2115             :          /* May not be embedded in an image */
    2116           0 :          return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2117             :              "invalid embedded Abstract ICC profile");
    2118             : 
    2119             :       case 0x6c696e6b: /* 'link' */
    2120             :          /* DeviceLink profiles cannot be interpreted in a non-device specific
    2121             :           * fashion, if an app uses the AToB0Tag in the profile the results are
    2122             :           * undefined unless the result is sent to the intended device,
    2123             :           * therefore a DeviceLink profile should not be found embedded in a
    2124             :           * PNG.
    2125             :           */
    2126           0 :          return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2127             :              "unexpected DeviceLink ICC profile class");
    2128             : 
    2129             :       case 0x6e6d636c: /* 'nmcl' */
    2130             :          /* A NamedColor profile is also device specific, however it doesn't
    2131             :           * contain an AToB0 tag that is open to misinterpretation.  Almost
    2132             :           * certainly it will fail the tests below.
    2133             :           */
    2134           0 :          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
    2135             :              "unexpected NamedColor ICC profile class");
    2136           0 :          break;
    2137             : 
    2138             :       default:
    2139             :          /* To allow for future enhancements to the profile accept unrecognized
    2140             :           * profile classes with a warning, these then hit the test below on the
    2141             :           * tag content to ensure they are backward compatible with one of the
    2142             :           * understood profiles.
    2143             :           */
    2144           0 :          (void)png_icc_profile_error(png_ptr, NULL, name, temp,
    2145             :              "unrecognized ICC profile class");
    2146           0 :          break;
    2147             :    }
    2148             : 
    2149             :    /* For any profile other than a device link one the PCS must be encoded
    2150             :     * either in XYZ or Lab.
    2151             :     */
    2152           0 :    temp = png_get_uint_32(profile+20);
    2153           0 :    switch (temp)
    2154             :    {
    2155             :       case 0x58595a20: /* 'XYZ ' */
    2156             :       case 0x4c616220: /* 'Lab ' */
    2157           0 :          break;
    2158             : 
    2159             :       default:
    2160           0 :          return png_icc_profile_error(png_ptr, colorspace, name, temp,
    2161             :              "unexpected ICC PCS encoding");
    2162             :    }
    2163             : 
    2164           0 :    return 1;
    2165             : }
    2166             : 
    2167             : int /* PRIVATE */
    2168           0 : png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
    2169             :     png_const_charp name, png_uint_32 profile_length,
    2170             :     png_const_bytep profile /* header plus whole tag table */)
    2171             : {
    2172           0 :    png_uint_32 tag_count = png_get_uint_32(profile+128);
    2173             :    png_uint_32 itag;
    2174           0 :    png_const_bytep tag = profile+132; /* The first tag */
    2175             : 
    2176             :    /* First scan all the tags in the table and add bits to the icc_info value
    2177             :     * (temporarily in 'tags').
    2178             :     */
    2179           0 :    for (itag=0; itag < tag_count; ++itag, tag += 12)
    2180             :    {
    2181           0 :       png_uint_32 tag_id = png_get_uint_32(tag+0);
    2182           0 :       png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
    2183           0 :       png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
    2184             : 
    2185             :       /* The ICC specification does not exclude zero length tags, therefore the
    2186             :        * start might actually be anywhere if there is no data, but this would be
    2187             :        * a clear abuse of the intent of the standard so the start is checked for
    2188             :        * being in range.  All defined tag types have an 8 byte header - a 4 byte
    2189             :        * type signature then 0.
    2190             :        */
    2191           0 :       if ((tag_start & 3) != 0)
    2192             :       {
    2193             :          /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
    2194             :           * only a warning here because libpng does not care about the
    2195             :           * alignment.
    2196             :           */
    2197           0 :          (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
    2198             :              "ICC profile tag start not a multiple of 4");
    2199             :       }
    2200             : 
    2201             :       /* This is a hard error; potentially it can cause read outside the
    2202             :        * profile.
    2203             :        */
    2204           0 :       if (tag_start > profile_length || tag_length > profile_length - tag_start)
    2205           0 :          return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
    2206             :              "ICC profile tag outside profile");
    2207             :    }
    2208             : 
    2209           0 :    return 1; /* success, maybe with warnings */
    2210             : }
    2211             : 
    2212             : #ifdef PNG_sRGB_SUPPORTED
    2213             : #if PNG_sRGB_PROFILE_CHECKS >= 0
    2214             : /* Information about the known ICC sRGB profiles */
    2215             : static const struct
    2216             : {
    2217             :    png_uint_32 adler, crc, length;
    2218             :    png_uint_32 md5[4];
    2219             :    png_byte    have_md5;
    2220             :    png_byte    is_broken;
    2221             :    png_uint_16 intent;
    2222             : 
    2223             : #  define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
    2224             : #  define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
    2225             :       { adler, crc, length, md5, broke, intent },
    2226             : 
    2227             : } png_sRGB_checks[] =
    2228             : {
    2229             :    /* This data comes from contrib/tools/checksum-icc run on downloads of
    2230             :     * all four ICC sRGB profiles from www.color.org.
    2231             :     */
    2232             :    /* adler32, crc32, MD5[4], intent, date, length, file-name */
    2233             :    PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
    2234             :        PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
    2235             :        "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
    2236             : 
    2237             :    /* ICC sRGB v2 perceptual no black-compensation: */
    2238             :    PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
    2239             :        PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
    2240             :        "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
    2241             : 
    2242             :    PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
    2243             :        PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
    2244             :        "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
    2245             : 
    2246             :    /* ICC sRGB v4 perceptual */
    2247             :    PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
    2248             :        PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
    2249             :        "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
    2250             : 
    2251             :    /* The following profiles have no known MD5 checksum. If there is a match
    2252             :     * on the (empty) MD5 the other fields are used to attempt a match and
    2253             :     * a warning is produced.  The first two of these profiles have a 'cprt' tag
    2254             :     * which suggests that they were also made by Hewlett Packard.
    2255             :     */
    2256             :    PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
    2257             :        PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
    2258             :        "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
    2259             : 
    2260             :    /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
    2261             :     * match the D50 PCS illuminant in the header (it is in fact the D65 values,
    2262             :     * so the white point is recorded as the un-adapted value.)  The profiles
    2263             :     * below only differ in one byte - the intent - and are basically the same as
    2264             :     * the previous profile except for the mediaWhitePointTag error and a missing
    2265             :     * chromaticAdaptationTag.
    2266             :     */
    2267             :    PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
    2268             :        PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
    2269             :        "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
    2270             : 
    2271             :    PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
    2272             :        PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
    2273             :        "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
    2274             : };
    2275             : 
    2276             : static int
    2277             : png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
    2278             :     png_const_bytep profile, uLong adler)
    2279             : {
    2280             :    /* The quick check is to verify just the MD5 signature and trust the
    2281             :     * rest of the data.  Because the profile has already been verified for
    2282             :     * correctness this is safe.  png_colorspace_set_sRGB will check the 'intent'
    2283             :     * field too, so if the profile has been edited with an intent not defined
    2284             :     * by sRGB (but maybe defined by a later ICC specification) the read of
    2285             :     * the profile will fail at that point.
    2286             :     */
    2287             : 
    2288             :    png_uint_32 length = 0;
    2289             :    png_uint_32 intent = 0x10000; /* invalid */
    2290             : #if PNG_sRGB_PROFILE_CHECKS > 1
    2291             :    uLong crc = 0; /* the value for 0 length data */
    2292             : #endif
    2293             :    unsigned int i;
    2294             : 
    2295             : #ifdef PNG_SET_OPTION_SUPPORTED
    2296             :    /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
    2297             :    if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
    2298             :                PNG_OPTION_ON)
    2299             :       return 0;
    2300             : #endif
    2301             : 
    2302             :    for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
    2303             :    {
    2304             :       if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
    2305             :          png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
    2306             :          png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
    2307             :          png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
    2308             :       {
    2309             :          /* This may be one of the old HP profiles without an MD5, in that
    2310             :           * case we can only use the length and Adler32 (note that these
    2311             :           * are not used by default if there is an MD5!)
    2312             :           */
    2313             : #        if PNG_sRGB_PROFILE_CHECKS == 0
    2314             :             if (png_sRGB_checks[i].have_md5 != 0)
    2315             :                return 1+png_sRGB_checks[i].is_broken;
    2316             : #        endif
    2317             : 
    2318             :          /* Profile is unsigned or more checks have been configured in. */
    2319             :          if (length == 0)
    2320             :          {
    2321             :             length = png_get_uint_32(profile);
    2322             :             intent = png_get_uint_32(profile+64);
    2323             :          }
    2324             : 
    2325             :          /* Length *and* intent must match */
    2326             :          if (length == (png_uint_32) png_sRGB_checks[i].length &&
    2327             :             intent == (png_uint_32) png_sRGB_checks[i].intent)
    2328             :          {
    2329             :             /* Now calculate the adler32 if not done already. */
    2330             :             if (adler == 0)
    2331             :             {
    2332             :                adler = adler32(0, NULL, 0);
    2333             :                adler = adler32(adler, profile, length);
    2334             :             }
    2335             : 
    2336             :             if (adler == png_sRGB_checks[i].adler)
    2337             :             {
    2338             :                /* These basic checks suggest that the data has not been
    2339             :                 * modified, but if the check level is more than 1 perform
    2340             :                 * our own crc32 checksum on the data.
    2341             :                 */
    2342             : #              if PNG_sRGB_PROFILE_CHECKS > 1
    2343             :                   if (crc == 0)
    2344             :                   {
    2345             :                      crc = crc32(0, NULL, 0);
    2346             :                      crc = crc32(crc, profile, length);
    2347             :                   }
    2348             : 
    2349             :                   /* So this check must pass for the 'return' below to happen.
    2350             :                    */
    2351             :                   if (crc == png_sRGB_checks[i].crc)
    2352             : #              endif
    2353             :                {
    2354             :                   if (png_sRGB_checks[i].is_broken != 0)
    2355             :                   {
    2356             :                      /* These profiles are known to have bad data that may cause
    2357             :                       * problems if they are used, therefore attempt to
    2358             :                       * discourage their use, skip the 'have_md5' warning below,
    2359             :                       * which is made irrelevant by this error.
    2360             :                       */
    2361             :                      png_chunk_report(png_ptr, "known incorrect sRGB profile",
    2362             :                          PNG_CHUNK_ERROR);
    2363             :                   }
    2364             : 
    2365             :                   /* Warn that this being done; this isn't even an error since
    2366             :                    * the profile is perfectly valid, but it would be nice if
    2367             :                    * people used the up-to-date ones.
    2368             :                    */
    2369             :                   else if (png_sRGB_checks[i].have_md5 == 0)
    2370             :                   {
    2371             :                      png_chunk_report(png_ptr,
    2372             :                          "out-of-date sRGB profile with no signature",
    2373             :                          PNG_CHUNK_WARNING);
    2374             :                   }
    2375             : 
    2376             :                   return 1+png_sRGB_checks[i].is_broken;
    2377             :                }
    2378             :             }
    2379             : 
    2380             : # if PNG_sRGB_PROFILE_CHECKS > 0
    2381             :          /* The signature matched, but the profile had been changed in some
    2382             :           * way.  This probably indicates a data error or uninformed hacking.
    2383             :           * Fall through to "no match".
    2384             :           */
    2385             :          png_chunk_report(png_ptr,
    2386             :              "Not recognizing known sRGB profile that has been edited",
    2387             :              PNG_CHUNK_WARNING);
    2388             :          break;
    2389             : # endif
    2390             :          }
    2391             :       }
    2392             :    }
    2393             : 
    2394             :    return 0; /* no match */
    2395             : }
    2396             : 
    2397             : void /* PRIVATE */
    2398             : png_icc_set_sRGB(png_const_structrp png_ptr,
    2399             :     png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
    2400             : {
    2401             :    /* Is this profile one of the known ICC sRGB profiles?  If it is, just set
    2402             :     * the sRGB information.
    2403             :     */
    2404             :    if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
    2405             :       (void)png_colorspace_set_sRGB(png_ptr, colorspace,
    2406             :          (int)/*already checked*/png_get_uint_32(profile+64));
    2407             : }
    2408             : #endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
    2409             : #endif /* sRGB */
    2410             : 
    2411             : int /* PRIVATE */
    2412           0 : png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
    2413             :     png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
    2414             :     int color_type)
    2415             : {
    2416           0 :    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
    2417           0 :       return 0;
    2418             : 
    2419           0 :    if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
    2420           0 :        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
    2421           0 :            color_type) != 0 &&
    2422           0 :        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
    2423             :            profile) != 0)
    2424             :    {
    2425             : #     if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
    2426             :          /* If no sRGB support, don't try storing sRGB information */
    2427             :          png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
    2428             : #     endif
    2429           0 :       return 1;
    2430             :    }
    2431             : 
    2432             :    /* Failure case */
    2433           0 :    return 0;
    2434             : }
    2435             : #endif /* iCCP */
    2436             : 
    2437             : #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
    2438             : void /* PRIVATE */
    2439             : png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
    2440             : {
    2441             :    /* Set the rgb_to_gray coefficients from the colorspace. */
    2442             :    if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
    2443             :       (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
    2444             :    {
    2445             :       /* png_set_background has not been called, get the coefficients from the Y
    2446             :        * values of the colorspace colorants.
    2447             :        */
    2448             :       png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
    2449             :       png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
    2450             :       png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
    2451             :       png_fixed_point total = r+g+b;
    2452             : 
    2453             :       if (total > 0 &&
    2454             :          r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
    2455             :          g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
    2456             :          b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
    2457             :          r+g+b <= 32769)
    2458             :       {
    2459             :          /* We allow 0 coefficients here.  r+g+b may be 32769 if two or
    2460             :           * all of the coefficients were rounded up.  Handle this by
    2461             :           * reducing the *largest* coefficient by 1; this matches the
    2462             :           * approach used for the default coefficients in pngrtran.c
    2463             :           */
    2464             :          int add = 0;
    2465             : 
    2466             :          if (r+g+b > 32768)
    2467             :             add = -1;
    2468             :          else if (r+g+b < 32768)
    2469             :             add = 1;
    2470             : 
    2471             :          if (add != 0)
    2472             :          {
    2473             :             if (g >= r && g >= b)
    2474             :                g += add;
    2475             :             else if (r >= g && r >= b)
    2476             :                r += add;
    2477             :             else
    2478             :                b += add;
    2479             :          }
    2480             : 
    2481             :          /* Check for an internal error. */
    2482             :          if (r+g+b != 32768)
    2483             :             png_error(png_ptr,
    2484             :                 "internal error handling cHRM coefficients");
    2485             : 
    2486             :          else
    2487             :          {
    2488             :             png_ptr->rgb_to_gray_red_coeff   = (png_uint_16)r;
    2489             :             png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
    2490             :          }
    2491             :       }
    2492             : 
    2493             :       /* This is a png_error at present even though it could be ignored -
    2494             :        * it should never happen, but it is important that if it does, the
    2495             :        * bug is fixed.
    2496             :        */
    2497             :       else
    2498             :          png_error(png_ptr, "internal error handling cHRM->XYZ");
    2499             :    }
    2500             : }
    2501             : #endif /* READ_RGB_TO_GRAY */
    2502             : 
    2503             : #endif /* COLORSPACE */
    2504             : 
    2505             : #ifdef __GNUC__
    2506             : /* This exists solely to work round a warning from GNU C. */
    2507             : static int /* PRIVATE */
    2508          62 : png_gt(size_t a, size_t b)
    2509             : {
    2510          62 :    return a > b;
    2511             : }
    2512             : #else
    2513             : #   define png_gt(a,b) ((a) > (b))
    2514             : #endif
    2515             : 
    2516             : void /* PRIVATE */
    2517          62 : png_check_IHDR(png_const_structrp png_ptr,
    2518             :     png_uint_32 width, png_uint_32 height, int bit_depth,
    2519             :     int color_type, int interlace_type, int compression_type,
    2520             :     int filter_type)
    2521             : {
    2522          62 :    int error = 0;
    2523             : 
    2524             :    /* Check for width and height valid values */
    2525          62 :    if (width == 0)
    2526             :    {
    2527           0 :       png_warning(png_ptr, "Image width is zero in IHDR");
    2528           0 :       error = 1;
    2529             :    }
    2530             : 
    2531          62 :    if (width > PNG_UINT_31_MAX)
    2532             :    {
    2533           0 :       png_warning(png_ptr, "Invalid image width in IHDR");
    2534           0 :       error = 1;
    2535             :    }
    2536             : 
    2537          62 :    if (png_gt(((width + 7) & (~7U)),
    2538             :        ((PNG_SIZE_MAX
    2539             :            - 48        /* big_row_buf hack */
    2540             :            - 1)        /* filter byte */
    2541             :            / 8)        /* 8-byte RGBA pixels */
    2542             :            - 1))       /* extra max_pixel_depth pad */
    2543             :    {
    2544             :       /* The size of the row must be within the limits of this architecture.
    2545             :        * Because the read code can perform arbitrary transformations the
    2546             :        * maximum size is checked here.  Because the code in png_read_start_row
    2547             :        * adds extra space "for safety's sake" in several places a conservative
    2548             :        * limit is used here.
    2549             :        *
    2550             :        * NOTE: it would be far better to check the size that is actually used,
    2551             :        * but the effect in the real world is minor and the changes are more
    2552             :        * extensive, therefore much more dangerous and much more difficult to
    2553             :        * write in a way that avoids compiler warnings.
    2554             :        */
    2555           0 :       png_warning(png_ptr, "Image width is too large for this architecture");
    2556           0 :       error = 1;
    2557             :    }
    2558             : 
    2559             : #ifdef PNG_SET_USER_LIMITS_SUPPORTED
    2560          62 :    if (width > png_ptr->user_width_max)
    2561             : #else
    2562             :    if (width > PNG_USER_WIDTH_MAX)
    2563             : #endif
    2564             :    {
    2565           0 :       png_warning(png_ptr, "Image width exceeds user limit in IHDR");
    2566           0 :       error = 1;
    2567             :    }
    2568             : 
    2569          62 :    if (height == 0)
    2570             :    {
    2571           0 :       png_warning(png_ptr, "Image height is zero in IHDR");
    2572           0 :       error = 1;
    2573             :    }
    2574             : 
    2575          62 :    if (height > PNG_UINT_31_MAX)
    2576             :    {
    2577           0 :       png_warning(png_ptr, "Invalid image height in IHDR");
    2578           0 :       error = 1;
    2579             :    }
    2580             : 
    2581             : #ifdef PNG_SET_USER_LIMITS_SUPPORTED
    2582          62 :    if (height > png_ptr->user_height_max)
    2583             : #else
    2584             :    if (height > PNG_USER_HEIGHT_MAX)
    2585             : #endif
    2586             :    {
    2587           0 :       png_warning(png_ptr, "Image height exceeds user limit in IHDR");
    2588           0 :       error = 1;
    2589             :    }
    2590             : 
    2591             :    /* Check other values */
    2592          62 :    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
    2593           0 :        bit_depth != 8 && bit_depth != 16)
    2594             :    {
    2595           0 :       png_warning(png_ptr, "Invalid bit depth in IHDR");
    2596           0 :       error = 1;
    2597             :    }
    2598             : 
    2599          62 :    if (color_type < 0 || color_type == 1 ||
    2600          62 :        color_type == 5 || color_type > 6)
    2601             :    {
    2602           0 :       png_warning(png_ptr, "Invalid color type in IHDR");
    2603           0 :       error = 1;
    2604             :    }
    2605             : 
    2606          62 :    if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
    2607          62 :        ((color_type == PNG_COLOR_TYPE_RGB ||
    2608          54 :          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
    2609          58 :          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
    2610             :    {
    2611           0 :       png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
    2612           0 :       error = 1;
    2613             :    }
    2614             : 
    2615          62 :    if (interlace_type >= PNG_INTERLACE_LAST)
    2616             :    {
    2617           0 :       png_warning(png_ptr, "Unknown interlace method in IHDR");
    2618           0 :       error = 1;
    2619             :    }
    2620             : 
    2621          62 :    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
    2622             :    {
    2623           0 :       png_warning(png_ptr, "Unknown compression method in IHDR");
    2624           0 :       error = 1;
    2625             :    }
    2626             : 
    2627             : #ifdef PNG_MNG_FEATURES_SUPPORTED
    2628             :    /* Accept filter_method 64 (intrapixel differencing) only if
    2629             :     * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
    2630             :     * 2. Libpng did not read a PNG signature (this filter_method is only
    2631             :     *    used in PNG datastreams that are embedded in MNG datastreams) and
    2632             :     * 3. The application called png_permit_mng_features with a mask that
    2633             :     *    included PNG_FLAG_MNG_FILTER_64 and
    2634             :     * 4. The filter_method is 64 and
    2635             :     * 5. The color_type is RGB or RGBA
    2636             :     */
    2637             :    if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
    2638             :        png_ptr->mng_features_permitted != 0)
    2639             :       png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
    2640             : 
    2641             :    if (filter_type != PNG_FILTER_TYPE_BASE)
    2642             :    {
    2643             :       if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
    2644             :           (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
    2645             :           ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
    2646             :           (color_type == PNG_COLOR_TYPE_RGB ||
    2647             :           color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
    2648             :       {
    2649             :          png_warning(png_ptr, "Unknown filter method in IHDR");
    2650             :          error = 1;
    2651             :       }
    2652             : 
    2653             :       if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
    2654             :       {
    2655             :          png_warning(png_ptr, "Invalid filter method in IHDR");
    2656             :          error = 1;
    2657             :       }
    2658             :    }
    2659             : 
    2660             : #else
    2661          62 :    if (filter_type != PNG_FILTER_TYPE_BASE)
    2662             :    {
    2663           0 :       png_warning(png_ptr, "Unknown filter method in IHDR");
    2664           0 :       error = 1;
    2665             :    }
    2666             : #endif
    2667             : 
    2668          62 :    if (error == 1)
    2669           0 :       png_error(png_ptr, "Invalid IHDR data");
    2670          62 : }
    2671             : 
    2672             : #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
    2673             : /* ASCII to fp functions */
    2674             : /* Check an ASCII formated floating point value, see the more detailed
    2675             :  * comments in pngpriv.h
    2676             :  */
    2677             : /* The following is used internally to preserve the sticky flags */
    2678             : #define png_fp_add(state, flags) ((state) |= (flags))
    2679             : #define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
    2680             : 
    2681             : int /* PRIVATE */
    2682             : png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
    2683             :     png_size_tp whereami)
    2684             : {
    2685             :    int state = *statep;
    2686             :    png_size_t i = *whereami;
    2687             : 
    2688             :    while (i < size)
    2689             :    {
    2690             :       int type;
    2691             :       /* First find the type of the next character */
    2692             :       switch (string[i])
    2693             :       {
    2694             :       case 43:  type = PNG_FP_SAW_SIGN;                   break;
    2695             :       case 45:  type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
    2696             :       case 46:  type = PNG_FP_SAW_DOT;                    break;
    2697             :       case 48:  type = PNG_FP_SAW_DIGIT;                  break;
    2698             :       case 49: case 50: case 51: case 52:
    2699             :       case 53: case 54: case 55: case 56:
    2700             :       case 57:  type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
    2701             :       case 69:
    2702             :       case 101: type = PNG_FP_SAW_E;                      break;
    2703             :       default:  goto PNG_FP_End;
    2704             :       }
    2705             : 
    2706             :       /* Now deal with this type according to the current
    2707             :        * state, the type is arranged to not overlap the
    2708             :        * bits of the PNG_FP_STATE.
    2709             :        */
    2710             :       switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
    2711             :       {
    2712             :       case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
    2713             :          if ((state & PNG_FP_SAW_ANY) != 0)
    2714             :             goto PNG_FP_End; /* not a part of the number */
    2715             : 
    2716             :          png_fp_add(state, type);
    2717             :          break;
    2718             : 
    2719             :       case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
    2720             :          /* Ok as trailer, ok as lead of fraction. */
    2721             :          if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
    2722             :             goto PNG_FP_End;
    2723             : 
    2724             :          else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
    2725             :             png_fp_add(state, type);
    2726             : 
    2727             :          else
    2728             :             png_fp_set(state, PNG_FP_FRACTION | type);
    2729             : 
    2730             :          break;
    2731             : 
    2732             :       case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
    2733             :          if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
    2734             :             png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
    2735             : 
    2736             :          png_fp_add(state, type | PNG_FP_WAS_VALID);
    2737             : 
    2738             :          break;
    2739             : 
    2740             :       case PNG_FP_INTEGER + PNG_FP_SAW_E:
    2741             :          if ((state & PNG_FP_SAW_DIGIT) == 0)
    2742             :             goto PNG_FP_End;
    2743             : 
    2744             :          png_fp_set(state, PNG_FP_EXPONENT);
    2745             : 
    2746             :          break;
    2747             : 
    2748             :    /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
    2749             :          goto PNG_FP_End; ** no sign in fraction */
    2750             : 
    2751             :    /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
    2752             :          goto PNG_FP_End; ** Because SAW_DOT is always set */
    2753             : 
    2754             :       case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
    2755             :          png_fp_add(state, type | PNG_FP_WAS_VALID);
    2756             :          break;
    2757             : 
    2758             :       case PNG_FP_FRACTION + PNG_FP_SAW_E:
    2759             :          /* This is correct because the trailing '.' on an
    2760             :           * integer is handled above - so we can only get here
    2761             :           * with the sequence ".E" (with no preceding digits).
    2762             :           */
    2763             :          if ((state & PNG_FP_SAW_DIGIT) == 0)
    2764             :             goto PNG_FP_End;
    2765             : 
    2766             :          png_fp_set(state, PNG_FP_EXPONENT);
    2767             : 
    2768             :          break;
    2769             : 
    2770             :       case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
    2771             :          if ((state & PNG_FP_SAW_ANY) != 0)
    2772             :             goto PNG_FP_End; /* not a part of the number */
    2773             : 
    2774             :          png_fp_add(state, PNG_FP_SAW_SIGN);
    2775             : 
    2776             :          break;
    2777             : 
    2778             :    /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
    2779             :          goto PNG_FP_End; */
    2780             : 
    2781             :       case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
    2782             :          png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
    2783             : 
    2784             :          break;
    2785             : 
    2786             :    /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
    2787             :          goto PNG_FP_End; */
    2788             : 
    2789             :       default: goto PNG_FP_End; /* I.e. break 2 */
    2790             :       }
    2791             : 
    2792             :       /* The character seems ok, continue. */
    2793             :       ++i;
    2794             :    }
    2795             : 
    2796             : PNG_FP_End:
    2797             :    /* Here at the end, update the state and return the correct
    2798             :     * return code.
    2799             :     */
    2800             :    *statep = state;
    2801             :    *whereami = i;
    2802             : 
    2803             :    return (state & PNG_FP_SAW_DIGIT) != 0;
    2804             : }
    2805             : 
    2806             : 
    2807             : /* The same but for a complete string. */
    2808             : int
    2809             : png_check_fp_string(png_const_charp string, png_size_t size)
    2810             : {
    2811             :    int        state=0;
    2812             :    png_size_t char_index=0;
    2813             : 
    2814             :    if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
    2815             :       (char_index == size || string[char_index] == 0))
    2816             :       return state /* must be non-zero - see above */;
    2817             : 
    2818             :    return 0; /* i.e. fail */
    2819             : }
    2820             : #endif /* pCAL || sCAL */
    2821             : 
    2822             : #ifdef PNG_sCAL_SUPPORTED
    2823             : #  ifdef PNG_FLOATING_POINT_SUPPORTED
    2824             : /* Utility used below - a simple accurate power of ten from an integral
    2825             :  * exponent.
    2826             :  */
    2827             : static double
    2828             : png_pow10(int power)
    2829             : {
    2830             :    int recip = 0;
    2831             :    double d = 1;
    2832             : 
    2833             :    /* Handle negative exponent with a reciprocal at the end because
    2834             :     * 10 is exact whereas .1 is inexact in base 2
    2835             :     */
    2836             :    if (power < 0)
    2837             :    {
    2838             :       if (power < DBL_MIN_10_EXP) return 0;
    2839             :       recip = 1, power = -power;
    2840             :    }
    2841             : 
    2842             :    if (power > 0)
    2843             :    {
    2844             :       /* Decompose power bitwise. */
    2845             :       double mult = 10;
    2846             :       do
    2847             :       {
    2848             :          if (power & 1) d *= mult;
    2849             :          mult *= mult;
    2850             :          power >>= 1;
    2851             :       }
    2852             :       while (power > 0);
    2853             : 
    2854             :       if (recip != 0) d = 1/d;
    2855             :    }
    2856             :    /* else power is 0 and d is 1 */
    2857             : 
    2858             :    return d;
    2859             : }
    2860             : 
    2861             : /* Function to format a floating point value in ASCII with a given
    2862             :  * precision.
    2863             :  */
    2864             : void /* PRIVATE */
    2865             : png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
    2866             :     double fp, unsigned int precision)
    2867             : {
    2868             :    /* We use standard functions from math.h, but not printf because
    2869             :     * that would require stdio.  The caller must supply a buffer of
    2870             :     * sufficient size or we will png_error.  The tests on size and
    2871             :     * the space in ascii[] consumed are indicated below.
    2872             :     */
    2873             :    if (precision < 1)
    2874             :       precision = DBL_DIG;
    2875             : 
    2876             :    /* Enforce the limit of the implementation precision too. */
    2877             :    if (precision > DBL_DIG+1)
    2878             :       precision = DBL_DIG+1;
    2879             : 
    2880             :    /* Basic sanity checks */
    2881             :    if (size >= precision+5) /* See the requirements below. */
    2882             :    {
    2883             :       if (fp < 0)
    2884             :       {
    2885             :          fp = -fp;
    2886             :          *ascii++ = 45; /* '-'  PLUS 1 TOTAL 1 */
    2887             :          --size;
    2888             :       }
    2889             : 
    2890             :       if (fp >= DBL_MIN && fp <= DBL_MAX)
    2891             :       {
    2892             :          int exp_b10;   /* A base 10 exponent */
    2893             :          double base;   /* 10^exp_b10 */
    2894             : 
    2895             :          /* First extract a base 10 exponent of the number,
    2896             :           * the calculation below rounds down when converting
    2897             :           * from base 2 to base 10 (multiply by log10(2) -
    2898             :           * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
    2899             :           * be increased.  Note that the arithmetic shift
    2900             :           * performs a floor() unlike C arithmetic - using a
    2901             :           * C multiply would break the following for negative
    2902             :           * exponents.
    2903             :           */
    2904             :          (void)frexp(fp, &exp_b10); /* exponent to base 2 */
    2905             : 
    2906             :          exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
    2907             : 
    2908             :          /* Avoid underflow here. */
    2909             :          base = png_pow10(exp_b10); /* May underflow */
    2910             : 
    2911             :          while (base < DBL_MIN || base < fp)
    2912             :          {
    2913             :             /* And this may overflow. */
    2914             :             double test = png_pow10(exp_b10+1);
    2915             : 
    2916             :             if (test <= DBL_MAX)
    2917             :                ++exp_b10, base = test;
    2918             : 
    2919             :             else
    2920             :                break;
    2921             :          }
    2922             : 
    2923             :          /* Normalize fp and correct exp_b10, after this fp is in the
    2924             :           * range [.1,1) and exp_b10 is both the exponent and the digit
    2925             :           * *before* which the decimal point should be inserted
    2926             :           * (starting with 0 for the first digit).  Note that this
    2927             :           * works even if 10^exp_b10 is out of range because of the
    2928             :           * test on DBL_MAX above.
    2929             :           */
    2930             :          fp /= base;
    2931             :          while (fp >= 1) fp /= 10, ++exp_b10;
    2932             : 
    2933             :          /* Because of the code above fp may, at this point, be
    2934             :           * less than .1, this is ok because the code below can
    2935             :           * handle the leading zeros this generates, so no attempt
    2936             :           * is made to correct that here.
    2937             :           */
    2938             : 
    2939             :          {
    2940             :             unsigned int czero, clead, cdigits;
    2941             :             char exponent[10];
    2942             : 
    2943             :             /* Allow up to two leading zeros - this will not lengthen
    2944             :              * the number compared to using E-n.
    2945             :              */
    2946             :             if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
    2947             :             {
    2948             :                czero = (unsigned int)(-exp_b10); /* PLUS 2 digits: TOTAL 3 */
    2949             :                exp_b10 = 0;      /* Dot added below before first output. */
    2950             :             }
    2951             :             else
    2952             :                czero = 0;    /* No zeros to add */
    2953             : 
    2954             :             /* Generate the digit list, stripping trailing zeros and
    2955             :              * inserting a '.' before a digit if the exponent is 0.
    2956             :              */
    2957             :             clead = czero; /* Count of leading zeros */
    2958             :             cdigits = 0;   /* Count of digits in list. */
    2959             : 
    2960             :             do
    2961             :             {
    2962             :                double d;
    2963             : 
    2964             :                fp *= 10;
    2965             :                /* Use modf here, not floor and subtract, so that
    2966             :                 * the separation is done in one step.  At the end
    2967             :                 * of the loop don't break the number into parts so
    2968             :                 * that the final digit is rounded.
    2969             :                 */
    2970             :                if (cdigits+czero+1 < precision+clead)
    2971             :                   fp = modf(fp, &d);
    2972             : 
    2973             :                else
    2974             :                {
    2975             :                   d = floor(fp + .5);
    2976             : 
    2977             :                   if (d > 9)
    2978             :                   {
    2979             :                      /* Rounding up to 10, handle that here. */
    2980             :                      if (czero > 0)
    2981             :                      {
    2982             :                         --czero, d = 1;
    2983             :                         if (cdigits == 0) --clead;
    2984             :                      }
    2985             :                      else
    2986             :                      {
    2987             :                         while (cdigits > 0 && d > 9)
    2988             :                         {
    2989             :                            int ch = *--ascii;
    2990             : 
    2991             :                            if (exp_b10 != (-1))
    2992             :                               ++exp_b10;
    2993             : 
    2994             :                            else if (ch == 46)
    2995             :                            {
    2996             :                               ch = *--ascii, ++size;
    2997             :                               /* Advance exp_b10 to '1', so that the
    2998             :                                * decimal point happens after the
    2999             :                                * previous digit.
    3000             :                                */
    3001             :                               exp_b10 = 1;
    3002             :                            }
    3003             : 
    3004             :                            --cdigits;
    3005             :                            d = ch - 47;  /* I.e. 1+(ch-48) */
    3006             :                         }
    3007             : 
    3008             :                         /* Did we reach the beginning? If so adjust the
    3009             :                          * exponent but take into account the leading
    3010             :                          * decimal point.
    3011             :                          */
    3012             :                         if (d > 9)  /* cdigits == 0 */
    3013             :                         {
    3014             :                            if (exp_b10 == (-1))
    3015             :                            {
    3016             :                               /* Leading decimal point (plus zeros?), if
    3017             :                                * we lose the decimal point here it must
    3018             :                                * be reentered below.
    3019             :                                */
    3020             :                               int ch = *--ascii;
    3021             : 
    3022             :                               if (ch == 46)
    3023             :                                  ++size, exp_b10 = 1;
    3024             : 
    3025             :                               /* Else lost a leading zero, so 'exp_b10' is
    3026             :                                * still ok at (-1)
    3027             :                                */
    3028             :                            }
    3029             :                            else
    3030             :                               ++exp_b10;
    3031             : 
    3032             :                            /* In all cases we output a '1' */
    3033             :                            d = 1;
    3034             :                         }
    3035             :                      }
    3036             :                   }
    3037             :                   fp = 0; /* Guarantees termination below. */
    3038             :                }
    3039             : 
    3040             :                if (d == 0)
    3041             :                {
    3042             :                   ++czero;
    3043             :                   if (cdigits == 0) ++clead;
    3044             :                }
    3045             :                else
    3046             :                {
    3047             :                   /* Included embedded zeros in the digit count. */
    3048             :                   cdigits += czero - clead;
    3049             :                   clead = 0;
    3050             : 
    3051             :                   while (czero > 0)
    3052             :                   {
    3053             :                      /* exp_b10 == (-1) means we just output the decimal
    3054             :                       * place - after the DP don't adjust 'exp_b10' any
    3055             :                       * more!
    3056             :                       */
    3057             :                      if (exp_b10 != (-1))
    3058             :                      {
    3059             :                         if (exp_b10 == 0) *ascii++ = 46, --size;
    3060             :                         /* PLUS 1: TOTAL 4 */
    3061             :                         --exp_b10;
    3062             :                      }
    3063             :                      *ascii++ = 48, --czero;
    3064             :                   }
    3065             : 
    3066             :                   if (exp_b10 != (-1))
    3067             :                   {
    3068             :                      if (exp_b10 == 0)
    3069             :                         *ascii++ = 46, --size; /* counted above */
    3070             : 
    3071             :                      --exp_b10;
    3072             :                   }
    3073             :                   *ascii++ = (char)(48 + (int)d), ++cdigits;
    3074             :                }
    3075             :             }
    3076             :             while (cdigits+czero < precision+clead && fp > DBL_MIN);
    3077             : 
    3078             :             /* The total output count (max) is now 4+precision */
    3079             : 
    3080             :             /* Check for an exponent, if we don't need one we are
    3081             :              * done and just need to terminate the string.  At
    3082             :              * this point exp_b10==(-1) is effectively if flag - it got
    3083             :              * to '-1' because of the decrement after outputting
    3084             :              * the decimal point above (the exponent required is
    3085             :              * *not* -1!)
    3086             :              */
    3087             :             if (exp_b10 >= (-1) && exp_b10 <= 2)
    3088             :             {
    3089             :                /* The following only happens if we didn't output the
    3090             :                 * leading zeros above for negative exponent, so this
    3091             :                 * doesn't add to the digit requirement.  Note that the
    3092             :                 * two zeros here can only be output if the two leading
    3093             :                 * zeros were *not* output, so this doesn't increase
    3094             :                 * the output count.
    3095             :                 */
    3096             :                while (--exp_b10 >= 0) *ascii++ = 48;
    3097             : 
    3098             :                *ascii = 0;
    3099             : 
    3100             :                /* Total buffer requirement (including the '\0') is
    3101             :                 * 5+precision - see check at the start.
    3102             :                 */
    3103             :                return;
    3104             :             }
    3105             : 
    3106             :             /* Here if an exponent is required, adjust size for
    3107             :              * the digits we output but did not count.  The total
    3108             :              * digit output here so far is at most 1+precision - no
    3109             :              * decimal point and no leading or trailing zeros have
    3110             :              * been output.
    3111             :              */
    3112             :             size -= cdigits;
    3113             : 
    3114             :             *ascii++ = 69, --size;    /* 'E': PLUS 1 TOTAL 2+precision */
    3115             : 
    3116             :             /* The following use of an unsigned temporary avoids ambiguities in
    3117             :              * the signed arithmetic on exp_b10 and permits GCC at least to do
    3118             :              * better optimization.
    3119             :              */
    3120             :             {
    3121             :                unsigned int uexp_b10;
    3122             : 
    3123             :                if (exp_b10 < 0)
    3124             :                {
    3125             :                   *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
    3126             :                   uexp_b10 = (unsigned int)(-exp_b10);
    3127             :                }
    3128             : 
    3129             :                else
    3130             :                   uexp_b10 = (unsigned int)exp_b10;
    3131             : 
    3132             :                cdigits = 0;
    3133             : 
    3134             :                while (uexp_b10 > 0)
    3135             :                {
    3136             :                   exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
    3137             :                   uexp_b10 /= 10;
    3138             :                }
    3139             :             }
    3140             : 
    3141             :             /* Need another size check here for the exponent digits, so
    3142             :              * this need not be considered above.
    3143             :              */
    3144             :             if (size > cdigits)
    3145             :             {
    3146             :                while (cdigits > 0) *ascii++ = exponent[--cdigits];
    3147             : 
    3148             :                *ascii = 0;
    3149             : 
    3150             :                return;
    3151             :             }
    3152             :          }
    3153             :       }
    3154             :       else if (!(fp >= DBL_MIN))
    3155             :       {
    3156             :          *ascii++ = 48; /* '0' */
    3157             :          *ascii = 0;
    3158             :          return;
    3159             :       }
    3160             :       else
    3161             :       {
    3162             :          *ascii++ = 105; /* 'i' */
    3163             :          *ascii++ = 110; /* 'n' */
    3164             :          *ascii++ = 102; /* 'f' */
    3165             :          *ascii = 0;
    3166             :          return;
    3167             :       }
    3168             :    }
    3169             : 
    3170             :    /* Here on buffer too small. */
    3171             :    png_error(png_ptr, "ASCII conversion buffer too small");
    3172             : }
    3173             : 
    3174             : #  endif /* FLOATING_POINT */
    3175             : 
    3176             : #  ifdef PNG_FIXED_POINT_SUPPORTED
    3177             : /* Function to format a fixed point value in ASCII.
    3178             :  */
    3179             : void /* PRIVATE */
    3180             : png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
    3181             :     png_size_t size, png_fixed_point fp)
    3182             : {
    3183             :    /* Require space for 10 decimal digits, a decimal point, a minus sign and a
    3184             :     * trailing \0, 13 characters:
    3185             :     */
    3186             :    if (size > 12)
    3187             :    {
    3188             :       png_uint_32 num;
    3189             : 
    3190             :       /* Avoid overflow here on the minimum integer. */
    3191             :       if (fp < 0)
    3192             :          *ascii++ = 45, num = (png_uint_32)(-fp);
    3193             :       else
    3194             :          num = (png_uint_32)fp;
    3195             : 
    3196             :       if (num <= 0x80000000) /* else overflowed */
    3197             :       {
    3198             :          unsigned int ndigits = 0, first = 16 /* flag value */;
    3199             :          char digits[10];
    3200             : 
    3201             :          while (num)
    3202             :          {
    3203             :             /* Split the low digit off num: */
    3204             :             unsigned int tmp = num/10;
    3205             :             num -= tmp*10;
    3206             :             digits[ndigits++] = (char)(48 + num);
    3207             :             /* Record the first non-zero digit, note that this is a number
    3208             :              * starting at 1, it's not actually the array index.
    3209             :              */
    3210             :             if (first == 16 && num > 0)
    3211             :                first = ndigits;
    3212             :             num = tmp;
    3213             :          }
    3214             : 
    3215             :          if (ndigits > 0)
    3216             :          {
    3217             :             while (ndigits > 5) *ascii++ = digits[--ndigits];
    3218             :             /* The remaining digits are fractional digits, ndigits is '5' or
    3219             :              * smaller at this point.  It is certainly not zero.  Check for a
    3220             :              * non-zero fractional digit:
    3221             :              */
    3222             :             if (first <= 5)
    3223             :             {
    3224             :                unsigned int i;
    3225             :                *ascii++ = 46; /* decimal point */
    3226             :                /* ndigits may be <5 for small numbers, output leading zeros
    3227             :                 * then ndigits digits to first:
    3228             :                 */
    3229             :                i = 5;
    3230             :                while (ndigits < i) *ascii++ = 48, --i;
    3231             :                while (ndigits >= first) *ascii++ = digits[--ndigits];
    3232             :                /* Don't output the trailing zeros! */
    3233             :             }
    3234             :          }
    3235             :          else
    3236             :             *ascii++ = 48;
    3237             : 
    3238             :          /* And null terminate the string: */
    3239             :          *ascii = 0;
    3240             :          return;
    3241             :       }
    3242             :    }
    3243             : 
    3244             :    /* Here on buffer too small. */
    3245             :    png_error(png_ptr, "ASCII conversion buffer too small");
    3246             : }
    3247             : #   endif /* FIXED_POINT */
    3248             : #endif /* SCAL */
    3249             : 
    3250             : #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
    3251             :    !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
    3252             :    (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
    3253             :    defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    3254             :    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
    3255             :    (defined(PNG_sCAL_SUPPORTED) && \
    3256             :    defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
    3257             : png_fixed_point
    3258           0 : png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
    3259             : {
    3260           0 :    double r = floor(100000 * fp + .5);
    3261             : 
    3262           0 :    if (r > 2147483647. || r < -2147483648.)
    3263           0 :       png_fixed_error(png_ptr, text);
    3264             : 
    3265             : #  ifndef PNG_ERROR_TEXT_SUPPORTED
    3266             :    PNG_UNUSED(text)
    3267             : #  endif
    3268             : 
    3269           0 :    return (png_fixed_point)r;
    3270             : }
    3271             : #endif
    3272             : 
    3273             : #if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
    3274             :     defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
    3275             : /* muldiv functions */
    3276             : /* This API takes signed arguments and rounds the result to the nearest
    3277             :  * integer (or, for a fixed point number - the standard argument - to
    3278             :  * the nearest .00001).  Overflow and divide by zero are signalled in
    3279             :  * the result, a boolean - true on success, false on overflow.
    3280             :  */
    3281             : int
    3282          23 : png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
    3283             :     png_int_32 divisor)
    3284             : {
    3285             :    /* Return a * times / divisor, rounded. */
    3286          23 :    if (divisor != 0)
    3287             :    {
    3288          23 :       if (a == 0 || times == 0)
    3289             :       {
    3290           0 :          *res = 0;
    3291           0 :          return 1;
    3292             :       }
    3293             :       else
    3294             :       {
    3295             : #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3296          23 :          double r = a;
    3297          23 :          r *= times;
    3298          23 :          r /= divisor;
    3299          23 :          r = floor(r+.5);
    3300             : 
    3301             :          /* A png_fixed_point is a 32-bit integer. */
    3302          23 :          if (r <= 2147483647. && r >= -2147483648.)
    3303             :          {
    3304          23 :             *res = (png_fixed_point)r;
    3305          23 :             return 1;
    3306             :          }
    3307             : #else
    3308             :          int negative = 0;
    3309             :          png_uint_32 A, T, D;
    3310             :          png_uint_32 s16, s32, s00;
    3311             : 
    3312             :          if (a < 0)
    3313             :             negative = 1, A = -a;
    3314             :          else
    3315             :             A = a;
    3316             : 
    3317             :          if (times < 0)
    3318             :             negative = !negative, T = -times;
    3319             :          else
    3320             :             T = times;
    3321             : 
    3322             :          if (divisor < 0)
    3323             :             negative = !negative, D = -divisor;
    3324             :          else
    3325             :             D = divisor;
    3326             : 
    3327             :          /* Following can't overflow because the arguments only
    3328             :           * have 31 bits each, however the result may be 32 bits.
    3329             :           */
    3330             :          s16 = (A >> 16) * (T & 0xffff) +
    3331             :                            (A & 0xffff) * (T >> 16);
    3332             :          /* Can't overflow because the a*times bit is only 30
    3333             :           * bits at most.
    3334             :           */
    3335             :          s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
    3336             :          s00 = (A & 0xffff) * (T & 0xffff);
    3337             : 
    3338             :          s16 = (s16 & 0xffff) << 16;
    3339             :          s00 += s16;
    3340             : 
    3341             :          if (s00 < s16)
    3342             :             ++s32; /* carry */
    3343             : 
    3344             :          if (s32 < D) /* else overflow */
    3345             :          {
    3346             :             /* s32.s00 is now the 64-bit product, do a standard
    3347             :              * division, we know that s32 < D, so the maximum
    3348             :              * required shift is 31.
    3349             :              */
    3350             :             int bitshift = 32;
    3351             :             png_fixed_point result = 0; /* NOTE: signed */
    3352             : 
    3353             :             while (--bitshift >= 0)
    3354             :             {
    3355             :                png_uint_32 d32, d00;
    3356             : 
    3357             :                if (bitshift > 0)
    3358             :                   d32 = D >> (32-bitshift), d00 = D << bitshift;
    3359             : 
    3360             :                else
    3361             :                   d32 = 0, d00 = D;
    3362             : 
    3363             :                if (s32 > d32)
    3364             :                {
    3365             :                   if (s00 < d00) --s32; /* carry */
    3366             :                   s32 -= d32, s00 -= d00, result += 1<<bitshift;
    3367             :                }
    3368             : 
    3369             :                else
    3370             :                   if (s32 == d32 && s00 >= d00)
    3371             :                      s32 = 0, s00 -= d00, result += 1<<bitshift;
    3372             :             }
    3373             : 
    3374             :             /* Handle the rounding. */
    3375             :             if (s00 >= (D >> 1))
    3376             :                ++result;
    3377             : 
    3378             :             if (negative != 0)
    3379             :                result = -result;
    3380             : 
    3381             :             /* Check for overflow. */
    3382             :             if ((negative != 0 && result <= 0) ||
    3383             :                 (negative == 0 && result >= 0))
    3384             :             {
    3385             :                *res = result;
    3386             :                return 1;
    3387             :             }
    3388             :          }
    3389             : #endif
    3390             :       }
    3391             :    }
    3392             : 
    3393           0 :    return 0;
    3394             : }
    3395             : #endif /* READ_GAMMA || INCH_CONVERSIONS */
    3396             : 
    3397             : #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
    3398             : /* The following is for when the caller doesn't much care about the
    3399             :  * result.
    3400             :  */
    3401             : png_fixed_point
    3402           0 : png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
    3403             :     png_int_32 divisor)
    3404             : {
    3405             :    png_fixed_point result;
    3406             : 
    3407           0 :    if (png_muldiv(&result, a, times, divisor) != 0)
    3408           0 :       return result;
    3409             : 
    3410           0 :    png_warning(png_ptr, "fixed point overflow ignored");
    3411           0 :    return 0;
    3412             : }
    3413             : #endif
    3414             : 
    3415             : #ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
    3416             : /* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
    3417             : png_fixed_point
    3418           8 : png_reciprocal(png_fixed_point a)
    3419             : {
    3420             : #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3421           8 :    double r = floor(1E10/a+.5);
    3422             : 
    3423           8 :    if (r <= 2147483647. && r >= -2147483648.)
    3424           8 :       return (png_fixed_point)r;
    3425             : #else
    3426             :    png_fixed_point res;
    3427             : 
    3428             :    if (png_muldiv(&res, 100000, 100000, a) != 0)
    3429             :       return res;
    3430             : #endif
    3431             : 
    3432           0 :    return 0; /* error/overflow */
    3433             : }
    3434             : 
    3435             : /* This is the shared test on whether a gamma value is 'significant' - whether
    3436             :  * it is worth doing gamma correction.
    3437             :  */
    3438             : int /* PRIVATE */
    3439          23 : png_gamma_significant(png_fixed_point gamma_val)
    3440             : {
    3441          23 :    return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
    3442             :        gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
    3443             : }
    3444             : #endif
    3445             : 
    3446             : #ifdef PNG_READ_GAMMA_SUPPORTED
    3447             : #ifdef PNG_16BIT_SUPPORTED
    3448             : /* A local convenience routine. */
    3449             : static png_fixed_point
    3450           0 : png_product2(png_fixed_point a, png_fixed_point b)
    3451             : {
    3452             :    /* The required result is 1/a * 1/b; the following preserves accuracy. */
    3453             : #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3454           0 :    double r = a * 1E-5;
    3455           0 :    r *= b;
    3456           0 :    r = floor(r+.5);
    3457             : 
    3458           0 :    if (r <= 2147483647. && r >= -2147483648.)
    3459           0 :       return (png_fixed_point)r;
    3460             : #else
    3461             :    png_fixed_point res;
    3462             : 
    3463             :    if (png_muldiv(&res, a, b, 100000) != 0)
    3464             :       return res;
    3465             : #endif
    3466             : 
    3467           0 :    return 0; /* overflow */
    3468             : }
    3469             : #endif /* 16BIT */
    3470             : 
    3471             : /* The inverse of the above. */
    3472             : png_fixed_point
    3473           0 : png_reciprocal2(png_fixed_point a, png_fixed_point b)
    3474             : {
    3475             :    /* The required result is 1/a * 1/b; the following preserves accuracy. */
    3476             : #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3477           0 :    if (a != 0 && b != 0)
    3478             :    {
    3479           0 :       double r = 1E15/a;
    3480           0 :       r /= b;
    3481           0 :       r = floor(r+.5);
    3482             : 
    3483           0 :       if (r <= 2147483647. && r >= -2147483648.)
    3484           0 :          return (png_fixed_point)r;
    3485             :    }
    3486             : #else
    3487             :    /* This may overflow because the range of png_fixed_point isn't symmetric,
    3488             :     * but this API is only used for the product of file and screen gamma so it
    3489             :     * doesn't matter that the smallest number it can produce is 1/21474, not
    3490             :     * 1/100000
    3491             :     */
    3492             :    png_fixed_point res = png_product2(a, b);
    3493             : 
    3494             :    if (res != 0)
    3495             :       return png_reciprocal(res);
    3496             : #endif
    3497             : 
    3498           0 :    return 0; /* overflow */
    3499             : }
    3500             : #endif /* READ_GAMMA */
    3501             : 
    3502             : #ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
    3503             : #ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3504             : /* Fixed point gamma.
    3505             :  *
    3506             :  * The code to calculate the tables used below can be found in the shell script
    3507             :  * contrib/tools/intgamma.sh
    3508             :  *
    3509             :  * To calculate gamma this code implements fast log() and exp() calls using only
    3510             :  * fixed point arithmetic.  This code has sufficient precision for either 8-bit
    3511             :  * or 16-bit sample values.
    3512             :  *
    3513             :  * The tables used here were calculated using simple 'bc' programs, but C double
    3514             :  * precision floating point arithmetic would work fine.
    3515             :  *
    3516             :  * 8-bit log table
    3517             :  *   This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
    3518             :  *   255, so it's the base 2 logarithm of a normalized 8-bit floating point
    3519             :  *   mantissa.  The numbers are 32-bit fractions.
    3520             :  */
    3521             : static const png_uint_32
    3522             : png_8bit_l2[128] =
    3523             : {
    3524             :    4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
    3525             :    3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
    3526             :    3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
    3527             :    3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
    3528             :    3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
    3529             :    2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
    3530             :    2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
    3531             :    2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
    3532             :    2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
    3533             :    2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
    3534             :    1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
    3535             :    1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
    3536             :    1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
    3537             :    1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
    3538             :    1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
    3539             :    971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
    3540             :    803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
    3541             :    639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
    3542             :    479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
    3543             :    324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
    3544             :    172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
    3545             :    24347096U, 0U
    3546             : 
    3547             : #if 0
    3548             :    /* The following are the values for 16-bit tables - these work fine for the
    3549             :     * 8-bit conversions but produce very slightly larger errors in the 16-bit
    3550             :     * log (about 1.2 as opposed to 0.7 absolute error in the final value).  To
    3551             :     * use these all the shifts below must be adjusted appropriately.
    3552             :     */
    3553             :    65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
    3554             :    57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
    3555             :    50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
    3556             :    43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
    3557             :    37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
    3558             :    31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
    3559             :    25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
    3560             :    20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
    3561             :    15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
    3562             :    10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
    3563             :    6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
    3564             :    1119, 744, 372
    3565             : #endif
    3566             : };
    3567             : 
    3568             : static png_int_32
    3569             : png_log8bit(unsigned int x)
    3570             : {
    3571             :    unsigned int lg2 = 0;
    3572             :    /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
    3573             :     * because the log is actually negate that means adding 1.  The final
    3574             :     * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
    3575             :     * input), return -1 for the overflow (log 0) case, - so the result is
    3576             :     * always at most 19 bits.
    3577             :     */
    3578             :    if ((x &= 0xff) == 0)
    3579             :       return -1;
    3580             : 
    3581             :    if ((x & 0xf0) == 0)
    3582             :       lg2  = 4, x <<= 4;
    3583             : 
    3584             :    if ((x & 0xc0) == 0)
    3585             :       lg2 += 2, x <<= 2;
    3586             : 
    3587             :    if ((x & 0x80) == 0)
    3588             :       lg2 += 1, x <<= 1;
    3589             : 
    3590             :    /* result is at most 19 bits, so this cast is safe: */
    3591             :    return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
    3592             : }
    3593             : 
    3594             : /* The above gives exact (to 16 binary places) log2 values for 8-bit images,
    3595             :  * for 16-bit images we use the most significant 8 bits of the 16-bit value to
    3596             :  * get an approximation then multiply the approximation by a correction factor
    3597             :  * determined by the remaining up to 8 bits.  This requires an additional step
    3598             :  * in the 16-bit case.
    3599             :  *
    3600             :  * We want log2(value/65535), we have log2(v'/255), where:
    3601             :  *
    3602             :  *    value = v' * 256 + v''
    3603             :  *          = v' * f
    3604             :  *
    3605             :  * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
    3606             :  * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
    3607             :  * than 258.  The final factor also needs to correct for the fact that our 8-bit
    3608             :  * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
    3609             :  *
    3610             :  * This gives a final formula using a calculated value 'x' which is value/v' and
    3611             :  * scaling by 65536 to match the above table:
    3612             :  *
    3613             :  *   log2(x/257) * 65536
    3614             :  *
    3615             :  * Since these numbers are so close to '1' we can use simple linear
    3616             :  * interpolation between the two end values 256/257 (result -368.61) and 258/257
    3617             :  * (result 367.179).  The values used below are scaled by a further 64 to give
    3618             :  * 16-bit precision in the interpolation:
    3619             :  *
    3620             :  * Start (256): -23591
    3621             :  * Zero  (257):      0
    3622             :  * End   (258):  23499
    3623             :  */
    3624             : #ifdef PNG_16BIT_SUPPORTED
    3625             : static png_int_32
    3626             : png_log16bit(png_uint_32 x)
    3627             : {
    3628             :    unsigned int lg2 = 0;
    3629             : 
    3630             :    /* As above, but now the input has 16 bits. */
    3631             :    if ((x &= 0xffff) == 0)
    3632             :       return -1;
    3633             : 
    3634             :    if ((x & 0xff00) == 0)
    3635             :       lg2  = 8, x <<= 8;
    3636             : 
    3637             :    if ((x & 0xf000) == 0)
    3638             :       lg2 += 4, x <<= 4;
    3639             : 
    3640             :    if ((x & 0xc000) == 0)
    3641             :       lg2 += 2, x <<= 2;
    3642             : 
    3643             :    if ((x & 0x8000) == 0)
    3644             :       lg2 += 1, x <<= 1;
    3645             : 
    3646             :    /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
    3647             :     * value.
    3648             :     */
    3649             :    lg2 <<= 28;
    3650             :    lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
    3651             : 
    3652             :    /* Now we need to interpolate the factor, this requires a division by the top
    3653             :     * 8 bits.  Do this with maximum precision.
    3654             :     */
    3655             :    x = ((x << 16) + (x >> 9)) / (x >> 8);
    3656             : 
    3657             :    /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
    3658             :     * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
    3659             :     * 16 bits to interpolate to get the low bits of the result.  Round the
    3660             :     * answer.  Note that the end point values are scaled by 64 to retain overall
    3661             :     * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
    3662             :     * the overall scaling by 6-12.  Round at every step.
    3663             :     */
    3664             :    x -= 1U << 24;
    3665             : 
    3666             :    if (x <= 65536U) /* <= '257' */
    3667             :       lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
    3668             : 
    3669             :    else
    3670             :       lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
    3671             : 
    3672             :    /* Safe, because the result can't have more than 20 bits: */
    3673             :    return (png_int_32)((lg2 + 2048) >> 12);
    3674             : }
    3675             : #endif /* 16BIT */
    3676             : 
    3677             : /* The 'exp()' case must invert the above, taking a 20-bit fixed point
    3678             :  * logarithmic value and returning a 16 or 8-bit number as appropriate.  In
    3679             :  * each case only the low 16 bits are relevant - the fraction - since the
    3680             :  * integer bits (the top 4) simply determine a shift.
    3681             :  *
    3682             :  * The worst case is the 16-bit distinction between 65535 and 65534. This
    3683             :  * requires perhaps spurious accuracy in the decoding of the logarithm to
    3684             :  * distinguish log2(65535/65534.5) - 10^-5 or 17 bits.  There is little chance
    3685             :  * of getting this accuracy in practice.
    3686             :  *
    3687             :  * To deal with this the following exp() function works out the exponent of the
    3688             :  * frational part of the logarithm by using an accurate 32-bit value from the
    3689             :  * top four fractional bits then multiplying in the remaining bits.
    3690             :  */
    3691             : static const png_uint_32
    3692             : png_32bit_exp[16] =
    3693             : {
    3694             :    /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
    3695             :    4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
    3696             :    3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
    3697             :    2553802834U, 2445529972U, 2341847524U, 2242560872U
    3698             : };
    3699             : 
    3700             : /* Adjustment table; provided to explain the numbers in the code below. */
    3701             : #if 0
    3702             : for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
    3703             :    11 44937.64284865548751208448
    3704             :    10 45180.98734845585101160448
    3705             :     9 45303.31936980687359311872
    3706             :     8 45364.65110595323018870784
    3707             :     7 45395.35850361789624614912
    3708             :     6 45410.72259715102037508096
    3709             :     5 45418.40724413220722311168
    3710             :     4 45422.25021786898173001728
    3711             :     3 45424.17186732298419044352
    3712             :     2 45425.13273269940811464704
    3713             :     1 45425.61317555035558641664
    3714             :     0 45425.85339951654943850496
    3715             : #endif
    3716             : 
    3717             : static png_uint_32
    3718             : png_exp(png_fixed_point x)
    3719             : {
    3720             :    if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
    3721             :    {
    3722             :       /* Obtain a 4-bit approximation */
    3723             :       png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
    3724             : 
    3725             :       /* Incorporate the low 12 bits - these decrease the returned value by
    3726             :        * multiplying by a number less than 1 if the bit is set.  The multiplier
    3727             :        * is determined by the above table and the shift. Notice that the values
    3728             :        * converge on 45426 and this is used to allow linear interpolation of the
    3729             :        * low bits.
    3730             :        */
    3731             :       if (x & 0x800)
    3732             :          e -= (((e >> 16) * 44938U) +  16U) >> 5;
    3733             : 
    3734             :       if (x & 0x400)
    3735             :          e -= (((e >> 16) * 45181U) +  32U) >> 6;
    3736             : 
    3737             :       if (x & 0x200)
    3738             :          e -= (((e >> 16) * 45303U) +  64U) >> 7;
    3739             : 
    3740             :       if (x & 0x100)
    3741             :          e -= (((e >> 16) * 45365U) + 128U) >> 8;
    3742             : 
    3743             :       if (x & 0x080)
    3744             :          e -= (((e >> 16) * 45395U) + 256U) >> 9;
    3745             : 
    3746             :       if (x & 0x040)
    3747             :          e -= (((e >> 16) * 45410U) + 512U) >> 10;
    3748             : 
    3749             :       /* And handle the low 6 bits in a single block. */
    3750             :       e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
    3751             : 
    3752             :       /* Handle the upper bits of x. */
    3753             :       e >>= x >> 16;
    3754             :       return e;
    3755             :    }
    3756             : 
    3757             :    /* Check for overflow */
    3758             :    if (x <= 0)
    3759             :       return png_32bit_exp[0];
    3760             : 
    3761             :    /* Else underflow */
    3762             :    return 0;
    3763             : }
    3764             : 
    3765             : static png_byte
    3766             : png_exp8bit(png_fixed_point lg2)
    3767             : {
    3768             :    /* Get a 32-bit value: */
    3769             :    png_uint_32 x = png_exp(lg2);
    3770             : 
    3771             :    /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
    3772             :     * second, rounding, step can't overflow because of the first, subtraction,
    3773             :     * step.
    3774             :     */
    3775             :    x -= x >> 8;
    3776             :    return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
    3777             : }
    3778             : 
    3779             : #ifdef PNG_16BIT_SUPPORTED
    3780             : static png_uint_16
    3781             : png_exp16bit(png_fixed_point lg2)
    3782             : {
    3783             :    /* Get a 32-bit value: */
    3784             :    png_uint_32 x = png_exp(lg2);
    3785             : 
    3786             :    /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
    3787             :    x -= x >> 16;
    3788             :    return (png_uint_16)((x + 32767U) >> 16);
    3789             : }
    3790             : #endif /* 16BIT */
    3791             : #endif /* FLOATING_ARITHMETIC */
    3792             : 
    3793             : png_byte
    3794           0 : png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
    3795             : {
    3796           0 :    if (value > 0 && value < 255)
    3797             :    {
    3798             : #     ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3799             :          /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
    3800             :           * convert this to a floating point value.  This includes values that
    3801             :           * would overflow if 'value' were to be converted to 'int'.
    3802             :           *
    3803             :           * Apparently GCC, however, does an intermediate conversion to (int)
    3804             :           * on some (ARM) but not all (x86) platforms, possibly because of
    3805             :           * hardware FP limitations.  (E.g. if the hardware conversion always
    3806             :           * assumes the integer register contains a signed value.)  This results
    3807             :           * in ANSI-C undefined behavior for large values.
    3808             :           *
    3809             :           * Other implementations on the same machine might actually be ANSI-C90
    3810             :           * conformant and therefore compile spurious extra code for the large
    3811             :           * values.
    3812             :           *
    3813             :           * We can be reasonably sure that an unsigned to float conversion
    3814             :           * won't be faster than an int to float one.  Therefore this code
    3815             :           * assumes responsibility for the undefined behavior, which it knows
    3816             :           * can't happen because of the check above.
    3817             :           *
    3818             :           * Note the argument to this routine is an (unsigned int) because, on
    3819             :           * 16-bit platforms, it is assigned a value which might be out of
    3820             :           * range for an (int); that would result in undefined behavior in the
    3821             :           * caller if the *argument* ('value') were to be declared (int).
    3822             :           */
    3823           0 :          double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
    3824           0 :          return (png_byte)r;
    3825             : #     else
    3826             :          png_int_32 lg2 = png_log8bit(value);
    3827             :          png_fixed_point res;
    3828             : 
    3829             :          if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
    3830             :             return png_exp8bit(res);
    3831             : 
    3832             :          /* Overflow. */
    3833             :          value = 0;
    3834             : #     endif
    3835             :    }
    3836             : 
    3837           0 :    return (png_byte)(value & 0xff);
    3838             : }
    3839             : 
    3840             : #ifdef PNG_16BIT_SUPPORTED
    3841             : png_uint_16
    3842           0 : png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
    3843             : {
    3844           0 :    if (value > 0 && value < 65535)
    3845             :    {
    3846             : # ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3847             :       /* The same (unsigned int)->(double) constraints apply here as above,
    3848             :        * however in this case the (unsigned int) to (int) conversion can
    3849             :        * overflow on an ANSI-C90 compliant system so the cast needs to ensure
    3850             :        * that this is not possible.
    3851             :        */
    3852           0 :       double r = floor(65535*pow((png_int_32)value/65535.,
    3853             :           gamma_val*.00001)+.5);
    3854           0 :       return (png_uint_16)r;
    3855             : # else
    3856             :       png_int_32 lg2 = png_log16bit(value);
    3857             :       png_fixed_point res;
    3858             : 
    3859             :       if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
    3860             :          return png_exp16bit(res);
    3861             : 
    3862             :       /* Overflow. */
    3863             :       value = 0;
    3864             : # endif
    3865             :    }
    3866             : 
    3867           0 :    return (png_uint_16)value;
    3868             : }
    3869             : #endif /* 16BIT */
    3870             : 
    3871             : /* This does the right thing based on the bit_depth field of the
    3872             :  * png_struct, interpreting values as 8-bit or 16-bit.  While the result
    3873             :  * is nominally a 16-bit value if bit depth is 8 then the result is
    3874             :  * 8-bit (as are the arguments.)
    3875             :  */
    3876             : png_uint_16 /* PRIVATE */
    3877           0 : png_gamma_correct(png_structrp png_ptr, unsigned int value,
    3878             :     png_fixed_point gamma_val)
    3879             : {
    3880           0 :    if (png_ptr->bit_depth == 8)
    3881           0 :       return png_gamma_8bit_correct(value, gamma_val);
    3882             : 
    3883             : #ifdef PNG_16BIT_SUPPORTED
    3884             :    else
    3885           0 :       return png_gamma_16bit_correct(value, gamma_val);
    3886             : #else
    3887             :       /* should not reach this */
    3888             :       return 0;
    3889             : #endif /* 16BIT */
    3890             : }
    3891             : 
    3892             : #ifdef PNG_16BIT_SUPPORTED
    3893             : /* Internal function to build a single 16-bit table - the table consists of
    3894             :  * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
    3895             :  * to shift the input values right (or 16-number_of_signifiant_bits).
    3896             :  *
    3897             :  * The caller is responsible for ensuring that the table gets cleaned up on
    3898             :  * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
    3899             :  * should be somewhere that will be cleaned.
    3900             :  */
    3901             : static void
    3902           0 : png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
    3903             :     PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
    3904             : {
    3905             :    /* Various values derived from 'shift': */
    3906           0 :    PNG_CONST unsigned int num = 1U << (8U - shift);
    3907             : #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3908             :    /* CSE the division and work round wacky GCC warnings (see the comments
    3909             :     * in png_gamma_8bit_correct for where these come from.)
    3910             :     */
    3911           0 :    PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
    3912             : #endif
    3913           0 :    PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
    3914           0 :    PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
    3915             :    unsigned int i;
    3916             : 
    3917           0 :    png_uint_16pp table = *ptable =
    3918           0 :        (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
    3919             : 
    3920           0 :    for (i = 0; i < num; i++)
    3921             :    {
    3922           0 :       png_uint_16p sub_table = table[i] =
    3923           0 :           (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
    3924             : 
    3925             :       /* The 'threshold' test is repeated here because it can arise for one of
    3926             :        * the 16-bit tables even if the others don't hit it.
    3927             :        */
    3928           0 :       if (png_gamma_significant(gamma_val) != 0)
    3929             :       {
    3930             :          /* The old code would overflow at the end and this would cause the
    3931             :           * 'pow' function to return a result >1, resulting in an
    3932             :           * arithmetic error.  This code follows the spec exactly; ig is
    3933             :           * the recovered input sample, it always has 8-16 bits.
    3934             :           *
    3935             :           * We want input * 65535/max, rounded, the arithmetic fits in 32
    3936             :           * bits (unsigned) so long as max <= 32767.
    3937             :           */
    3938             :          unsigned int j;
    3939           0 :          for (j = 0; j < 256; j++)
    3940             :          {
    3941           0 :             png_uint_32 ig = (j << (8-shift)) + i;
    3942             : #           ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
    3943             :                /* Inline the 'max' scaling operation: */
    3944             :                /* See png_gamma_8bit_correct for why the cast to (int) is
    3945             :                 * required here.
    3946             :                 */
    3947           0 :                double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
    3948           0 :                sub_table[j] = (png_uint_16)d;
    3949             : #           else
    3950             :                if (shift != 0)
    3951             :                   ig = (ig * 65535U + max_by_2)/max;
    3952             : 
    3953             :                sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
    3954             : #           endif
    3955             :          }
    3956             :       }
    3957             :       else
    3958             :       {
    3959             :          /* We must still build a table, but do it the fast way. */
    3960             :          unsigned int j;
    3961             : 
    3962           0 :          for (j = 0; j < 256; j++)
    3963             :          {
    3964           0 :             png_uint_32 ig = (j << (8-shift)) + i;
    3965             : 
    3966           0 :             if (shift != 0)
    3967           0 :                ig = (ig * 65535U + max_by_2)/max;
    3968             : 
    3969           0 :             sub_table[j] = (png_uint_16)ig;
    3970             :          }
    3971             :       }
    3972             :    }
    3973           0 : }
    3974             : 
    3975             : /* NOTE: this function expects the *inverse* of the overall gamma transformation
    3976             :  * required.
    3977             :  */
    3978             : static void
    3979           0 : png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
    3980             :     PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
    3981             : {
    3982           0 :    PNG_CONST unsigned int num = 1U << (8U - shift);
    3983           0 :    PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
    3984             :    unsigned int i;
    3985             :    png_uint_32 last;
    3986             : 
    3987           0 :    png_uint_16pp table = *ptable =
    3988           0 :        (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
    3989             : 
    3990             :    /* 'num' is the number of tables and also the number of low bits of low
    3991             :     * bits of the input 16-bit value used to select a table.  Each table is
    3992             :     * itself indexed by the high 8 bits of the value.
    3993             :     */
    3994           0 :    for (i = 0; i < num; i++)
    3995           0 :       table[i] = (png_uint_16p)png_malloc(png_ptr,
    3996             :           256 * (sizeof (png_uint_16)));
    3997             : 
    3998             :    /* 'gamma_val' is set to the reciprocal of the value calculated above, so
    3999             :     * pow(out,g) is an *input* value.  'last' is the last input value set.
    4000             :     *
    4001             :     * In the loop 'i' is used to find output values.  Since the output is
    4002             :     * 8-bit there are only 256 possible values.  The tables are set up to
    4003             :     * select the closest possible output value for each input by finding
    4004             :     * the input value at the boundary between each pair of output values
    4005             :     * and filling the table up to that boundary with the lower output
    4006             :     * value.
    4007             :     *
    4008             :     * The boundary values are 0.5,1.5..253.5,254.5.  Since these are 9-bit
    4009             :     * values the code below uses a 16-bit value in i; the values start at
    4010             :     * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
    4011             :     * entries are filled with 255).  Start i at 128 and fill all 'last'
    4012             :     * table entries <= 'max'
    4013             :     */
    4014           0 :    last = 0;
    4015           0 :    for (i = 0; i < 255; ++i) /* 8-bit output value */
    4016             :    {
    4017             :       /* Find the corresponding maximum input value */
    4018           0 :       png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
    4019             : 
    4020             :       /* Find the boundary value in 16 bits: */
    4021           0 :       png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
    4022             : 
    4023             :       /* Adjust (round) to (16-shift) bits: */
    4024           0 :       bound = (bound * max + 32768U)/65535U + 1U;
    4025             : 
    4026           0 :       while (last < bound)
    4027             :       {
    4028           0 :          table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
    4029           0 :          last++;
    4030             :       }
    4031             :    }
    4032             : 
    4033             :    /* And fill in the final entries. */
    4034           0 :    while (last < (num << 8))
    4035             :    {
    4036           0 :       table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
    4037           0 :       last++;
    4038             :    }
    4039           0 : }
    4040             : #endif /* 16BIT */
    4041             : 
    4042             : /* Build a single 8-bit table: same as the 16-bit case but much simpler (and
    4043             :  * typically much faster).  Note that libpng currently does no sBIT processing
    4044             :  * (apparently contrary to the spec) so a 256-entry table is always generated.
    4045             :  */
    4046             : static void
    4047           0 : png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
    4048             :     PNG_CONST png_fixed_point gamma_val)
    4049             : {
    4050             :    unsigned int i;
    4051           0 :    png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
    4052             : 
    4053           0 :    if (png_gamma_significant(gamma_val) != 0)
    4054           0 :       for (i=0; i<256; i++)
    4055           0 :          table[i] = png_gamma_8bit_correct(i, gamma_val);
    4056             : 
    4057             :    else
    4058           0 :       for (i=0; i<256; ++i)
    4059           0 :          table[i] = (png_byte)(i & 0xff);
    4060           0 : }
    4061             : 
    4062             : /* Used from png_read_destroy and below to release the memory used by the gamma
    4063             :  * tables.
    4064             :  */
    4065             : void /* PRIVATE */
    4066          31 : png_destroy_gamma_table(png_structrp png_ptr)
    4067             : {
    4068          31 :    png_free(png_ptr, png_ptr->gamma_table);
    4069          31 :    png_ptr->gamma_table = NULL;
    4070             : 
    4071             : #ifdef PNG_16BIT_SUPPORTED
    4072          31 :    if (png_ptr->gamma_16_table != NULL)
    4073             :    {
    4074             :       int i;
    4075           0 :       int istop = (1 << (8 - png_ptr->gamma_shift));
    4076           0 :       for (i = 0; i < istop; i++)
    4077             :       {
    4078           0 :          png_free(png_ptr, png_ptr->gamma_16_table[i]);
    4079             :       }
    4080           0 :    png_free(png_ptr, png_ptr->gamma_16_table);
    4081           0 :    png_ptr->gamma_16_table = NULL;
    4082             :    }
    4083             : #endif /* 16BIT */
    4084             : 
    4085             : #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    4086             :    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    4087             :    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    4088             :    png_free(png_ptr, png_ptr->gamma_from_1);
    4089             :    png_ptr->gamma_from_1 = NULL;
    4090             :    png_free(png_ptr, png_ptr->gamma_to_1);
    4091             :    png_ptr->gamma_to_1 = NULL;
    4092             : 
    4093             : #ifdef PNG_16BIT_SUPPORTED
    4094             :    if (png_ptr->gamma_16_from_1 != NULL)
    4095             :    {
    4096             :       int i;
    4097             :       int istop = (1 << (8 - png_ptr->gamma_shift));
    4098             :       for (i = 0; i < istop; i++)
    4099             :       {
    4100             :          png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
    4101             :       }
    4102             :    png_free(png_ptr, png_ptr->gamma_16_from_1);
    4103             :    png_ptr->gamma_16_from_1 = NULL;
    4104             :    }
    4105             :    if (png_ptr->gamma_16_to_1 != NULL)
    4106             :    {
    4107             :       int i;
    4108             :       int istop = (1 << (8 - png_ptr->gamma_shift));
    4109             :       for (i = 0; i < istop; i++)
    4110             :       {
    4111             :          png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
    4112             :       }
    4113             :    png_free(png_ptr, png_ptr->gamma_16_to_1);
    4114             :    png_ptr->gamma_16_to_1 = NULL;
    4115             :    }
    4116             : #endif /* 16BIT */
    4117             : #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
    4118          31 : }
    4119             : 
    4120             : /* We build the 8- or 16-bit gamma tables here.  Note that for 16-bit
    4121             :  * tables, we don't make a full table if we are reducing to 8-bit in
    4122             :  * the future.  Note also how the gamma_16 tables are segmented so that
    4123             :  * we don't need to allocate > 64K chunks for a full 16-bit table.
    4124             :  */
    4125             : void /* PRIVATE */
    4126           0 : png_build_gamma_table(png_structrp png_ptr, int bit_depth)
    4127             : {
    4128             :    png_debug(1, "in png_build_gamma_table");
    4129             : 
    4130             :    /* Remove any existing table; this copes with multiple calls to
    4131             :     * png_read_update_info. The warning is because building the gamma tables
    4132             :     * multiple times is a performance hit - it's harmless but the ability to
    4133             :     * call png_read_update_info() multiple times is new in 1.5.6 so it seems
    4134             :     * sensible to warn if the app introduces such a hit.
    4135             :     */
    4136           0 :    if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
    4137             :    {
    4138           0 :       png_warning(png_ptr, "gamma table being rebuilt");
    4139           0 :       png_destroy_gamma_table(png_ptr);
    4140             :    }
    4141             : 
    4142           0 :    if (bit_depth <= 8)
    4143             :    {
    4144           0 :       png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
    4145           0 :           png_ptr->screen_gamma > 0 ?
    4146           0 :           png_reciprocal2(png_ptr->colorspace.gamma,
    4147             :           png_ptr->screen_gamma) : PNG_FP_1);
    4148             : 
    4149             : #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    4150             :    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    4151             :    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    4152             :       if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
    4153             :       {
    4154             :          png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
    4155             :              png_reciprocal(png_ptr->colorspace.gamma));
    4156             : 
    4157             :          png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
    4158             :              png_ptr->screen_gamma > 0 ?
    4159             :              png_reciprocal(png_ptr->screen_gamma) :
    4160             :              png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
    4161             :       }
    4162             : #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
    4163             :    }
    4164             : #ifdef PNG_16BIT_SUPPORTED
    4165             :    else
    4166             :    {
    4167             :       png_byte shift, sig_bit;
    4168             : 
    4169           0 :       if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
    4170             :       {
    4171           0 :          sig_bit = png_ptr->sig_bit.red;
    4172             : 
    4173           0 :          if (png_ptr->sig_bit.green > sig_bit)
    4174           0 :             sig_bit = png_ptr->sig_bit.green;
    4175             : 
    4176           0 :          if (png_ptr->sig_bit.blue > sig_bit)
    4177           0 :             sig_bit = png_ptr->sig_bit.blue;
    4178             :       }
    4179             :       else
    4180           0 :          sig_bit = png_ptr->sig_bit.gray;
    4181             : 
    4182             :       /* 16-bit gamma code uses this equation:
    4183             :        *
    4184             :        *   ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
    4185             :        *
    4186             :        * Where 'iv' is the input color value and 'ov' is the output value -
    4187             :        * pow(iv, gamma).
    4188             :        *
    4189             :        * Thus the gamma table consists of up to 256 256-entry tables.  The table
    4190             :        * is selected by the (8-gamma_shift) most significant of the low 8 bits
    4191             :        * of the color value then indexed by the upper 8 bits:
    4192             :        *
    4193             :        *   table[low bits][high 8 bits]
    4194             :        *
    4195             :        * So the table 'n' corresponds to all those 'iv' of:
    4196             :        *
    4197             :        *   <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
    4198             :        *
    4199             :        */
    4200           0 :       if (sig_bit > 0 && sig_bit < 16U)
    4201             :          /* shift == insignificant bits */
    4202           0 :          shift = (png_byte)((16U - sig_bit) & 0xff);
    4203             : 
    4204             :       else
    4205           0 :          shift = 0; /* keep all 16 bits */
    4206             : 
    4207           0 :       if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
    4208             :       {
    4209             :          /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
    4210             :           * the significant bits in the *input* when the output will
    4211             :           * eventually be 8 bits.  By default it is 11.
    4212             :           */
    4213           0 :          if (shift < (16U - PNG_MAX_GAMMA_8))
    4214           0 :             shift = (16U - PNG_MAX_GAMMA_8);
    4215             :       }
    4216             : 
    4217           0 :       if (shift > 8U)
    4218           0 :          shift = 8U; /* Guarantees at least one table! */
    4219             : 
    4220           0 :       png_ptr->gamma_shift = shift;
    4221             : 
    4222             :       /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
    4223             :        * PNG_COMPOSE).  This effectively smashed the background calculation for
    4224             :        * 16-bit output because the 8-bit table assumes the result will be
    4225             :        * reduced to 8 bits.
    4226             :        */
    4227           0 :       if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
    4228           0 :           png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
    4229           0 :           png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
    4230             :           png_ptr->screen_gamma) : PNG_FP_1);
    4231             : 
    4232             :       else
    4233           0 :           png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
    4234           0 :           png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
    4235             :           png_ptr->screen_gamma) : PNG_FP_1);
    4236             : 
    4237             : #if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
    4238             :    defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
    4239             :    defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
    4240             :       if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
    4241             :       {
    4242             :          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
    4243             :              png_reciprocal(png_ptr->colorspace.gamma));
    4244             : 
    4245             :          /* Notice that the '16 from 1' table should be full precision, however
    4246             :           * the lookup on this table still uses gamma_shift, so it can't be.
    4247             :           * TODO: fix this.
    4248             :           */
    4249             :          png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
    4250             :              png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
    4251             :              png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
    4252             :       }
    4253             : #endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
    4254             :    }
    4255             : #endif /* 16BIT */
    4256           0 : }
    4257             : #endif /* READ_GAMMA */
    4258             : 
    4259             : /* HARDWARE OR SOFTWARE OPTION SUPPORT */
    4260             : #ifdef PNG_SET_OPTION_SUPPORTED
    4261             : int PNGAPI
    4262          31 : png_set_option(png_structrp png_ptr, int option, int onoff)
    4263             : {
    4264          62 :    if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
    4265          31 :       (option & 1) == 0)
    4266             :    {
    4267          31 :       png_uint_32 mask = 3U << option;
    4268          31 :       png_uint_32 setting = (2U + (onoff != 0)) << option;
    4269          31 :       png_uint_32 current = png_ptr->options;
    4270             : 
    4271          31 :       png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff);
    4272             : 
    4273          31 :       return (int)(current & mask) >> option;
    4274             :    }
    4275             : 
    4276           0 :    return PNG_OPTION_INVALID;
    4277             : }
    4278             : #endif
    4279             : 
    4280             : /* sRGB support */
    4281             : #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
    4282             :    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
    4283             : /* sRGB conversion tables; these are machine generated with the code in
    4284             :  * contrib/tools/makesRGB.c.  The actual sRGB transfer curve defined in the
    4285             :  * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
    4286             :  * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
    4287             :  * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
    4288             :  * The inverse (linear to sRGB) table has accuracies as follows:
    4289             :  *
    4290             :  * For all possible (255*65535+1) input values:
    4291             :  *
    4292             :  *    error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
    4293             :  *
    4294             :  * For the input values corresponding to the 65536 16-bit values:
    4295             :  *
    4296             :  *    error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
    4297             :  *
    4298             :  * In all cases the inexact readings are only off by one.
    4299             :  */
    4300             : 
    4301             : #ifdef PNG_SIMPLIFIED_READ_SUPPORTED
    4302             : /* The convert-to-sRGB table is only currently required for read. */
    4303             : const png_uint_16 png_sRGB_table[256] =
    4304             : {
    4305             :    0,20,40,60,80,99,119,139,
    4306             :    159,179,199,219,241,264,288,313,
    4307             :    340,367,396,427,458,491,526,562,
    4308             :    599,637,677,718,761,805,851,898,
    4309             :    947,997,1048,1101,1156,1212,1270,1330,
    4310             :    1391,1453,1517,1583,1651,1720,1790,1863,
    4311             :    1937,2013,2090,2170,2250,2333,2418,2504,
    4312             :    2592,2681,2773,2866,2961,3058,3157,3258,
    4313             :    3360,3464,3570,3678,3788,3900,4014,4129,
    4314             :    4247,4366,4488,4611,4736,4864,4993,5124,
    4315             :    5257,5392,5530,5669,5810,5953,6099,6246,
    4316             :    6395,6547,6700,6856,7014,7174,7335,7500,
    4317             :    7666,7834,8004,8177,8352,8528,8708,8889,
    4318             :    9072,9258,9445,9635,9828,10022,10219,10417,
    4319             :    10619,10822,11028,11235,11446,11658,11873,12090,
    4320             :    12309,12530,12754,12980,13209,13440,13673,13909,
    4321             :    14146,14387,14629,14874,15122,15371,15623,15878,
    4322             :    16135,16394,16656,16920,17187,17456,17727,18001,
    4323             :    18277,18556,18837,19121,19407,19696,19987,20281,
    4324             :    20577,20876,21177,21481,21787,22096,22407,22721,
    4325             :    23038,23357,23678,24002,24329,24658,24990,25325,
    4326             :    25662,26001,26344,26688,27036,27386,27739,28094,
    4327             :    28452,28813,29176,29542,29911,30282,30656,31033,
    4328             :    31412,31794,32179,32567,32957,33350,33745,34143,
    4329             :    34544,34948,35355,35764,36176,36591,37008,37429,
    4330             :    37852,38278,38706,39138,39572,40009,40449,40891,
    4331             :    41337,41785,42236,42690,43147,43606,44069,44534,
    4332             :    45002,45473,45947,46423,46903,47385,47871,48359,
    4333             :    48850,49344,49841,50341,50844,51349,51858,52369,
    4334             :    52884,53401,53921,54445,54971,55500,56032,56567,
    4335             :    57105,57646,58190,58737,59287,59840,60396,60955,
    4336             :    61517,62082,62650,63221,63795,64372,64952,65535
    4337             : };
    4338             : #endif /* SIMPLIFIED_READ */
    4339             : 
    4340             : /* The base/delta tables are required for both read and write (but currently
    4341             :  * only the simplified versions.)
    4342             :  */
    4343             : const png_uint_16 png_sRGB_base[512] =
    4344             : {
    4345             :    128,1782,3383,4644,5675,6564,7357,8074,
    4346             :    8732,9346,9921,10463,10977,11466,11935,12384,
    4347             :    12816,13233,13634,14024,14402,14769,15125,15473,
    4348             :    15812,16142,16466,16781,17090,17393,17690,17981,
    4349             :    18266,18546,18822,19093,19359,19621,19879,20133,
    4350             :    20383,20630,20873,21113,21349,21583,21813,22041,
    4351             :    22265,22487,22707,22923,23138,23350,23559,23767,
    4352             :    23972,24175,24376,24575,24772,24967,25160,25352,
    4353             :    25542,25730,25916,26101,26284,26465,26645,26823,
    4354             :    27000,27176,27350,27523,27695,27865,28034,28201,
    4355             :    28368,28533,28697,28860,29021,29182,29341,29500,
    4356             :    29657,29813,29969,30123,30276,30429,30580,30730,
    4357             :    30880,31028,31176,31323,31469,31614,31758,31902,
    4358             :    32045,32186,32327,32468,32607,32746,32884,33021,
    4359             :    33158,33294,33429,33564,33697,33831,33963,34095,
    4360             :    34226,34357,34486,34616,34744,34873,35000,35127,
    4361             :    35253,35379,35504,35629,35753,35876,35999,36122,
    4362             :    36244,36365,36486,36606,36726,36845,36964,37083,
    4363             :    37201,37318,37435,37551,37668,37783,37898,38013,
    4364             :    38127,38241,38354,38467,38580,38692,38803,38915,
    4365             :    39026,39136,39246,39356,39465,39574,39682,39790,
    4366             :    39898,40005,40112,40219,40325,40431,40537,40642,
    4367             :    40747,40851,40955,41059,41163,41266,41369,41471,
    4368             :    41573,41675,41777,41878,41979,42079,42179,42279,
    4369             :    42379,42478,42577,42676,42775,42873,42971,43068,
    4370             :    43165,43262,43359,43456,43552,43648,43743,43839,
    4371             :    43934,44028,44123,44217,44311,44405,44499,44592,
    4372             :    44685,44778,44870,44962,45054,45146,45238,45329,
    4373             :    45420,45511,45601,45692,45782,45872,45961,46051,
    4374             :    46140,46229,46318,46406,46494,46583,46670,46758,
    4375             :    46846,46933,47020,47107,47193,47280,47366,47452,
    4376             :    47538,47623,47709,47794,47879,47964,48048,48133,
    4377             :    48217,48301,48385,48468,48552,48635,48718,48801,
    4378             :    48884,48966,49048,49131,49213,49294,49376,49458,
    4379             :    49539,49620,49701,49782,49862,49943,50023,50103,
    4380             :    50183,50263,50342,50422,50501,50580,50659,50738,
    4381             :    50816,50895,50973,51051,51129,51207,51285,51362,
    4382             :    51439,51517,51594,51671,51747,51824,51900,51977,
    4383             :    52053,52129,52205,52280,52356,52432,52507,52582,
    4384             :    52657,52732,52807,52881,52956,53030,53104,53178,
    4385             :    53252,53326,53400,53473,53546,53620,53693,53766,
    4386             :    53839,53911,53984,54056,54129,54201,54273,54345,
    4387             :    54417,54489,54560,54632,54703,54774,54845,54916,
    4388             :    54987,55058,55129,55199,55269,55340,55410,55480,
    4389             :    55550,55620,55689,55759,55828,55898,55967,56036,
    4390             :    56105,56174,56243,56311,56380,56448,56517,56585,
    4391             :    56653,56721,56789,56857,56924,56992,57059,57127,
    4392             :    57194,57261,57328,57395,57462,57529,57595,57662,
    4393             :    57728,57795,57861,57927,57993,58059,58125,58191,
    4394             :    58256,58322,58387,58453,58518,58583,58648,58713,
    4395             :    58778,58843,58908,58972,59037,59101,59165,59230,
    4396             :    59294,59358,59422,59486,59549,59613,59677,59740,
    4397             :    59804,59867,59930,59993,60056,60119,60182,60245,
    4398             :    60308,60370,60433,60495,60558,60620,60682,60744,
    4399             :    60806,60868,60930,60992,61054,61115,61177,61238,
    4400             :    61300,61361,61422,61483,61544,61605,61666,61727,
    4401             :    61788,61848,61909,61969,62030,62090,62150,62211,
    4402             :    62271,62331,62391,62450,62510,62570,62630,62689,
    4403             :    62749,62808,62867,62927,62986,63045,63104,63163,
    4404             :    63222,63281,63340,63398,63457,63515,63574,63632,
    4405             :    63691,63749,63807,63865,63923,63981,64039,64097,
    4406             :    64155,64212,64270,64328,64385,64443,64500,64557,
    4407             :    64614,64672,64729,64786,64843,64900,64956,65013,
    4408             :    65070,65126,65183,65239,65296,65352,65409,65465
    4409             : };
    4410             : 
    4411             : const png_byte png_sRGB_delta[512] =
    4412             : {
    4413             :    207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
    4414             :    52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
    4415             :    35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
    4416             :    28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
    4417             :    23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
    4418             :    21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
    4419             :    19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
    4420             :    17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
    4421             :    16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
    4422             :    15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
    4423             :    14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
    4424             :    13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
    4425             :    12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
    4426             :    12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
    4427             :    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
    4428             :    11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
    4429             :    11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
    4430             :    10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
    4431             :    10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
    4432             :    10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
    4433             :    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
    4434             :    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
    4435             :    9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
    4436             :    9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    4437             :    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    4438             :    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    4439             :    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    4440             :    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
    4441             :    8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
    4442             :    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    4443             :    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    4444             :    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
    4445             : };
    4446             : #endif /* SIMPLIFIED READ/WRITE sRGB support */
    4447             : 
    4448             : /* SIMPLIFIED READ/WRITE SUPPORT */
    4449             : #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
    4450             :    defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
    4451             : static int
    4452             : png_image_free_function(png_voidp argument)
    4453             : {
    4454             :    png_imagep image = png_voidcast(png_imagep, argument);
    4455             :    png_controlp cp = image->opaque;
    4456             :    png_control c;
    4457             : 
    4458             :    /* Double check that we have a png_ptr - it should be impossible to get here
    4459             :     * without one.
    4460             :     */
    4461             :    if (cp->png_ptr == NULL)
    4462             :       return 0;
    4463             : 
    4464             :    /* First free any data held in the control structure. */
    4465             : #  ifdef PNG_STDIO_SUPPORTED
    4466             :       if (cp->owned_file != 0)
    4467             :       {
    4468             :          FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
    4469             :          cp->owned_file = 0;
    4470             : 
    4471             :          /* Ignore errors here. */
    4472             :          if (fp != NULL)
    4473             :          {
    4474             :             cp->png_ptr->io_ptr = NULL;
    4475             :             (void)fclose(fp);
    4476             :          }
    4477             :       }
    4478             : #  endif
    4479             : 
    4480             :    /* Copy the control structure so that the original, allocated, version can be
    4481             :     * safely freed.  Notice that a png_error here stops the remainder of the
    4482             :     * cleanup, but this is probably fine because that would indicate bad memory
    4483             :     * problems anyway.
    4484             :     */
    4485             :    c = *cp;
    4486             :    image->opaque = &c;
    4487             :    png_free(c.png_ptr, cp);
    4488             : 
    4489             :    /* Then the structures, calling the correct API. */
    4490             :    if (c.for_write != 0)
    4491             :    {
    4492             : #     ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
    4493             :          png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
    4494             : #     else
    4495             :          png_error(c.png_ptr, "simplified write not supported");
    4496             : #     endif
    4497             :    }
    4498             :    else
    4499             :    {
    4500             : #     ifdef PNG_SIMPLIFIED_READ_SUPPORTED
    4501             :          png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
    4502             : #     else
    4503             :          png_error(c.png_ptr, "simplified read not supported");
    4504             : #     endif
    4505             :    }
    4506             : 
    4507             :    /* Success. */
    4508             :    return 1;
    4509             : }
    4510             : 
    4511             : void PNGAPI
    4512             : png_image_free(png_imagep image)
    4513             : {
    4514             :    /* Safely call the real function, but only if doing so is safe at this point
    4515             :     * (if not inside an error handling context).  Otherwise assume
    4516             :     * png_safe_execute will call this API after the return.
    4517             :     */
    4518             :    if (image != NULL && image->opaque != NULL &&
    4519             :       image->opaque->error_buf == NULL)
    4520             :    {
    4521             :       /* Ignore errors here: */
    4522             :       (void)png_safe_execute(image, png_image_free_function, image);
    4523             :       image->opaque = NULL;
    4524             :    }
    4525             : }
    4526             : 
    4527             : int /* PRIVATE */
    4528             : png_image_error(png_imagep image, png_const_charp error_message)
    4529             : {
    4530             :    /* Utility to log an error. */
    4531             :    png_safecat(image->message, (sizeof image->message), 0, error_message);
    4532             :    image->warning_or_error |= PNG_IMAGE_ERROR;
    4533             :    png_image_free(image);
    4534             :    return 0;
    4535             : }
    4536             : 
    4537             : #endif /* SIMPLIFIED READ/WRITE */
    4538             : #endif /* READ || WRITE */

Generated by: LCOV version 1.13