14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* png.c - location for general purpose libpng functions 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Last changed in libpng 1.6.19 [November 12, 2015] 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This code is released under the libpng license. 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For conditions of distribution and use, see the disclaimer 114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and license in png.h 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "pngpriv.h" 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Generate a compiler error if there is an old png.h in the search path. */ 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmanntypedef png_libpng_version_1_6_22 Your_png_h_is_not_version_1_6_22; 184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Tells libpng that we have already handled the first "num_bytes" bytes 204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of the PNG file signature. If the PNG data is embedded into another 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * stream we can set num_bytes = 8 so that libpng will not attempt to read 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or write any of the magic bytes before it starts on the IHDR. 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_sig_bytes(png_structrp png_ptr, int num_bytes) 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int nb = (unsigned int)num_bytes; 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_set_sig_bytes"); 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num_bytes < 0) 374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann nb = 0; 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nb > 8) 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "Too many bytes for PNG signature"); 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->sig_bytes = (png_byte)nb; 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Checks whether the supplied bytes match the PNG signature. We allow 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * checking less than the full 8-byte signature so that those apps that 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * already read the first few bytes of a file to determine the file type 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * can simply check the remaining bytes for extra assurance. Returns 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * an integer less than, equal to, or greater than zero if sig is found, 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * respectively, to be less than, to match, or be greater than the correct 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG signature (this is the same behavior as strcmp, memcmp, etc). 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num_to_check > 8) 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_to_check = 8; 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (num_to_check < 1) 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (-1); 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (start > 7) 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (-1); 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (start + num_to_check > 8) 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_to_check = 8 - start; 694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */ 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to allocate memory for zlib */ 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(voidpf /* PRIVATE */, 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_alloc_size_t num_bytes = size; 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return NULL; 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (items >= (~(png_alloc_size_t)0)/size) 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning (png_voidcast(png_structrp, png_ptr), 884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Potential overflow in png_zalloc()"); 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return NULL; 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_bytes *= items; 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to free memory for zlib */ 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zfree(voidpf png_ptr, voidpf ptr) 994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_voidcast(png_const_structrp,png_ptr), ptr); 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Reset the CRC variable to 32 bits of 1's. Care must be taken 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in case CRC is > 32 bits to leave the top bits 0. 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reset_crc(png_structrp png_ptr) 1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The cast is safe because the crc is a 32-bit value. */ 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Calculate the CRC over a section of data. We can only pass as 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * much data to this routine as the largest single buffer size. We 1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * also check that this data will actually be used before going to the 1164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * trouble of calculating it. 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) 1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int need_crc = 1; 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann need_crc = 0; 1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* critical */ 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann need_crc = 0; 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 'uLong' is defined in zlib.h as unsigned long; this means that on some 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * systems it is a 64-bit value. crc32, however, returns 32 bits so the 1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * following cast is safe. 'uInt' may be no more than 16 bits, so it is 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * necessary to perform a loop here. 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (need_crc != 0 && length > 0) 1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uLong crc = png_ptr->crc; /* Should never issue a warning */ 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uInt safe_length = (uInt)length; 1484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef __COVERITY__ 1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (safe_length == 0) 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann safe_length = (uInt)-1; /* evil, but safe */ 1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann crc = crc32(crc, ptr, safe_length); 1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following should never issue compiler warnings; if they do the 1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * target system has characteristics that will probably violate other 1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * assumptions within the libpng code. 1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptr += safe_length; 1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann length -= safe_length; 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (length > 0); 1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And the following is always safe because the crc is only 32 bits. */ 1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->crc = (png_uint_32)crc; 1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Check a user supplied version number, called from both read and write 1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * functions that create a png_struct. 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Libpng versions 1.0.0 and later are binary compatible if the version 1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * string matches through the second '.'; we must recompile any 1774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * applications that use any older library version. 1784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 1794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (user_png_ver != NULL) 1814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i = -1; 1834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int found_dots = 0; 1844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do 1864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 1874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann i++; 1884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) 1894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 1904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (user_png_ver[i] == '.') 1914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann found_dots++; 1924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } while (found_dots < 2 && user_png_ver[i] != 0 && 1934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_LIBPNG_VER_STRING[i] != 0); 1944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 1974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 1984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0) 2004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_WARNINGS_SUPPORTED 2024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size_t pos = 0; 2034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char m[128]; 2044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(m, (sizeof m), pos, 2064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Application built with libpng-"); 2074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(m, (sizeof m), pos, user_png_ver); 2084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(m, (sizeof m), pos, " but running with "); 2094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); 2104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(pos) 2114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, m); 2134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_ERROR_NUMBERS_SUPPORTED 2164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->flags = 0; 2174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 2184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 2204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 2214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Success return. */ 2234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 2244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 2254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Generic function to create a png_struct for either read or write - this 2274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contains the common initialization. 2284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_structp /* PRIVATE */, 2304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, 2314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 2324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) 2334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 2344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_struct create_struct; 2354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SETJMP_SUPPORTED 2364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann jmp_buf create_jmp_buf; 2374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This temporary stack-allocated structure is used to provide a place to 2404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * build enough context to allow the user provided memory allocator (if any) 2414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to be called. 2424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(&create_struct, 0, (sizeof create_struct)); 2444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Added at libpng-1.2.6 */ 2464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_USER_LIMITS_SUPPORTED 2474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.user_width_max = PNG_USER_WIDTH_MAX; 2484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.user_height_max = PNG_USER_HEIGHT_MAX; 2494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_USER_CHUNK_CACHE_MAX 2514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Added at libpng-1.2.43 and 1.4.0 */ 2524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; 2534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_USER_CHUNK_MALLOC_MAX 2564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists 2574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in png_struct regardless. 2584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; 2604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following two API calls simply set fields in png_struct, so it is safe 2644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to do them now even though error handling is not yet set up. 2654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_USER_MEM_SUPPORTED 2674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); 2684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 2694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(mem_ptr) 2704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(malloc_fn) 2714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(free_fn) 2724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* (*error_fn) can return control to the caller after the error_ptr is set, 2754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this will result in a memory leak unless the error_fn does something 2764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * extremely sophisticated. The design lacks merit but is implicit in the 2774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * API. 2784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); 2804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SETJMP_SUPPORTED 2824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!setjmp(create_jmp_buf)) 2834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SETJMP_SUPPORTED 2864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Temporarily fake out the longjmp information until we have 2874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * successfully completed this function. This only works if we have 2884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * setjmp() support compiled in, but it is safe - this stuff should 2894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * never happen. 2904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.jmp_buf_ptr = &create_jmp_buf; 2924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.jmp_buf_size = 0; /*stack allocation*/ 2934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.longjmp_fn = longjmp; 2944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 2954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Call the general version checker (shared with read and write code): 2964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 2974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_user_version_check(&create_struct, user_png_ver) != 0) 2984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 2994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_structrp png_ptr = png_voidcast(png_structrp, 3004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_malloc_warn(&create_struct, (sizeof *png_ptr))); 3014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 3034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* png_ptr->zstream holds a back-pointer to the png_struct, so 3054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this can only be done now: 3064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.zstream.zalloc = png_zalloc; 3084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.zstream.zfree = png_zfree; 3094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.zstream.opaque = png_ptr; 3104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SETJMP_SUPPORTED 3124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Eliminate the local error handling: */ 3134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.jmp_buf_ptr = NULL; 3144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.jmp_buf_size = 0; 3154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann create_struct.longjmp_fn = 0; 3164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 3174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *png_ptr = create_struct; 3194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is the successful return point */ 3214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_ptr; 3224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* A longjmp because of a bug in the application storage allocator or a 3274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * simple failure to allocate the png_struct. 3284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return NULL; 3304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Allocate the memory for an info_struct for the application. */ 3334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(png_infop,PNGAPI 3344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) 3354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 3364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr; 3374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_create_info_struct"); 3394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 3414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return NULL; 3424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Use the internal API that does not (or at least should not) error out, so 3444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that this call always returns ok. The application typically sets up the 3454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * error handling *after* creating the info_struct because this is the way it 3464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * has always been done in 'example.c'. 3474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, 3494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (sizeof *info_ptr))); 3504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr != NULL) 3524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(info_ptr, 0, (sizeof *info_ptr)); 3534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return info_ptr; 3554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function frees the memory associated with a single info struct. 3584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Normally, one would use either png_destroy_read_struct() or 3594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_destroy_write_struct() to free an info struct, but this may be 3604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * useful for some applications. From libpng 1.6.0 this function is also used 3614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * internally to implement the png_info release part of the 'struct' destroy 3624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * APIs. This ensures that all possible approaches free the same data (all of 3634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it). 3644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 3664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) 3674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 3684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = NULL; 3694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_destroy_info_struct"); 3714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 3734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 3744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr_ptr != NULL) 3764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr = *info_ptr_ptr; 3774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr != NULL) 3794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 3804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do this first in case of an error below; if the app implements its own 3814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * memory management this can lead to png_free calling png_error, which 3824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * will abort this routine and return control to the app error handler. 3834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * An infinite loop may result if it then tries to free the same info 3844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ptr. 3854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 3864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *info_ptr_ptr = NULL; 3874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 3894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(info_ptr, 0, (sizeof *info_ptr)); 3904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr); 3914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 3924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 3934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize the info structure. This is now an internal function (0.89) 3954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and applications using it are urged to use png_create_info_struct() 3964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * instead. Use deprecated in 1.6.0, internal use removed (used internally it 3974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is just a memset). 3984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 3994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: it is almost inconceivable that this API is used because it bypasses 4004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the user-memory mechanism and the user error handling/warning mechanisms in 4014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * those cases where it does anything other than a memset. 4024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 4034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FUNCTION(void,PNGAPI 4044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), 4054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_DEPRECATED) 4064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 4074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_inforp info_ptr = *ptr_ptr; 4084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_info_init_3"); 4104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr == NULL) 4124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((sizeof (png_info)) > png_info_struct_size) 4154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ptr_ptr = NULL; 4174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following line is why this API should not be used: */ 4184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann free(info_ptr); 4194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, 4204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (sizeof *info_ptr))); 4214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr == NULL) 4224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ptr_ptr = info_ptr; 4244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Set everything to 0 */ 4274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann memset(info_ptr, 0, (sizeof *info_ptr)); 4284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following API is not called internally */ 4314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 4324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, 4334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int freer, png_uint_32 mask) 4344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 4354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_data_freer"); 4364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL || info_ptr == NULL) 4384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (freer == PNG_DESTROY_WILL_FREE_DATA) 4414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->free_me |= mask; 4424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (freer == PNG_USER_WILL_FREE_DATA) 4444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->free_me &= ~mask; 4454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 4474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "Unknown freer parameter in png_data_freer"); 4484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 4494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 4514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, 4524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int num) 4534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 4544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_free_data"); 4554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL || info_ptr == NULL) 4574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 4584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_TEXT_SUPPORTED 4604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free text item num or (if num == -1) all text items */ 4614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->text != 0 && 4624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) 4634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num != -1) 4654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->text[num].key); 4674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->text[num].key = NULL; 4684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 4714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 4734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < info_ptr->num_text; i++) 4754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->text[i].key); 4764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->text); 4784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->text = NULL; 4794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->num_text = 0; 4804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_tRNS_SUPPORTED 4854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any tRNS entry */ 4864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) 4874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_tRNS; 4894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->trans_alpha); 4904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->trans_alpha = NULL; 4914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->num_trans = 0; 4924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 4934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 4944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sCAL_SUPPORTED 4964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any sCAL entry */ 4974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) 4984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 4994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->scal_s_width); 5004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->scal_s_height); 5014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->scal_s_width = NULL; 5024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->scal_s_height = NULL; 5034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_sCAL; 5044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_pCAL_SUPPORTED 5084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any pCAL entry */ 5094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) 5104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->pcal_purpose); 5124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->pcal_units); 5134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->pcal_purpose = NULL; 5144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->pcal_units = NULL; 5154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->pcal_params != NULL) 5174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 5194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < info_ptr->pcal_nparams; i++) 5214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->pcal_params[i]); 5224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->pcal_params); 5244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->pcal_params = NULL; 5254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_pCAL; 5274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_iCCP_SUPPORTED 5314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any profile entry */ 5324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) 5334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->iccp_name); 5354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->iccp_profile); 5364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->iccp_name = NULL; 5374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->iccp_profile = NULL; 5384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_iCCP; 5394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sPLT_SUPPORTED 5434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ 5444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->splt_palettes != 0 && 5454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) 5464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num != -1) 5484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->splt_palettes[num].name); 5504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->splt_palettes[num].entries); 5514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->splt_palettes[num].name = NULL; 5524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->splt_palettes[num].entries = NULL; 5534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 5564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 5584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < info_ptr->splt_palettes_num; i++) 5604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->splt_palettes[i].name); 5624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->splt_palettes[i].entries); 5634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->splt_palettes); 5664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->splt_palettes = NULL; 5674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->splt_palettes_num = 0; 5684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_sPLT; 5694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED 5744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->unknown_chunks != 0 && 5754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) 5764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num != -1) 5784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->unknown_chunks[num].data); 5804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->unknown_chunks[num].data = NULL; 5814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 5844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 5854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 5864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < info_ptr->unknown_chunks_num; i++) 5884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->unknown_chunks[i].data); 5894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->unknown_chunks); 5914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->unknown_chunks = NULL; 5924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->unknown_chunks_num = 0; 5934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 5954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 5964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_hIST_SUPPORTED 5984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any hIST entry */ 5994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) 6004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->hist); 6024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->hist = NULL; 6034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_hIST; 6044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 6064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any PLTE entry that was internally allocated */ 6084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) 6094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->palette); 6114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->palette = NULL; 6124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_PLTE; 6134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->num_palette = 0; 6144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_INFO_IMAGE_SUPPORTED 6174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Free any image bits attached to the info structure */ 6184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) 6194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr->row_pointers != 0) 6214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 6224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 row; 6234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (row = 0; row < info_ptr->height; row++) 6244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->row_pointers[row]); 6254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, info_ptr->row_pointers); 6274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->row_pointers = NULL; 6284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_IDAT; 6304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 6314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 6324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num != -1) 6344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mask &= ~PNG_FREE_MUL; 6354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->free_me &= ~mask; 6374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */ 6394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function returns a pointer to the io_ptr associated with the user 6414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * functions. The application should free any memory associated with this 6424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pointer before png_write_destroy() or png_read_destroy() are called. 6434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_voidp PNGAPI 6454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_io_ptr(png_const_structrp png_ptr) 6464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 6484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (NULL); 6494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_ptr->io_ptr); 6514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 6544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_STDIO_SUPPORTED 6554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Initialize the default input/output functions for the PNG file. If you 6564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * use your own read or write routines, you can call either png_set_read_fn() 6574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or png_set_write_fn() instead of png_init_io(). If you have defined 6584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a 6594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * function of your own because "FILE *" isn't necessarily available. 6604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 6624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_init_io(png_structrp png_ptr, png_FILE_p fp) 6634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_init_io"); 6654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 6674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 6684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->io_ptr = (png_voidp)fp; 6704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 6724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SAVE_INT_32_SUPPORTED 6744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 6754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * defines a cast of a signed integer to an unsigned integer either to preserve 6764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the value, if it is positive, or to calculate: 6774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (UNSIGNED_MAX+1) + integer 6794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the 6814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * negative integral value is added the result will be an unsigned value 6824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correspnding to the 2's complement representation. 6834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 6854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_save_int_32(png_bytep buf, png_int_32 i) 6864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_save_uint_32(buf, i); 6884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 6894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 6904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_TIME_RFC1123_SUPPORTED 6924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Convert the supplied time into an RFC 1123 string suitable for use in 6934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a "Creation Time" or other text-based time string. 6944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 6954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 6964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) 6974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 6984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann static PNG_CONST char short_months[12][4] = 6994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 7004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 7014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (out == NULL) 7034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 7044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ptime->year > 9999 /* RFC1123 limitation */ || 7064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptime->month == 0 || ptime->month > 12 || 7074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptime->day == 0 || ptime->day > 31 || 7084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptime->hour > 23 || ptime->minute > 59 || 7094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ptime->second > 60) 7104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 7114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size_t pos = 0; 7144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char number_buf[5]; /* enough for a four-digit year */ 7154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) 7174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define APPEND_NUMBER(format, value)\ 7184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) 7194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define APPEND(ch) if (pos < 28) out[pos++] = (ch) 7204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); 7224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND(' '); 7234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_STRING(short_months[(ptime->month - 1)]); 7244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND(' '); 7254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); 7264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND(' '); 7274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); 7284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND(':'); 7294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); 7304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND(':'); 7314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); 7324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ 7334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED (pos) 7344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# undef APPEND 7364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# undef APPEND_NUMBER 7374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# undef APPEND_STRING 7384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 7414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 7424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_LIBPNG_VER < 10700 7444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* To do: remove the following from libpng-1.7 */ 7454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Original API that uses a private buffer in png_struct. 7464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Deprecated because it causes png_struct to carry a spurious temporary 7474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * buffer (png_struct::time_buffer), better to have the caller pass this in. 7484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 7494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI 7504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) 7514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 7524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL) 7534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 7544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The only failure above if png_ptr != NULL is from an invalid ptime */ 7554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0) 7564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Ignoring invalid time value"); 7574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 7594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_ptr->time_buffer; 7604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 7614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return NULL; 7634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 7644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif /* LIBPNG_VER < 10700 */ 7654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif /* TIME_RFC1123 */ 7664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */ 7684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI 7704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_copyright(png_const_structrp png_ptr) 7714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 7724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 7734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_STRING_COPYRIGHT 7744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_STRING_COPYRIGHT 7754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 7764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef __STDC__ 7774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_STRING_NEWLINE \ 7784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "libpng version 1.6.22 - May 26, 2016" PNG_STRING_NEWLINE \ 7794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \ 7804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_STRING_NEWLINE \ 7814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ 7824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ 7834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_STRING_NEWLINE; 7844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 7854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return "libpng version 1.6.22 - May 26, 2016\ 7864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\ 7874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Copyright (c) 1996-1997 Andreas Dilger\ 7884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; 7894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 7904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 7914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 7924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following return the library version as a short string in the 7944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * format 1.0.0 through 99.99.99zz. To get the version of *.h files 7954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * used with your application, print out PNG_LIBPNG_VER_STRING, which 7964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is defined in png.h. 7974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Note: now there is no difference between png_get_libpng_ver() and 7984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, 7994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is guaranteed that png.c uses the correct version of png.h. 8004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 8014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI 8024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_libpng_ver(png_const_structrp png_ptr) 8034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 8044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Version of *.c files used when building libpng */ 8054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_get_header_ver(png_ptr); 8064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 8074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI 8094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_header_ver(png_const_structrp png_ptr) 8104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 8114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Version of *.h files used when building libpng */ 8124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 8134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_LIBPNG_VER_STRING; 8144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 8154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_const_charp PNGAPI 8174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_get_header_version(png_const_structrp png_ptr) 8184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 8194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Returns longer string containing both version and date */ 8204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 8214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef __STDC__ 8224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_HEADER_VERSION_STRING 8234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifndef PNG_READ_SUPPORTED 8244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann " (NO READ SUPPORT)" 8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 8264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_STRING_NEWLINE; 8274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 8284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_HEADER_VERSION_STRING; 8294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 8314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED 8334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* NOTE: this routine is not used internally! */ 8344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth 8354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * large of png_color. This lets grayscale images be treated as 8364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * paletted. Most useful for gamma correction and simplification 8374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of code. This API is not used internally. 8384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 8394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 8404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_grayscale_palette(int bit_depth, png_colorp palette) 8414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 8424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int num_palette; 8434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int color_inc; 8444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 8454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int v; 8464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_do_build_grayscale_palette"); 8484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (palette == NULL) 8504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 8514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (bit_depth) 8534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 8544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_palette = 2; 8564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_inc = 0xff; 8574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 8584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 2: 8604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_palette = 4; 8614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_inc = 0x55; 8624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 8634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 4: 8654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_palette = 16; 8664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_inc = 0x11; 8674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 8684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 8: 8704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_palette = 256; 8714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_inc = 1; 8724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 8734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 8754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num_palette = 0; 8764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_inc = 0; 8774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 8784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 8794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0, v = 0; i < num_palette; i++, v += color_inc) 8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 8824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann palette[i].red = (png_byte)(v & 0xff); 8834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann palette[i].green = (png_byte)(v & 0xff); 8844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann palette[i].blue = (png_byte)(v & 0xff); 8854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 8864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 8874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 8884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 8904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 8914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) 8924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 8934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check chunk_name and return "keep" value if it's on the list, else 0 */ 8944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep p, p_end; 8954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) 8974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_HANDLE_CHUNK_AS_DEFAULT; 8984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p_end = png_ptr->chunk_list; 9004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ 9014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The code is the fifth byte after each four byte string. Historically this 9034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * code was always searched from the end of the list, this is no longer 9044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * necessary because the 'set' routine handles duplicate entries correcty. 9054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do /* num_chunk_list > 0, so at least one */ 9074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 9084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann p -= 5; 9094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (memcmp(chunk_name, p, 4) == 0) 9114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return p[4]; 9124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 9134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (p > p_end); 9144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This means that known chunks should be processed and unknown chunks should 9164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be handled according to the value of png_ptr->unknown_default; this can be 9174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * confusing because, as a result, there are two levels of defaulting for 9184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * unknown chunks. 9194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_HANDLE_CHUNK_AS_DEFAULT; 9214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ 9244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) 9254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 9264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) 9274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte chunk_string[5]; 9294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); 9314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_handle_as_unknown(png_ptr, chunk_string); 9324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ 9344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SET_UNKNOWN_CHUNKS */ 9354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED 9374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function, added to libpng-1.0.6g, is untested. */ 9384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 9394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reset_zstream(png_structrp png_ptr) 9404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr == NULL) 9424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return Z_STREAM_ERROR; 9434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* WARNING: this resets the window bits to the maximum! */ 9454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (inflateReset(&png_ptr->zstream)); 9464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ */ 9484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This function was added to libpng-1.0.7 */ 9504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_32 PNGAPI 9514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_access_version_number(void) 9524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Version of *.c files used when building libpng */ 9544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return((png_uint_32)PNG_LIBPNG_VER); 9554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 9564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 9584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. 9594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * If it doesn't 'ret' is used to set it to something appropriate, even in cases 9604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * like Z_OK or Z_STREAM_END where the error code is apparently a success code. 9614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 9634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_zstream_error(png_structrp png_ptr, int ret) 9644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 9654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Translate 'ret' into an appropriate error string, priority is given to the 9664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * one in zstream if set. This always returns a string, even in cases like 9674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Z_OK or Z_STREAM_END where the error code is a success code. 9684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->zstream.msg == NULL) switch (ret) 9704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 9714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 9724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_OK: 9734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); 9744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 9754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_STREAM_END: 9774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Normal exit */ 9784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); 9794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 9804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_NEED_DICT: 9824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This means the deflate stream did not have a dictionary; this 9834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * indicates a bogus PNG. 9844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 9854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); 9864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 9874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_ERRNO: 9894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* gz APIs only: should not happen */ 9904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); 9914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 9924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_STREAM_ERROR: 9944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* internal libpng error */ 9954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); 9964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 9974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_DATA_ERROR: 9994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); 10004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 10014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_MEM_ERROR: 10034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); 10044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 10054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_BUF_ERROR: 10074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* End of input or output; not a problem if the caller is doing 10084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * incremental read or write. 10094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); 10114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 10124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case Z_VERSION_ERROR: 10144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); 10154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 10164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_UNEXPECTED_ZLIB_RETURN: 10184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Compile errors here mean that zlib now uses the value co-opted in 10194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above 10204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and change pngpriv.h. Note that this message is "... return", 10214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * whereas the default/Z_OK one is "... return code". 10224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); 10244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 10254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 10264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 10274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* png_convert_size: a PNGAPI but no longer in png.h, so deleted 10294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * at libpng 1.5.5! 10304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ 10334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ 10344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 10354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_gamma(png_const_structrp png_ptr, 10364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, png_fixed_point gAMA, int from) 10374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is called to check a new gamma value against an existing one. The 10384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * routine returns false if the new gamma value should not be written. 10394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 10404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'from' says where the new gamma value comes from: 10414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 10424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0: the new gamma value is the libpng estimate for an ICC profile 10434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1: the new gamma value comes from a gAMA chunk 10444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 2: the new gamma value comes from an sRGB chunk 10454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 10474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point gtest; 10484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && 10504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || 10514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_gamma_significant(gtest) != 0)) 10524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 10534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Either this is an sRGB image, in which case the calculated gamma 10544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * approximation should match, or this is an image with a profile and the 10554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value libpng calculates for the gamma of the profile does not match the 10564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value recorded in the file. The former, sRGB, case is an error, the 10574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * latter is just a warning. 10584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) 10604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 10614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, "gamma value does not match sRGB", 10624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_ERROR); 10634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do not overwrite an sRGB value */ 10644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return from == 2; 10654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 10664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else /* sRGB tag not involved */ 10684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 10694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, "gamma value does not match libpng estimate", 10704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_WARNING); 10714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return from == 1; 10724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 10734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 10744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 10764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 10774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 10794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_gamma(png_const_structrp png_ptr, 10804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, png_fixed_point gAMA) 10814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 10824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't 10834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * occur. Since the fixed point representation is asymetrical it is 10844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * possible for 1/gamma to overflow the limit of 21474 and this means the 10854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * gamma value must be at least 5/100000 and hence at most 20000.0. For 10864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * safety the limits here are a little narrower. The values are 0.00016 to 10874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6250.0, which are truly ridiculous gamma values (and will produce 10884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * displays that are all black or all white.) 10894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 10904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk 10914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * handling code, which only required the value to be >0. 10924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 10934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp errmsg; 10944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (gAMA < 16 || gAMA > 625000000) 10964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann errmsg = "gamma value out of range"; 10974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_READ_gAMA_SUPPORTED 10994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Allow the application to set the gamma value more than once */ 11004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && 11014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) 11024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann errmsg = "duplicate"; 11034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 11044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do nothing if the colorspace is already invalid */ 11064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) 11074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 11084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 11104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 11114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 11124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1/*from gAMA*/) != 0) 11134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 11144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Store this gamma value. */ 11154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->gamma = gAMA; 11164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= 11174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); 11184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 11194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* At present if the check_gamma test fails the gamma of the colorspace is 11214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * not updated however the colorspace is not invalidated. This 11224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * corresponds to the case where the existing gamma comes from an sRGB 11234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunk or profile. An error message has already been output. 11244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 11264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 11274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Error exit - errmsg has been set. */ 11294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 11304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); 11314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 11324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 11344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) 11354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 11364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) 11374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 11384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Everything is invalid */ 11394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| 11404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_INFO_iCCP); 11414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_COLORSPACE_SUPPORTED 11434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Clean up the iCCP profile now if it won't be used. */ 11444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); 11454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 11464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(png_ptr) 11474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 11484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 11494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 11514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 11524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_COLORSPACE_SUPPORTED 11534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Leave the INFO_iCCP flag set if the pngset.c code has already set 11544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it; this allows a PNG to contain a profile which matches sRGB and 11554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * yet still have that profile retrievable by the application. 11564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) 11584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid |= PNG_INFO_sRGB; 11594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 11614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_sRGB; 11624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 11644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid |= PNG_INFO_cHRM; 11654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 11674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_cHRM; 11684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 11694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) 11714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid |= PNG_INFO_gAMA; 11724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 11744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->valid &= ~PNG_INFO_gAMA; 11754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 11764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 11774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_SUPPORTED 11794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 11804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) 11814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 11824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (info_ptr == NULL) /* reduce code size; check here not in the caller */ 11834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 11844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann info_ptr->colorspace = png_ptr->colorspace; 11864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspace_sync_info(png_ptr, info_ptr); 11874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 11884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 11894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* GAMMA */ 11904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_COLORSPACE_SUPPORTED 11924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for 11934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * cHRM, as opposed to using chromaticities. These internal APIs return 11944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * non-zero on a parameter error. The X, Y and Z values are required to be 11954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * positive and less than 1.0. 11964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 11974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 11984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) 11994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 12004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 d, dwhite, whiteX, whiteY; 12014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; 12034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) 12044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) 12064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dwhite = d; 12084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteX = XYZ->red_X; 12094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteY = XYZ->red_Y; 12104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; 12124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) 12134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) 12154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dwhite += d; 12174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteX += XYZ->green_X; 12184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteY += XYZ->green_Y; 12194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; 12214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) 12224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) 12244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann dwhite += d; 12264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteX += XYZ->blue_X; 12274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann whiteY += XYZ->blue_Y; 12284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, 12304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * thus: 12314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) 12334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) 12354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 12364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 12384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 12394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 12414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) 12424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 12434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point red_inverse, green_inverse, blue_scale; 12444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point left, right, denominator; 12454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check xy and, implicitly, z. Note that wide gamut color spaces typically 12474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * have end points with 0 tristimulus values (these are impossible end 12484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * points, but they are used to cover the possible colors). We check 12494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * xy->whitey against 5, not 0, to avoid a possible integer overflow. 12504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 12514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; 12524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; 12534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; 12544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; 12554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; 12564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; 12574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; 12584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1; 12594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The reverse calculation is more difficult because the original tristimulus 12614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 12624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * derived values were recorded in the cHRM chunk; 12634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (red,green,blue,white)x(x,y). This loses one degree of freedom and 12644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * therefore an arbitrary ninth value has to be introduced to undo the 12654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * original transformations. 12664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Think of the original end-points as points in (X,Y,Z) space. The 12684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chromaticity values (c) have the property: 12694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * C 12714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * c = --------- 12724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * X + Y + Z 12734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the 12754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * three chromaticity values (x,y,z) for each end-point obey the 12764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * relationship: 12774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * x + y + z = 1 12794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This describes the plane in (X,Y,Z) space that intersects each axis at the 12814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value 1.0; call this the chromaticity plane. Thus the chromaticity 12824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * calculation has scaled each end-point so that it is on the x+y+z=1 plane 12834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and chromaticity is the intersection of the vector from the origin to the 12844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (X,Y,Z) value with the chromaticity plane. 12854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To fully invert the chromaticity calculation we would need the three 12874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * end-point scale factors, (red-scale, green-scale, blue-scale), but these 12884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * were not recorded. Instead we calculated the reference white (X,Y,Z) and 12894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * recorded the chromaticity of this. The reference white (X,Y,Z) would have 12904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * given all three of the scale factors since: 12914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-C = color-c * color-scale 12934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-C = red-C + green-C + blue-C 12944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale 12954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * But cHRM records only white-x and white-y, so we have lost the white scale 12974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * factor: 12984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 12994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-C = white-c*white-scale 13004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To handle this the inverse transformation makes an arbitrary assumption 13024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * about white-scale: 13034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Assume: white-Y = 1.0 13054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Hence: white-scale = 1/white-y 13064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Or: red-Y + green-Y + blue-Y = 1.0 13074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Notice the last statement of the assumption gives an equation in three of 13094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the nine values we want to calculate. 8 more equations come from the 13104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * above routine as summarised at the top above (the chromaticity 13114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * calculation): 13124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Given: color-x = color-X / (color-X + color-Y + color-Z) 13144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 13154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This is 9 simultaneous equations in the 9 variables "color-C" and can be 13174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix 13184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * determinants, however this is not as bad as it seems because only 28 of 13194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the total of 90 terms in the various matrices are non-zero. Nevertheless 13204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Cramer's rule is notoriously numerically unstable because the determinant 13214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * calculation involves the difference of large, but similar, numbers. It is 13224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * difficult to be sure that the calculation is stable for real world values 13234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and it is certain that it becomes unstable where the end points are close 13244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * together. 13254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So this code uses the perhaps slightly less optimal but more 13274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * understandable and totally obvious approach of calculating color-scale. 13284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This algorithm depends on the precision in white-scale and that is 13304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (1/white-y), so we can immediately see that as white-y approaches 0 the 13314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * accuracy inherent in the cHRM chunk drops off substantially. 13324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng arithmetic: a simple inversion of the above equations 13344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ------------------------------------------------------------ 13354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white_scale = 1/white-y 13374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-X = white-x * white-scale 13384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-Y = 1.0 13394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-Z = (1 - white-x - white-y) * white_scale 13404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white-C = red-C + green-C + blue-C 13424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale 13434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This gives us three equations in (red-scale,green-scale,blue-scale) where 13454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * all the coefficients are now known: 13464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-x*red-scale + green-x*green-scale + blue-x*blue-scale 13484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * = white-x/white-y 13494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 13504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-z*red-scale + green-z*green-scale + blue-z*blue-scale 13514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * = (1 - white-x - white-y)/white-y 13524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * In the last equation color-z is (1 - color-x - color-y) so we can add all 13544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * three equations together to get an alternative third: 13554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-scale + green-scale + blue-scale = 1/white-y = white-scale 13574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So now we have a Cramer's rule solution where the determinants are just 13594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve 13604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * multiplication of three coefficients so we can't guarantee to avoid 13614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * overflow in the libpng fixed point representation. Using Cramer's rule in 13624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * floating point is probably a good choice here, but it's not an option for 13634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * fixed point. Instead proceed to simplify the first two equations by 13644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * eliminating what is likely to be the largest value, blue-scale: 13654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * blue-scale = white-scale - red-scale - green-scale 13674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Hence: 13694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = 13714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (white-x - blue-x)*white-scale 13724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = 13744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1 - blue-y*white-scale 13754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * And now we can trivially solve for (red-scale,green-scale): 13774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * green-scale = 13794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale 13804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ----------------------------------------------------------- 13814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * green-x - blue-x 13824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-scale = 13844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale 13854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * --------------------------------------------------------- 13864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-y - blue-y 13874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Hence: 13894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red-scale = 13914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ( (green-x - blue-x) * (white-y - blue-y) - 13924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (green-y - blue-y) * (white-x - blue-x) ) / white-y 13934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ------------------------------------------------------------------------- 13944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) 13954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 13964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * green-scale = 13974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ( (red-y - blue-y) * (white-x - blue-x) - 13984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (red-x - blue-x) * (white-y - blue-y) ) / white-y 13994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ------------------------------------------------------------------------- 14004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) 14014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Accuracy: 14034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The input values have 5 decimal digits of accuracy. The values are all in 14044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the range 0 < value < 1, so simple products are in the same range but may 14054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * need up to 10 decimal digits to preserve the original precision and avoid 14064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * underflow. Because we are using a 32-bit signed representation we cannot 14074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * match this; the best is a little over 9 decimal digits, less than 10. 14084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The approach used here is to preserve the maximum precision within the 14104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * signed representation. Because the red-scale calculation above uses the 14114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * difference between two products of values that must be in the range -1..+1 14124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The 14134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * factor is irrelevant in the calculation because it is applied to both 14144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * numerator and denominator. 14154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Note that the values of the differences of the products of the 14174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chromaticities in the above equations tend to be small, for example for 14184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the sRGB chromaticities they are: 14194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * red numerator: -0.04751 14214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * green numerator: -0.08788 14224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * denominator: -0.2241 (without white-y multiplication) 14234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The resultant Y coefficients from the chromaticities of some widely used 14254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color space definitions are (to 15 decimal places): 14264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 14274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * sRGB 14284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0.212639005871510 0.715168678767756 0.072192315360734 14294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Kodak ProPhoto 14304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0.288071128229293 0.711843217810102 0.000085653960605 14314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Adobe RGB 14324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0.297344975250536 0.627363566255466 0.075291458493998 14334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Adobe Wide Gamut RGB 14344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0.258728243040113 0.724682314948566 0.016589442011321 14354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* By the argument, above overflow should be impossible here. The return 14374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value of 2 indicates an internal error to the caller. 14384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) 14404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) 14424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann denominator = left - right; 14444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now find the red numerator. */ 14464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) 14474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) 14494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Overflow is possible here and it indicates an extreme set of PNG cHRM 14524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunk values. This calculation actually returns the reciprocal of the 14534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * scale value because this allows us to delay the multiplication of white-y 14544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * into the denominator, which tends to produce a small number. 14554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || 14574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red_inverse <= xy->whitey /* r+g+b scales = white scale */) 14584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Similarly for green_inverse: */ 14614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) 14624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) 14644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; 14654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || 14664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green_inverse <= xy->whitey) 14674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And the blue scale, the checks above guarantee this can't overflow but it 14704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * can still produce 0 for extreme cHRM values. 14714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 14724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - 14734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_reciprocal(green_inverse); 14744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (blue_scale <= 0) 14754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And fill in the png_XYZ: */ 14794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) 14804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) 14824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, 14844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann red_inverse) == 0) 14854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) 14884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) 14904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, 14924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann green_inverse) == 0) 14934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) 14964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) 14984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 14994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, 15004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_FP_1) == 0) 15014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /*success*/ 15044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 15074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_XYZ_normalize(png_XYZ *XYZ) 15084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 Y; 15104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || 15124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || 15134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) 15144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. 15174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore 15184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * relying on addition of two positive values producing a negative one is not 15194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * safe. 15204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 15214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Y = XYZ->red_Y; 15224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (0x7fffffff - Y < XYZ->green_X) 15234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Y += XYZ->green_Y; 15254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (0x7fffffff - Y < XYZ->blue_X) 15264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann Y += XYZ->blue_Y; 15284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (Y != PNG_FP_1) 15304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 15314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) 15324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) 15344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) 15364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) 15394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) 15414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) 15434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) 15464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) 15484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) 15504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 15524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 15544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 15574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) 15584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ 15604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || 15614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || 15624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || 15634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || 15644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || 15654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || 15664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || 15674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) 15684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 15694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 15704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 15714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM 15734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chunk chromaticities. Earlier checks used to simply look for the overflow 15744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * condition (where the determinant of the matrix to solve for XYZ ends up zero 15754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * because the chromaticity values are not all distinct.) Despite this it is 15764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * theoretically possible to produce chromaticities that are apparently valid 15774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but that rapidly degrade to invalid, potentially crashing, sets because of 15784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * arithmetic inaccuracies when calculations are performed on them. The new 15794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * check is to round-trip xy -> XYZ -> xy and then check that the result is 15804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * within a small percentage of the original. 15814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 15824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 15834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) 15844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 15854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 15864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_xy xy_test; 15874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* As a side-effect this routine also returns the XYZ endpoints. */ 15894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_XYZ_from_xy(XYZ, xy); 15904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (result != 0) 15914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 15924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_xy_from_XYZ(&xy_test, XYZ); 15944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (result != 0) 15954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 15964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_colorspace_endpoints_match(xy, &xy_test, 15984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5/*actually, the math is pretty accurate*/) != 0) 15994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 16004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Too much slip */ 16024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 16034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 16044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This is the check going the other way. The XYZ is modified to normalize it 16064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (another side-effect) and the xy chromaticities are returned. 16074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 16094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) 16104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int result; 16124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_XYZ XYZtemp; 16134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_XYZ_normalize(XYZ); 16154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (result != 0) 16164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 16174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = png_xy_from_XYZ(xy, XYZ); 16194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (result != 0) 16204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 16214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann XYZtemp = *XYZ; 16234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_colorspace_check_xy(&XYZtemp, xy); 16244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 16254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Used to check for an endpoint match against sRGB */ 16274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ 16284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* color x y */ 16304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* red */ 64000, 33000, 16314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* green */ 30000, 60000, 16324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* blue */ 15000, 6000, 16334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* white */ 31270, 32900 16344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 16354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 16374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, 16384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, 16394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int preferred) 16404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) 16424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 16434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The consistency check is performed on the chromaticities; this factors out 16454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * variations because of the normalization (or not) of the end point Y 16464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values. 16474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (preferred < 2 && 16494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 16504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The end points must be reasonably close to any we already have. The 16524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * following allows an error of up to +/-.001 16534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 16554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 100) == 0) 16564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 16584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "inconsistent chromaticities"); 16594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* failed */ 16604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Only overwrite with preferred values */ 16634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (preferred == 0) 16644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; /* ok, but no change */ 16654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 16664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->end_points_xy = *xy; 16684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->end_points_XYZ = *XYZ; 16694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; 16704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The end points are normally quoted to two decimal digits, so allow +/-0.01 16724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * on this test. 16734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) 16754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; 16764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 16784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags &= PNG_COLORSPACE_CANCEL( 16794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); 16804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 2; /* ok and changed */ 16824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 16834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 16854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_chromaticities(png_const_structrp png_ptr, 16864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, const png_xy *xy, int preferred) 16874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 16884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We must check the end points to ensure they are reasonable - in the past 16894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color management systems have crashed as a result of getting bogus 16904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * colorant values, while this isn't the fault of libpng it is the 16914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * responsibility of libpng because PNG carries the bomb and libpng is in a 16924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * position to protect against it. 16934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 16944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_XYZ XYZ; 16954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_colorspace_check_xy(&XYZ, xy)) 16974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 16984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0: /* success */ 16994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, 17004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann preferred); 17014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 17034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We can't invert the chromaticities so we can't produce value XYZ 17044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values. Likely as not a color management system will fail too. 17054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 17074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "invalid chromaticities"); 17084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 17094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 17114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* libpng is broken; this should be a warning but if it happens we 17124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * want error reports so for the moment it is an error. 17134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 17144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 17154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "internal error checking chromaticities"); 17164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* failed */ 17194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 17224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_endpoints(png_const_structrp png_ptr, 17234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) 17244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_XYZ XYZ = *XYZ_in; 17264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_xy xy; 17274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (png_colorspace_check_XYZ(&xy, &XYZ)) 17294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 17304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0: 17314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, 17324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann preferred); 17334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 1: 17354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* End points are invalid. */ 17364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 17374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "invalid end points"); 17384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 17394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 17414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 17424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "internal error checking chromaticities"); 17434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 17444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* failed */ 17464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) 17494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Error message generation */ 17504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic char 17514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_tag_char(png_uint_32 byte) 17524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann byte &= 0xff; 17544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (byte >= 32 && byte <= 126) 17554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (char)byte; 17564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 17574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return '?'; 17584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 17614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_tag_name(char *name, png_uint_32 tag) 17624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[0] = '\''; 17644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[1] = png_icc_tag_char(tag >> 24); 17654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[2] = png_icc_tag_char(tag >> 16); 17664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[3] = png_icc_tag_char(tag >> 8); 17674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[4] = png_icc_tag_char(tag ); 17684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann name[5] = '\''; 17694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 17724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannis_ICC_signature_char(png_alloc_size_t it) 17734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || 17754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (it >= 97 && it <= 122); 17764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 17794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannis_ICC_signature(png_alloc_size_t it) 17804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && 17824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann is_ICC_signature_char((it >> 16) & 0xff) && 17834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann is_ICC_signature_char((it >> 8) & 0xff) && 17844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann is_ICC_signature_char(it & 0xff); 17854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 17864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 17884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, 17894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp name, png_alloc_size_t value, png_const_charp reason) 17904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 17914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size_t pos; 17924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char message[196]; /* see below for calculation */ 17934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (colorspace != NULL) 17954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_INVALID; 17964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ 17984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ 17994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ 18004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (is_ICC_signature(value) != 0) 18014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* So 'value' is at most 4 bytes and the following cast is safe */ 18034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_icc_tag_name(message+pos, (png_uint_32)value); 18044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos += 6; /* total +8; less than the else clause */ 18054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann message[pos++] = ':'; 18064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann message[pos++] = ' '; 18074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_WARNINGS_SUPPORTED 18094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 18104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ 18124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, (sizeof message), pos, 18144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_format_number(number, number+(sizeof number), 18154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_NUMBER_FORMAT_x, value)); 18164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ 18174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 18194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ 18204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pos = png_safecat(message, (sizeof message), pos, reason); 18214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(pos) 18224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is recoverable, but make it unconditionally an app_error on write to 18244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * avoid writing invalid ICC profiles into PNG files (i.e., we handle them 18254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * on read, with a warning, but on write unless the app turns off 18264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * application errors the PNG won't be written.) 18274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, message, 18294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); 18304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 18324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 18334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB || iCCP */ 18344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sRGB_SUPPORTED 18364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 18374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, 18384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int intent) 18394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 18404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* sRGB sets known gamma, end points and (from the chunk) intent. */ 18414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* IMPORTANT: these are not necessarily the values found in an ICC profile 18424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * because ICC profiles store values adapted to a D50 environment; it is 18434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * expected that the ICC profile mediaWhitePointTag will be D50; see the 18444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * checks and code elsewhere to understand this better. 18454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 18464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * These XYZ values, which are accurate to 5dp, produce rgb to gray 18474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * coefficients of (6968,23435,2366), which are reduced (because they add up 18484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to 32769 not 32768) to (6968,23434,2366). These are the values that 18494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * libpng has traditionally used (and are the best values given the 15bit 18504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * algorithm used by the rgb to gray code.) 18514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ 18534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* color X Y Z */ 18554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* red */ 41239, 21264, 1933, 18564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* green */ 35758, 71517, 11919, 18574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* blue */ 18048, 7219, 95053 18584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann }; 18594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Do nothing if the colorspace is already invalidated. */ 18614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) 18624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 18634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check the intent, then check for existing settings. It is valid for the 18654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must 18664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be consistent with the correct values. If, however, this function is 18674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * called below because an iCCP chunk matches sRGB then it is quite 18684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * conceivable that an older app recorded incorrect gAMA and cHRM because of 18694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * an incorrect calculation based on the values in the profile - this does 18704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * *not* invalidate the profile (though it still produces an error, which can 18714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be ignored.) 18724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) 18744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, "sRGB", 18754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (unsigned)intent, "invalid sRGB rendering intent"); 18764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && 18784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->rendering_intent != intent) 18794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, "sRGB", 18804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (unsigned)intent, "inconsistent rendering intents"); 18814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) 18834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 18844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_benign_error(png_ptr, "duplicate sRGB information ignored"); 18854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 18864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 18874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If the standard sRGB cHRM chunk does not match the one from the PNG file 18894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * warn but overwrite the value with the correct one. 18904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 18914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && 18924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, 18934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 100)) 18944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", 18954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_ERROR); 18964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This check is just done for the error reporting - the routine always 18984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * returns true when the 'from' argument corresponds to sRGB (2). 18994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, 19014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2/*from sRGB*/); 19024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* intent: bugs in GCC force 'int' to be used as the parameter type. */ 19044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->rendering_intent = (png_uint_16)intent; 19054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; 19064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* endpoints */ 19084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->end_points_xy = sRGB_xy; 19094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->end_points_XYZ = sRGB_XYZ; 19104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= 19114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); 19124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* gamma */ 19144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; 19154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; 19164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Finally record that we have an sRGB profile */ 19184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann colorspace->flags |= 19194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); 19204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; /* set */ 19224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB */ 19244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_iCCP_SUPPORTED 19264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value 19274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is XYZ(0.9642,1.0,0.8249), which scales to: 19284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 19294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (63189.8112, 65536, 54060.6464) 19304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_byte D50_nCIEXYZ[12] = 19324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; 19334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 19354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, 19364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp name, png_uint_32 profile_length) 19374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 19384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (profile_length < 132) 19394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, profile_length, 19404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "too short"); 19414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 19434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 19444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 19464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, 19474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp name, png_uint_32 profile_length, 19484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep profile/* first 132 bytes only */, int color_type) 19494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 19504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 temp; 19514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Length check; this cannot be ignored in this code because profile_length 19534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is used later to check the tag table, so even if the profile seems over 19544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * long profile_length from the caller must be correct. The caller can fix 19554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this up on read or write by just passing in the profile header length. 19564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile); 19584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp != profile_length) 19594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 19604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "length does not match profile"); 19614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = (png_uint_32) (*(profile+8)); 19634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp > 3 && (profile_length & 3)) 19644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, profile_length, 19654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "invalid length"); 19664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ 19684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ 19694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann profile_length < 132+12*temp) /* truncated tag table */ 19704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 19714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "tag count too large"); 19724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The 'intent' must be valid or we can't store it, ICC limits the intent to 19744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16 bits. 19754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+64); 19774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp >= 0xffff) /* The ICC limit */ 19784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 19794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "invalid rendering intent"); 19804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is just a warning because the profile may be valid in future 19824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * versions. 19834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp >= PNG_sRGB_INTENT_LAST) 19854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_icc_profile_error(png_ptr, NULL, name, temp, 19864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "intent outside defined range"); 19874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* At this point the tag table can't be checked because it hasn't necessarily 19894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * been loaded; however, various header fields can be checked. These checks 19904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * are for values permitted by the PNG spec in an ICC profile; the PNG spec 19914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * restricts the profiles that can be passed in an iCCP chunk (they must be 19924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * appropriate to processing PNG data!) 19934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 19944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Data checks (could be skipped). These checks must be independent of the 19964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * version number; however, the version number doesn't accomodate changes in 19974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the header fields (just the known tags and the interpretation of the 19984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * data.) 19994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+36); /* signature 'ascp' */ 20014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (temp != 0x61637370) 20024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "invalid signature"); 20044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Currently the PCS illuminant/adopted white point (the computational 20064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * white point) are required to be D50, 20074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * however the profile contains a record of the illuminant so perhaps ICC 20084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * expects to be able to change this in the future (despite the rationale in 20094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the introduction for using a fixed PCS adopted white.) Consequently the 20104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * following is just a warning. 20114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) 20134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, 20144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "PCS illuminant is not D50"); 20154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The PNG spec requires this: 20174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * "If the iCCP chunk is present, the image samples conform to the colour 20184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * space represented by the embedded ICC profile as defined by the 20194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * International Color Consortium [ICC]. The colour space of the ICC profile 20204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * shall be an RGB colour space for colour images (PNG colour types 2, 3, and 20214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 6), or a greyscale colour space for greyscale images (PNG colour types 0 20224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and 4)." 20234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 20244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This checking code ensures the embedded profile (on either read or write) 20254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * conforms to the specification requirements. Notice that an ICC 'gray' 20264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * color-space profile contains the information to transform the monochrome 20274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * data to XYZ or L*a*b (according to which PCS the profile uses) and this 20284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * should be used in preference to the standard libpng K channel replication 20294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * into R, G and B channels. 20304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 20314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Previously it was suggested that an RGB profile on grayscale data could be 20324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * handled. However it it is clear that using an RGB profile in this context 20334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * must be an error - there is no specification of what it means. Thus it is 20344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * almost certainly more correct to ignore the profile. 20354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+16); /* data colour space field */ 20374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (temp) 20384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x52474220: /* 'RGB ' */ 20404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((color_type & PNG_COLOR_MASK_COLOR) == 0) 20414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "RGB color space not permitted on grayscale PNG"); 20434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 20444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x47524159: /* 'GRAY' */ 20464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((color_type & PNG_COLOR_MASK_COLOR) != 0) 20474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Gray color space not permitted on RGB PNG"); 20494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 20504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 20524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "invalid ICC profile color space"); 20544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 20554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* It is up to the application to check that the profile class matches the 20574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * application requirements; the spec provides no guidance, but it's pretty 20584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer 20594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these 20604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * cases. Issue an error for device link or abstract profiles - these don't 20614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contain the records necessary to transform the color-space to anything 20624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * other than the target device (and not even that for an abstract profile). 20634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Profiles of these classes may not be embedded in images. 20644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+12); /* profile/device class */ 20664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (temp) 20674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 20684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x73636e72: /* 'scnr' */ 20694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x6d6e7472: /* 'mntr' */ 20704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x70727472: /* 'prtr' */ 20714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x73706163: /* 'spac' */ 20724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* All supported */ 20734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 20744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x61627374: /* 'abst' */ 20764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* May not be embedded in an image */ 20774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "invalid embedded Abstract ICC profile"); 20794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x6c696e6b: /* 'link' */ 20814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* DeviceLink profiles cannot be interpreted in a non-device specific 20824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * fashion, if an app uses the AToB0Tag in the profile the results are 20834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * undefined unless the result is sent to the intended device, 20844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * therefore a DeviceLink profile should not be found embedded in a 20854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG. 20864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 20884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "unexpected DeviceLink ICC profile class"); 20894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x6e6d636c: /* 'nmcl' */ 20914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* A NamedColor profile is also device specific, however it doesn't 20924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contain an AToB0 tag that is open to misinterpretation. Almost 20934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * certainly it will fail the tests below. 20944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 20954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_icc_profile_error(png_ptr, NULL, name, temp, 20964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "unexpected NamedColor ICC profile class"); 20974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 20984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 21004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* To allow for future enhancements to the profile accept unrecognized 21014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * profile classes with a warning, these then hit the test below on the 21024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tag content to ensure they are backward compatible with one of the 21034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * understood profiles. 21044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_icc_profile_error(png_ptr, NULL, name, temp, 21064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "unrecognized ICC profile class"); 21074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 21084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* For any profile other than a device link one the PCS must be encoded 21114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * either in XYZ or Lab. 21124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann temp = png_get_uint_32(profile+20); 21144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (temp) 21154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x58595a20: /* 'XYZ ' */ 21174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 0x4c616220: /* 'Lab ' */ 21184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 21194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: 21214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, temp, 21224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "unexpected ICC PCS encoding"); 21234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 21264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 21274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 21294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, 21304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp name, png_uint_32 profile_length, 21314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep profile /* header plus whole tag table */) 21324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 21334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 tag_count = png_get_uint_32(profile+128); 21344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 itag; 21354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep tag = profile+132; /* The first tag */ 21364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* First scan all the tags in the table and add bits to the icc_info value 21384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (temporarily in 'tags'). 21394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (itag=0; itag < tag_count; ++itag, tag += 12) 21414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 tag_id = png_get_uint_32(tag+0); 21434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ 21444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ 21454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The ICC specification does not exclude zero length tags, therefore the 21474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * start might actually be anywhere if there is no data, but this would be 21484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a clear abuse of the intent of the standard so the start is checked for 21494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * being in range. All defined tag types have an 8 byte header - a 4 byte 21504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * type signature then 0. 21514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((tag_start & 3) != 0) 21534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 21544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is 21554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * only a warning here because libpng does not care about the 21564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * alignment. 21574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, 21594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "ICC profile tag start not a multiple of 4"); 21604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is a hard error; potentially it can cause read outside the 21634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * profile. 21644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (tag_start > profile_length || tag_length > profile_length - tag_start) 21664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_icc_profile_error(png_ptr, colorspace, name, tag_id, 21674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "ICC profile tag outside profile"); 21684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 21694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; /* success, maybe with warnings */ 21714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 21724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sRGB_SUPPORTED 21744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS >= 0 21754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Information about the known ICC sRGB profiles */ 21764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const struct 21774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 21784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 adler, crc, length; 21794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 md5[4]; 21804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte have_md5; 21814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte is_broken; 21824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16 intent; 21834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) 21854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ 21864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { adler, crc, length, md5, broke, intent }, 21874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} png_sRGB_checks[] = 21894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 21904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This data comes from contrib/tools/checksum-icc run on downloads of 21914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * all four ICC sRGB profiles from www.color.org. 21924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 21934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* adler32, crc32, MD5[4], intent, date, length, file-name */ 21944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, 21954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, 21964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") 21974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* ICC sRGB v2 perceptual no black-compensation: */ 21994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, 22004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, 22014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") 22024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, 22044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, 22054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") 22064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* ICC sRGB v4 perceptual */ 22084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, 22094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, 22104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") 22114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following profiles have no known MD5 checksum. If there is a match 22134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * on the (empty) MD5 the other fields are used to attempt a match and 22144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * a warning is produced. The first two of these profiles have a 'cprt' tag 22154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * which suggests that they were also made by Hewlett Packard. 22164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, 22184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, 22194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") 22204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not 22224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * match the D50 PCS illuminant in the header (it is in fact the D65 values, 22234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * so the white point is recorded as the un-adapted value.) The profiles 22244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * below only differ in one byte - the intent - and are basically the same as 22254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the previous profile except for the mediaWhitePointTag error and a missing 22264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * chromaticAdaptationTag. 22274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, 22294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, 22304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") 22314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, 22334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, 22344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") 22354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 22364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 22384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, 22394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_bytep profile, uLong adler) 22404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 22414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The quick check is to verify just the MD5 signature and trust the 22424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * rest of the data. Because the profile has already been verified for 22434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' 22444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * field too, so if the profile has been edited with an intent not defined 22454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * by sRGB (but maybe defined by a later ICC specification) the read of 22464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the profile will fail at that point. 22474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 length = 0; 22504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 intent = 0x10000; /* invalid */ 22514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS > 1 22524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uLong crc = 0; /* the value for 0 length data */ 22534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 22544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 22554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_OPTION_SUPPORTED 22574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ 22584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == 22594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_OPTION_ON) 22604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 22614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 22624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) 22644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && 22664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && 22674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && 22684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) 22694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This may be one of the old HP profiles without an MD5, in that 22714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * case we can only use the length and Adler32 (note that these 22724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * are not used by default if there is an MD5!) 22734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 22744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_sRGB_PROFILE_CHECKS == 0 22754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_sRGB_checks[i].have_md5 != 0) 22764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1+png_sRGB_checks[i].is_broken; 22774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 22784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Profile is unsigned or more checks have been configured in. */ 22804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (length == 0) 22814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann length = png_get_uint_32(profile); 22834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann intent = png_get_uint_32(profile+64); 22844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 22854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Length *and* intent must match */ 22874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (length == (png_uint_32) png_sRGB_checks[i].length && 22884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann intent == (png_uint_32) png_sRGB_checks[i].intent) 22894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now calculate the adler32 if not done already. */ 22914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (adler == 0) 22924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann adler = adler32(0, NULL, 0); 22944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann adler = adler32(adler, profile, length); 22954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 22964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (adler == png_sRGB_checks[i].adler) 22984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 22994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* These basic checks suggest that the data has not been 23004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * modified, but if the check level is more than 1 perform 23014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * our own crc32 checksum on the data. 23024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_sRGB_PROFILE_CHECKS > 1 23044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (crc == 0) 23054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann crc = crc32(0, NULL, 0); 23074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann crc = crc32(crc, profile, length); 23084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* So this check must pass for the 'return' below to happen. 23114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (crc == png_sRGB_checks[i].crc) 23134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 23144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_sRGB_checks[i].is_broken != 0) 23164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* These profiles are known to have bad data that may cause 23184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * problems if they are used, therefore attempt to 23194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * discourage their use, skip the 'have_md5' warning below, 23204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * which is made irrelevant by this error. 23214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, "known incorrect sRGB profile", 23234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_ERROR); 23244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Warn that this being done; this isn't even an error since 23274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the profile is perfectly valid, but it would be nice if 23284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * people used the up-to-date ones. 23294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (png_sRGB_checks[i].have_md5 == 0) 23314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, 23334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "out-of-date sRGB profile with no signature", 23344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_WARNING); 23354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1+png_sRGB_checks[i].is_broken; 23384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# if PNG_sRGB_PROFILE_CHECKS > 0 23424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The signature matched, but the profile had been changed in some 23434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * way. This probably indicates a data error or uninformed hacking. 23444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Fall through to "no match". 23454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_chunk_report(png_ptr, 23474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "Not recognizing known sRGB profile that has been edited", 23484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CHUNK_WARNING); 23494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 23504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 23514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* no match */ 23564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 23574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ 23584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 23604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_icc_set_sRGB(png_const_structrp png_ptr, 23614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_colorspacerp colorspace, png_const_bytep profile, uLong adler) 23624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 23634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Is this profile one of the known ICC sRGB profiles? If it is, just set 23644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the sRGB information. 23654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 23664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if PNG_sRGB_PROFILE_CHECKS >= 0 23674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) 23684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 23694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_colorspace_set_sRGB(png_ptr, colorspace, 23704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (int)/*already checked*/png_get_uint_32(profile+64)); 23714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 23724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* sRGB */ 23734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 23754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, 23764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, 23774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int color_type) 23784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 23794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) 23804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 23814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && 23834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, 23844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_type) != 0 && 23854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, 23864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann profile) != 0) 23874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 23884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_sRGB_SUPPORTED 23894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* If no sRGB support, don't try storing sRGB information */ 23904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_icc_set_sRGB(png_ptr, colorspace, profile, 0); 23914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 23924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 23934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 23944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Failure case */ 23964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 23974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 23984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* iCCP */ 23994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 24014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 24024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_colorspace_set_rgb_coefficients(png_structrp png_ptr) 24034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 24044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Set the rgb_to_gray coefficients from the colorspace. */ 24054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->rgb_to_gray_coefficients_set == 0 && 24064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 24074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* png_set_background has not been called, get the coefficients from the Y 24094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values of the colorspace colorants. 24104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; 24124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; 24134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; 24144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point total = r+g+b; 24154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (total > 0 && 24174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && 24184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && 24194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && 24204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r+g+b <= 32769) 24214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We allow 0 coefficients here. r+g+b may be 32769 if two or 24234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * all of the coefficients were rounded up. Handle this by 24244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * reducing the *largest* coefficient by 1; this matches the 24254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * approach used for the default coefficients in pngrtran.c 24264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int add = 0; 24284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r+g+b > 32768) 24304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann add = -1; 24314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (r+g+b < 32768) 24324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann add = 1; 24334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (add != 0) 24354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (g >= r && g >= b) 24374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann g += add; 24384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (r >= g && r >= b) 24394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r += add; 24404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 24414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann b += add; 24424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for an internal error. */ 24454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r+g+b != 32768) 24464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, 24474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann "internal error handling cHRM coefficients"); 24484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 24504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; 24524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; 24534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is a png_error at present even though it could be ignored - 24574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it should never happen, but it is important that if it does, the 24584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bug is fixed. 24594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 24604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 24614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "internal error handling cHRM->XYZ"); 24624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 24644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_RGB_TO_GRAY */ 24654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* COLORSPACE */ 24674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* #ifdef __GNUC__ */ 24694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 1 24704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This exists solely to work round a warning from GNU C. */ 24714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int /* PRIVATE */ 24724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gt(size_t a, size_t b) 24734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 24744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return a > b; 24754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 24764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 24774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# define png_gt(a,b) ((a) > (b)) 24784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 24794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 24814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_IHDR(png_const_structrp png_ptr, 24824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 width, png_uint_32 height, int bit_depth, 24834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int color_type, int interlace_type, int compression_type, 24844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int filter_type) 24854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 24864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int error = 0; 24874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for width and height valid values */ 24894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (width == 0) 24904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Image width is zero in IHDR"); 24924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 24934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 24944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (width > PNG_UINT_31_MAX) 24964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 24974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid image width in IHDR"); 24984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 24994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_gt(((width + 7) & (~7)), 25024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((PNG_SIZE_MAX 25034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann - 48 /* big_row_buf hack */ 25044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann - 1) /* filter byte */ 25054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann / 8) /* 8-byte RGBA pixels */ 25064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann - 1)) /* extra max_pixel_depth pad */ 25074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The size of the row must be within the limits of this architecture. 25094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Because the read code can perform arbitrary transformations the 25104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * maximum size is checked here. Because the code in png_read_start_row 25114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * adds extra space "for safety's sake" in several places a conservative 25124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * limit is used here. 25134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 25144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * NOTE: it would be far better to check the size that is actually used, 25154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but the effect in the real world is minor and the changes are more 25164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * extensive, therefore much more dangerous and much more difficult to 25174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * write in a way that avoids compiler warnings. 25184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 25194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Image width is too large for this architecture"); 25204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_USER_LIMITS_SUPPORTED 25244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (width > png_ptr->user_width_max) 25254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 25264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (width > PNG_USER_WIDTH_MAX) 25274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 25284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Image width exceeds user limit in IHDR"); 25304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (height == 0) 25344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Image height is zero in IHDR"); 25364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (height > PNG_UINT_31_MAX) 25404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid image height in IHDR"); 25424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_USER_LIMITS_SUPPORTED 25464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (height > png_ptr->user_height_max) 25474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 25484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (height > PNG_USER_HEIGHT_MAX) 25494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 25504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Image height exceeds user limit in IHDR"); 25524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check other values */ 25564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && 25574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bit_depth != 8 && bit_depth != 16) 25584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid bit depth in IHDR"); 25604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (color_type < 0 || color_type == 1 || 25644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_type == 5 || color_type > 6) 25654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid color type in IHDR"); 25674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || 25714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((color_type == PNG_COLOR_TYPE_RGB || 25724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_type == PNG_COLOR_TYPE_GRAY_ALPHA || 25734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) 25744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); 25764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (interlace_type >= PNG_INTERLACE_LAST) 25804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Unknown interlace method in IHDR"); 25824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (compression_type != PNG_COMPRESSION_TYPE_BASE) 25864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 25874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Unknown compression method in IHDR"); 25884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 25894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 25904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_MNG_FEATURES_SUPPORTED 25924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Accept filter_method 64 (intrapixel differencing) only if 25934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 25944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 2. Libpng did not read a PNG signature (this filter_method is only 25954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * used in PNG datastreams that are embedded in MNG datastreams) and 25964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 3. The application called png_permit_mng_features with a mask that 25974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * included PNG_FLAG_MNG_FILTER_64 and 25984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 4. The filter_method is 64 and 25994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 5. The color_type is RGB or RGBA 26004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && 26024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->mng_features_permitted != 0) 26034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); 26044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (filter_type != PNG_FILTER_TYPE_BASE) 26064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && 26084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && 26094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && 26104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (color_type == PNG_COLOR_TYPE_RGB || 26114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann color_type == PNG_COLOR_TYPE_RGB_ALPHA))) 26124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Unknown filter method in IHDR"); 26144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 26154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) 26184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Invalid filter method in IHDR"); 26204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 26214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 26254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (filter_type != PNG_FILTER_TYPE_BASE) 26264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "Unknown filter method in IHDR"); 26284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann error = 1; 26294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 26314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (error == 1) 26334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "Invalid IHDR data"); 26344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 26354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) 26374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* ASCII to fp functions */ 26384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Check an ASCII formated floating point value, see the more detailed 26394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * comments in pngpriv.h 26404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following is used internally to preserve the sticky flags */ 26424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define png_fp_add(state, flags) ((state) |= (flags)) 26434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) 26444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 26464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_fp_number(png_const_charp string, png_size_t size, int *statep, 26474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_size_tp whereami) 26484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 26494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int state = *statep; 26504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_size_t i = *whereami; 26514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (i < size) 26534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int type; 26554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* First find the type of the next character */ 26564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (string[i]) 26574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 43: type = PNG_FP_SAW_SIGN; break; 26594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; 26604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 46: type = PNG_FP_SAW_DOT; break; 26614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 48: type = PNG_FP_SAW_DIGIT; break; 26624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 49: case 50: case 51: case 52: 26634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 53: case 54: case 55: case 56: 26644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; 26654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 69: 26664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case 101: type = PNG_FP_SAW_E; break; 26674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: goto PNG_FP_End; 26684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 26694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now deal with this type according to the current 26714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * state, the type is arranged to not overlap the 26724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bits of the PNG_FP_STATE. 26734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 26744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) 26754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 26764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: 26774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_ANY) != 0) 26784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; /* not a part of the number */ 26794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, type); 26814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 26824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_INTEGER + PNG_FP_SAW_DOT: 26844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Ok as trailer, ok as lead of fraction. */ 26854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ 26864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; 26874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ 26894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, type); 26904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 26924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_set(state, PNG_FP_FRACTION | type); 26934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 26954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 26964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: 26974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ 26984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); 26994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, type | PNG_FP_WAS_VALID); 27014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_INTEGER + PNG_FP_SAW_E: 27054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_DIGIT) == 0) 27064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; 27074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_set(state, PNG_FP_EXPONENT); 27094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: 27134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; ** no sign in fraction */ 27144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: 27164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; ** Because SAW_DOT is always set */ 27174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: 27194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, type | PNG_FP_WAS_VALID); 27204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_FRACTION + PNG_FP_SAW_E: 27234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This is correct because the trailing '.' on an 27244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * integer is handled above - so we can only get here 27254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * with the sequence ".E" (with no preceding digits). 27264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_DIGIT) == 0) 27284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; 27294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_set(state, PNG_FP_EXPONENT); 27314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: 27354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((state & PNG_FP_SAW_ANY) != 0) 27364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; /* not a part of the number */ 27374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, PNG_FP_SAW_SIGN); 27394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: 27434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; */ 27444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: 27464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); 27474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 27494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: 27514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann goto PNG_FP_End; */ 27524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann default: goto PNG_FP_End; /* I.e. break 2 */ 27544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The character seems ok, continue. */ 27574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++i; 27584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 27594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannPNG_FP_End: 27614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Here at the end, update the state and return the correct 27624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * return code. 27634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *statep = state; 27654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *whereami = i; 27664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (state & PNG_FP_SAW_DIGIT) != 0; 27684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 27694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The same but for a complete string. */ 27724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint 27734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_check_fp_string(png_const_charp string, png_size_t size) 27744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 27754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int state=0; 27764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_size_t char_index=0; 27774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_check_fp_number(string, size, &state, &char_index) != 0 && 27794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (char_index == size || string[char_index] == 0)) 27804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return state /* must be non-zero - see above */; 27814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* i.e. fail */ 27834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 27844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* pCAL || sCAL */ 27854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_sCAL_SUPPORTED 27874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FLOATING_POINT_SUPPORTED 27884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Utility used below - a simple accurate power of ten from an integral 27894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exponent. 27904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 27914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic double 27924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_pow10(int power) 27934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 27944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int recip = 0; 27954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double d = 1; 27964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Handle negative exponent with a reciprocal at the end because 27984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 10 is exact whereas .1 is inexact in base 2 27994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (power < 0) 28014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (power < DBL_MIN_10_EXP) return 0; 28034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann recip = 1, power = -power; 28044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (power > 0) 28074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Decompose power bitwise. */ 28094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double mult = 10; 28104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do 28114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (power & 1) d *= mult; 28134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann mult *= mult; 28144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann power >>= 1; 28154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (power > 0); 28174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (recip != 0) d = 1/d; 28194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* else power is 0 and d is 1 */ 28214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return d; 28234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 28244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to format a floating point value in ASCII with a given 28264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision. 28274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 28294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, 28304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double fp, unsigned int precision) 28314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 28324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We use standard functions from math.h, but not printf because 28334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that would require stdio. The caller must supply a buffer of 28344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * sufficient size or we will png_error. The tests on size and 28354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the space in ascii[] consumed are indicated below. 28364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (precision < 1) 28384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann precision = DBL_DIG; 28394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Enforce the limit of the implementation precision too. */ 28414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (precision > DBL_DIG+1) 28424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann precision = DBL_DIG+1; 28434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Basic sanity checks */ 28454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (size >= precision+5) /* See the requirements below. */ 28464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fp < 0) 28484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fp = -fp; 28504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ 28514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann --size; 28524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fp >= DBL_MIN && fp <= DBL_MAX) 28554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int exp_b10; /* A base 10 exponent */ 28574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double base; /* 10^exp_b10 */ 28584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* First extract a base 10 exponent of the number, 28604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the calculation below rounds down when converting 28614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * from base 2 to base 10 (multiply by log10(2) - 28624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to 28634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be increased. Note that the arithmetic shift 28644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * performs a floor() unlike C arithmetic - using a 28654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * C multiply would break the following for negative 28664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exponents. 28674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)frexp(fp, &exp_b10); /* exponent to base 2 */ 28694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ 28714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Avoid underflow here. */ 28734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann base = png_pow10(exp_b10); /* May underflow */ 28744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (base < DBL_MIN || base < fp) 28764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 28774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And this may overflow. */ 28784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double test = png_pow10(exp_b10+1); 28794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (test <= DBL_MAX) 28814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++exp_b10, base = test; 28824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 28844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 28854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 28864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Normalize fp and correct exp_b10, after this fp is in the 28884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * range [.1,1) and exp_b10 is both the exponent and the digit 28894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * *before* which the decimal point should be inserted 28904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (starting with 0 for the first digit). Note that this 28914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * works even if 10^exp_b10 is out of range because of the 28924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * test on DBL_MAX above. 28934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 28944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fp /= base; 28954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (fp >= 1) fp /= 10, ++exp_b10; 28964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Because of the code above fp may, at this point, be 28984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * less than .1, this is ok because the code below can 28994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * handle the leading zeros this generates, so no attempt 29004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is made to correct that here. 29014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int czero, clead, cdigits; 29054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char exponent[10]; 29064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Allow up to two leading zeros - this will not lengthen 29084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the number compared to using E-n. 29094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ 29114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ 29134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann exp_b10 = 0; /* Dot added below before first output. */ 29144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 29164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann czero = 0; /* No zeros to add */ 29174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Generate the digit list, stripping trailing zeros and 29194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * inserting a '.' before a digit if the exponent is 0. 29204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann clead = czero; /* Count of leading zeros */ 29224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cdigits = 0; /* Count of digits in list. */ 29234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann do 29254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double d; 29274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fp *= 10; 29294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Use modf here, not floor and subtract, so that 29304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the separation is done in one step. At the end 29314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of the loop don't break the number into parts so 29324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that the final digit is rounded. 29334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cdigits+czero+1 < precision+clead) 29354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fp = modf(fp, &d); 29364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 29384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = floor(fp + .5); 29404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (d > 9) 29424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Rounding up to 10, handle that here. */ 29444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (czero > 0) 29454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann --czero, d = 1; 29474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cdigits == 0) --clead; 29484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 29504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (cdigits > 0 && d > 9) 29524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ch = *--ascii; 29544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 != (-1)) 29564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++exp_b10; 29574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (ch == 46) 29594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ch = *--ascii, ++size; 29614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Advance exp_b10 to '1', so that the 29624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * decimal point happens after the 29634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * previous digit. 29644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann exp_b10 = 1; 29664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann --cdigits; 29694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = ch - 47; /* I.e. 1+(ch-48) */ 29704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Did we reach the beginning? If so adjust the 29734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * exponent but take into account the leading 29744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * decimal point. 29754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (d > 9) /* cdigits == 0 */ 29774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 == (-1)) 29794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 29804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Leading decimal point (plus zeros?), if 29814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * we lose the decimal point here it must 29824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * be reentered below. 29834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int ch = *--ascii; 29854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ch == 46) 29874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++size, exp_b10 = 1; 29884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Else lost a leading zero, so 'exp_b10' is 29904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * still ok at (-1) 29914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 29924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 29944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++exp_b10; 29954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* In all cases we output a '1' */ 29974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d = 1; 29984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 29994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fp = 0; /* Guarantees termination below. */ 30024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (d == 0) 30054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++czero; 30074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cdigits == 0) ++clead; 30084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 30104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Included embedded zeros in the digit count. */ 30124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cdigits += czero - clead; 30134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann clead = 0; 30144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (czero > 0) 30164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* exp_b10 == (-1) means we just output the decimal 30184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * place - after the DP don't adjust 'exp_b10' any 30194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * more! 30204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 != (-1)) 30224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 == 0) *ascii++ = 46, --size; 30244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* PLUS 1: TOTAL 4 */ 30254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann --exp_b10; 30264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 48, --czero; 30284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 != (-1)) 30314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 == 0) 30334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 46, --size; /* counted above */ 30344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann --exp_b10; 30364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = (char)(48 + (int)d), ++cdigits; 30384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (cdigits+czero < precision+clead && fp > DBL_MIN); 30414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The total output count (max) is now 4+precision */ 30434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for an exponent, if we don't need one we are 30454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * done and just need to terminate the string. At 30464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this point exp_b10==(-1) is effectively if flag - it got 30474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to '-1' because of the decrement after outputting 30484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the decimal point above (the exponent required is 30494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * *not* -1!) 30504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 >= (-1) && exp_b10 <= 2) 30524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following only happens if we didn't output the 30544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * leading zeros above for negative exponent, so this 30554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * doesn't add to the digit requirement. Note that the 30564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * two zeros here can only be output if the two leading 30574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * zeros were *not* output, so this doesn't increase 30584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the output count. 30594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (--exp_b10 >= 0) *ascii++ = 48; 30614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii = 0; 30634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Total buffer requirement (including the '\0') is 30654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 5+precision - see check at the start. 30664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 30684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Here if an exponent is required, adjust size for 30714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the digits we output but did not count. The total 30724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * digit output here so far is at most 1+precision - no 30734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * decimal point and no leading or trailing zeros have 30744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * been output. 30754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size -= cdigits; 30774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ 30794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following use of an unsigned temporary avoids ambiguities in 30814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the signed arithmetic on exp_b10 and permits GCC at least to do 30824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * better optimization. 30834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 30844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int uexp_b10; 30864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (exp_b10 < 0) 30884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 30894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ 30904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uexp_b10 = -exp_b10; 30914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 30924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 30944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uexp_b10 = exp_b10; 30954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cdigits = 0; 30974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (uexp_b10 > 0) 30994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann exponent[cdigits++] = (char)(48 + uexp_b10 % 10); 31014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann uexp_b10 /= 10; 31024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Need another size check here for the exponent digits, so 31064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * this need not be considered above. 31074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (size > cdigits) 31094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (cdigits > 0) *ascii++ = exponent[--cdigits]; 31114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii = 0; 31134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 31154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (!(fp >= DBL_MIN)) 31194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 48; /* '0' */ 31214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii = 0; 31224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 31234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 31254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 105; /* 'i' */ 31274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 110; /* 'n' */ 31284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 102; /* 'f' */ 31294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii = 0; 31304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 31314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Here on buffer too small. */ 31354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "ASCII conversion buffer too small"); 31364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 31374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif /* FLOATING_POINT */ 31394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FIXED_POINT_SUPPORTED 31414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Function to format a fixed point value in ASCII. 31424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 31444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, 31454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_size_t size, png_fixed_point fp) 31464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 31474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Require space for 10 decimal digits, a decimal point, a minus sign and a 31484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * trailing \0, 13 characters: 31494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (size > 12) 31514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 num; 31534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Avoid overflow here on the minimum integer. */ 31554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fp < 0) 31564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 45, num = -fp; 31574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 31584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num = fp; 31594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (num <= 0x80000000) /* else overflowed */ 31614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int ndigits = 0, first = 16 /* flag value */; 31634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann char digits[10]; 31644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (num) 31664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Split the low digit off num: */ 31684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int tmp = num/10; 31694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num -= tmp*10; 31704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann digits[ndigits++] = (char)(48 + num); 31714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Record the first non-zero digit, note that this is a number 31724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * starting at 1, it's not actually the array index. 31734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (first == 16 && num > 0) 31754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann first = ndigits; 31764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann num = tmp; 31774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (ndigits > 0) 31804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (ndigits > 5) *ascii++ = digits[--ndigits]; 31824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The remaining digits are fractional digits, ndigits is '5' or 31834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * smaller at this point. It is certainly not zero. Check for a 31844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * non-zero fractional digit: 31854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (first <= 5) 31874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 31884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 31894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 46; /* decimal point */ 31904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* ndigits may be <5 for small numbers, output leading zeros 31914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * then ndigits digits to first: 31924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 31934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann i = 5; 31944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (ndigits < i) *ascii++ = 48, --i; 31954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (ndigits >= first) *ascii++ = digits[--ndigits]; 31964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Don't output the trailing zeros! */ 31974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 31994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii++ = 48; 32014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And null terminate the string: */ 32034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *ascii = 0; 32044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return; 32054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Here on buffer too small. */ 32094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(png_ptr, "ASCII conversion buffer too small"); 32104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 32114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif /* FIXED_POINT */ 32124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SCAL */ 32134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ 32154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ 32164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ 32174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 32184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ 32194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (defined(PNG_sCAL_SUPPORTED) && \ 32204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) 32214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point 32224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) 32234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 32244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = floor(100000 * fp + .5); 32254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r > 2147483647. || r < -2147483648.) 32274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_error(png_ptr, text); 32284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifndef PNG_ERROR_TEXT_SUPPORTED 32304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_UNUSED(text) 32314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 32324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_fixed_point)r; 32344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 32354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 32364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ 32384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) 32394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* muldiv functions */ 32404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This API takes signed arguments and rounds the result to the nearest 32414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * integer (or, for a fixed point number - the standard argument - to 32424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the nearest .00001). Overflow and divide by zero are signalled in 32434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the result, a boolean - true on success, false on overflow. 32444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 32454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint 32464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, 32474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 divisor) 32484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 32494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Return a * times / divisor, rounded. */ 32504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (divisor != 0) 32514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a == 0 || times == 0) 32534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *res = 0; 32554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 32564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 32604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = a; 32614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r *= times; 32624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r /= divisor; 32634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r = floor(r+.5); 32644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* A png_fixed_point is a 32-bit integer. */ 32664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r <= 2147483647. && r >= -2147483648.) 32674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 32684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *res = (png_fixed_point)r; 32694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 32704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 32714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 32724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int negative = 0; 32734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 A, T, D; 32744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 s16, s32, s00; 32754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a < 0) 32774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann negative = 1, A = -a; 32784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann A = a; 32804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (times < 0) 32824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann negative = !negative, T = -times; 32834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann T = times; 32854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (divisor < 0) 32874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann negative = !negative, D = -divisor; 32884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 32894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann D = divisor; 32904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Following can't overflow because the arguments only 32924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * have 31 bits each, however the result may be 32 bits. 32934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 32944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s16 = (A >> 16) * (T & 0xffff) + 32954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (A & 0xffff) * (T >> 16); 32964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Can't overflow because the a*times bit is only 30 32974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bits at most. 32984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 32994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s32 = (A >> 16) * (T >> 16) + (s16 >> 16); 33004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s00 = (A & 0xffff) * (T & 0xffff); 33014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s16 = (s16 & 0xffff) << 16; 33034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s00 += s16; 33044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s00 < s16) 33064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++s32; /* carry */ 33074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s32 < D) /* else overflow */ 33094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* s32.s00 is now the 64-bit product, do a standard 33114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * division, we know that s32 < D, so the maximum 33124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required shift is 31. 33134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int bitshift = 32; 33154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point result = 0; /* NOTE: signed */ 33164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (--bitshift >= 0) 33184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 d32, d00; 33204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bitshift > 0) 33224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d32 = D >> (32-bitshift), d00 = D << bitshift; 33234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 33254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann d32 = 0, d00 = D; 33264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s32 > d32) 33284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s00 < d00) --s32; /* carry */ 33304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s32 -= d32, s00 -= d00, result += 1<<bitshift; 33314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 33344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s32 == d32 && s00 >= d00) 33354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann s32 = 0, s00 -= d00, result += 1<<bitshift; 33364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Handle the rounding. */ 33394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (s00 >= (D >> 1)) 33404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++result; 33414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (negative != 0) 33434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann result = -result; 33444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for overflow. */ 33464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((negative != 0 && result <= 0) || 33474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (negative == 0 && result >= 0)) 33484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 33494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann *res = result; 33504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 33514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 33544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 33564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 33584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 33594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA || INCH_CONVERSIONS */ 33604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) 33624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The following is for when the caller doesn't much care about the 33634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * result. 33644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 33654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point 33664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, 33674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 divisor) 33684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 33694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point result; 33704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&result, a, times, divisor) != 0) 33724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return result; 33734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "fixed point overflow ignored"); 33754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 33764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 33774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 33784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ 33804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ 33814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point 33824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reciprocal(png_fixed_point a) 33834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 33844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 33854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = floor(1E10/a+.5); 33864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r <= 2147483647. && r >= -2147483648.) 33884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_fixed_point)r; 33894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 33904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point res; 33914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&res, 100000, 100000, a) != 0) 33934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return res; 33944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 33954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* error/overflow */ 33974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 33984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This is the shared test on whether a gamma value is 'significant' - whether 34004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * it is worth doing gamma correction. 34014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 34034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_significant(png_fixed_point gamma_val) 34044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 34054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || 34064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; 34074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 34084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 34094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED 34114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 34124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* A local convenience routine. */ 34134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_fixed_point 34144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_product2(png_fixed_point a, png_fixed_point b) 34154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 34164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The required result is 1/a * 1/b; the following preserves accuracy. */ 34174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 34184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = a * 1E-5; 34194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r *= b; 34204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r = floor(r+.5); 34214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r <= 2147483647. && r >= -2147483648.) 34234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_fixed_point)r; 34244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 34254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point res; 34264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&res, a, b, 100000) != 0) 34284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return res; 34294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 34304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* overflow */ 34324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 34334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 34344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The inverse of the above. */ 34364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_fixed_point 34374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_reciprocal2(png_fixed_point a, png_fixed_point b) 34384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 34394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The required result is 1/a * 1/b; the following preserves accuracy. */ 34404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 34414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (a != 0 && b != 0) 34424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 34434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = 1E15/a; 34444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r /= b; 34454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann r = floor(r+.5); 34464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (r <= 2147483647. && r >= -2147483648.) 34484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_fixed_point)r; 34494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 34504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 34514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* This may overflow because the range of png_fixed_point isn't symmetric, 34524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * but this API is only used for the product of file and screen gamma so it 34534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * doesn't matter that the smallest number it can produce is 1/21474, not 34544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 1/100000 34554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point res = png_product2(a, b); 34574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (res != 0) 34594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_reciprocal(res); 34604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 34614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; /* overflow */ 34634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 34644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */ 34654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ 34674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED 34684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Fixed point gamma. 34694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 34704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The code to calculate the tables used below can be found in the shell script 34714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contrib/tools/intgamma.sh 34724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 34734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To calculate gamma this code implements fast log() and exp() calls using only 34744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * fixed point arithmetic. This code has sufficient precision for either 8-bit 34754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * or 16-bit sample values. 34764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 34774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The tables used here were calculated using simple 'bc' programs, but C double 34784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision floating point arithmetic would work fine. 34794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 34804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit log table 34814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to 34824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 255, so it's the base 2 logarithm of a normalized 8-bit floating point 34834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * mantissa. The numbers are 32-bit fractions. 34844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 34854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_uint_32 34864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_8bit_l2[128] = 34874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 34884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, 34894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, 34904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, 34914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, 34924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, 34934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, 34944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, 34954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, 34964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, 34974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, 34984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, 34994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, 35004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, 35014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, 35024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, 35034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, 35044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, 35054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, 35064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, 35074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, 35084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, 35094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 24347096U, 0U 35104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 0 35124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The following are the values for 16-bit tables - these work fine for the 35134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit conversions but produce very slightly larger errors in the 16-bit 35144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * log (about 1.2 as opposed to 0.7 absolute error in the final value). To 35154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * use these all the shifts below must be adjusted appropriately. 35164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, 35184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, 35194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, 35204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, 35214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, 35224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, 35234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, 35244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, 35254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, 35264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, 35274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, 35284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1119, 744, 372 35294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 35304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 35314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_int_32 35334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_log8bit(unsigned int x) 35344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 35354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int lg2 = 0; 35364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, 35374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * because the log is actually negate that means adding 1. The final 35384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 35394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * input), return -1 for the overflow (log 0) case, - so the result is 35404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * always at most 19 bits. 35414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x &= 0xff) == 0) 35434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return -1; 35444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0xf0) == 0) 35464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 = 4, x <<= 4; 35474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0xc0) == 0) 35494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += 2, x <<= 2; 35504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0x80) == 0) 35524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += 1, x <<= 1; 35534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* result is at most 19 bits, so this cast is safe: */ 35554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); 35564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 35574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The above gives exact (to 16 binary places) log2 values for 8-bit images, 35594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * for 16-bit images we use the most significant 8 bits of the 16-bit value to 35604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * get an approximation then multiply the approximation by a correction factor 35614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * determined by the remaining up to 8 bits. This requires an additional step 35624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in the 16-bit case. 35634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * We want log2(value/65535), we have log2(v'/255), where: 35654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value = v' * 256 + v'' 35674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * = v' * f 35684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 35704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less 35714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * than 258. The final factor also needs to correct for the fact that our 8-bit 35724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. 35734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * This gives a final formula using a calculated value 'x' which is value/v' and 35754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * scaling by 65536 to match the above table: 35764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * log2(x/257) * 65536 35784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Since these numbers are so close to '1' we can use simple linear 35804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * interpolation between the two end values 256/257 (result -368.61) and 258/257 35814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (result 367.179). The values used below are scaled by a further 64 to give 35824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16-bit precision in the interpolation: 35834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 35844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Start (256): -23591 35854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Zero (257): 0 35864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * End (258): 23499 35874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 35884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 35894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_int_32 35904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_log16bit(png_uint_32 x) 35914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 35924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int lg2 = 0; 35934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* As above, but now the input has 16 bits. */ 35954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x &= 0xffff) == 0) 35964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return -1; 35974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0xff00) == 0) 35994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 = 8, x <<= 8; 36004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0xf000) == 0) 36024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += 4, x <<= 4; 36034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0xc000) == 0) 36054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += 2, x <<= 2; 36064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((x & 0x8000) == 0) 36084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += 1, x <<= 1; 36094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional 36114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value. 36124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 <<= 28; 36144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; 36154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Now we need to interpolate the factor, this requires a division by the top 36174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8 bits. Do this with maximum precision. 36184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann x = ((x << 16) + (x >> 9)) / (x >> 8); 36204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, 36224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly 36234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16 bits to interpolate to get the low bits of the result. Round the 36244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * answer. Note that the end point values are scaled by 64 to retain overall 36254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust 36264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the overall scaling by 6-12. Round at every step. 36274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann x -= 1U << 24; 36294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x <= 65536U) /* <= '257' */ 36314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); 36324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 36344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); 36354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Safe, because the result can't have more than 20 bits: */ 36374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_int_32)((lg2 + 2048) >> 12); 36384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 36394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 36404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The 'exp()' case must invert the above, taking a 20-bit fixed point 36424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * logarithmic value and returning a 16 or 8-bit number as appropriate. In 36434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * each case only the low 16 bits are relevant - the fraction - since the 36444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * integer bits (the top 4) simply determine a shift. 36454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 36464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The worst case is the 16-bit distinction between 65535 and 65534. This 36474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * requires perhaps spurious accuracy in the decoding of the logarithm to 36484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance 36494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * of getting this accuracy in practice. 36504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 36514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * To deal with this the following exp() function works out the exponent of the 36524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * frational part of the logarithm by using an accurate 32-bit value from the 36534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * top four fractional bits then multiplying in the remaining bits. 36544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic const png_uint_32 36564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_32bit_exp[16] = 36574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 36584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ 36594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, 36604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, 36614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2553802834U, 2445529972U, 2341847524U, 2242560872U 36624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 36634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Adjustment table; provided to explain the numbers in the code below. */ 36654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if 0 36664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannfor (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} 36674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11 44937.64284865548751208448 36684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10 45180.98734845585101160448 36694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9 45303.31936980687359311872 36704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8 45364.65110595323018870784 36714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7 45395.35850361789624614912 36724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6 45410.72259715102037508096 36734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5 45418.40724413220722311168 36744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4 45422.25021786898173001728 36754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3 45424.17186732298419044352 36764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2 45425.13273269940811464704 36774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1 45425.61317555035558641664 36784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0 45425.85339951654943850496 36794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 36804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_32 36824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp(png_fixed_point x) 36834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 36844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ 36854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 36864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Obtain a 4-bit approximation */ 36874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f]; 36884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Incorporate the low 12 bits - these decrease the returned value by 36904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * multiplying by a number less than 1 if the bit is set. The multiplier 36914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is determined by the above table and the shift. Notice that the values 36924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * converge on 45426 and this is used to allow linear interpolation of the 36934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * low bits. 36944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 36954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x800) 36964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 44938U) + 16U) >> 5; 36974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x400) 36994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 45181U) + 32U) >> 6; 37004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x200) 37024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 45303U) + 64U) >> 7; 37034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x100) 37054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 45365U) + 128U) >> 8; 37064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x080) 37084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 45395U) + 256U) >> 9; 37094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x & 0x040) 37114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 45410U) + 512U) >> 10; 37124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And handle the low 6 bits in a single block. */ 37144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; 37154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Handle the upper bits of x. */ 37174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann e >>= x >> 16; 37184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return e; 37194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 37204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Check for overflow */ 37224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (x <= 0) 37234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_32bit_exp[0]; 37244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Else underflow */ 37264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 37274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 37284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_byte 37304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp8bit(png_fixed_point lg2) 37314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 37324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Get a 32-bit value: */ 37334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 x = png_exp(lg2); 37344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the 37364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * second, rounding, step can't overflow because of the first, subtraction, 37374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * step. 37384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann x -= x >> 8; 37404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff); 37414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 37424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 37444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic png_uint_16 37454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_exp16bit(png_fixed_point lg2) 37464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 37474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Get a 32-bit value: */ 37484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 x = png_exp(lg2); 37494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ 37514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann x -= x >> 16; 37524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_uint_16)((x + 32767U) >> 16); 37534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 37544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 37554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* FLOATING_ARITHMETIC */ 37564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_byte 37584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) 37594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 37604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (value > 0 && value < 255) 37614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 37624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 37634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly 37644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * convert this to a floating point value. This includes values that 37654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * would overflow if 'value' were to be converted to 'int'. 37664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 37674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Apparently GCC, however, does an intermediate conversion to (int) 37684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * on some (ARM) but not all (x86) platforms, possibly because of 37694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * hardware FP limitations. (E.g. if the hardware conversion always 37704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * assumes the integer register contains a signed value.) This results 37714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in ANSI-C undefined behavior for large values. 37724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 37734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Other implementations on the same machine might actually be ANSI-C90 37744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * conformant and therefore compile spurious extra code for the large 37754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values. 37764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 37774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * We can be reasonably sure that an unsigned to float conversion 37784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * won't be faster than an int to float one. Therefore this code 37794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * assumes responsibility for the undefined behavior, which it knows 37804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * can't happen because of the check above. 37814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 37824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Note the argument to this routine is an (unsigned int) because, on 37834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16-bit platforms, it is assigned a value which might be out of 37844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * range for an (int); that would result in undefined behavior in the 37854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * caller if the *argument* ('value') were to be declared (int). 37864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 37874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); 37884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_byte)r; 37894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 37904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 lg2 = png_log8bit(value); 37914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point res; 37924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) 37944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_exp8bit(res); 37954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Overflow. */ 37974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann value = 0; 37984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 37994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_byte)(value & 0xff); 38024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 38034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 38054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_16 38064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) 38074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 38084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (value > 0 && value < 65535) 38094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 38114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The same (unsigned int)->(double) constraints apply here as above, 38124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * however in this case the (unsigned int) to (int) conversion can 38134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * overflow on an ANSI-C90 compliant system so the cast needs to ensure 38144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * that this is not possible. 38154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double r = floor(65535*pow((png_int_32)value/65535., 38174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann gamma_val*.00001)+.5); 38184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_uint_16)r; 38194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 38204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_int_32 lg2 = png_log16bit(value); 38214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point res; 38224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) 38244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_exp16bit(res); 38254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Overflow. */ 38274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann value = 0; 38284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 38294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 38304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (png_uint_16)value; 38324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 38334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 38344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* This does the right thing based on the bit_depth field of the 38364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_struct, interpreting values as 8-bit or 16-bit. While the result 38374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is nominally a 16-bit value if bit depth is 8 then the result is 38384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit (as are the arguments.) 38394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_uint_16 /* PRIVATE */ 38414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_gamma_correct(png_structrp png_ptr, unsigned int value, 38424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_fixed_point gamma_val) 38434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 38444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->bit_depth == 8) 38454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_gamma_8bit_correct(value, gamma_val); 38464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 38484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 38494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return png_gamma_16bit_correct(value, gamma_val); 38504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#else 38514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* should not reach this */ 38524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 38534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 38544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 38554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 38574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Internal function to build a single 16-bit table - the table consists of 38584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount 38594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to shift the input values right (or 16-number_of_signifiant_bits). 38604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 38614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The caller is responsible for ensuring that the table gets cleaned up on 38624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument 38634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * should be somewhere that will be cleaned. 38644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 38664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, 38674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) 38684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 38694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Various values derived from 'shift': */ 38704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int num = 1U << (8U - shift); 38714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 38724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* CSE the division and work round wacky GCC warnings (see the comments 38734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * in png_gamma_8bit_correct for where these come from.) 38744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1); 38764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 38774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int max = (1U << (16U - shift))-1U; 38784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); 38794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 38804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16pp table = *ptable = 38824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); 38834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < num; i++) 38854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16p sub_table = table[i] = 38874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); 38884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The 'threshold' test is repeated here because it can arise for one of 38904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the 16-bit tables even if the others don't hit it. 38914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 38924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_gamma_significant(gamma_val) != 0) 38934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 38944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* The old code would overflow at the end and this would cause the 38954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 'pow' function to return a result >1, resulting in an 38964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * arithmetic error. This code follows the spec exactly; ig is 38974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the recovered input sample, it always has 8-16 bits. 38984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 38994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * We want input * 65535/max, rounded, the arithmetic fits in 32 39004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bits (unsigned) so long as max <= 32767. 39014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int j; 39034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (j = 0; j < 256; j++) 39044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 ig = (j << (8-shift)) + i; 39064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 39074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Inline the 'max' scaling operation: */ 39084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* See png_gamma_8bit_correct for why the cast to (int) is 39094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required here. 39104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); 39124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sub_table[j] = (png_uint_16)d; 39134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 39144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (shift != 0) 39154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ig = (ig * 65535U + max_by_2)/max; 39164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); 39184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 39194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 39224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* We must still build a table, but do it the fast way. */ 39244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int j; 39254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (j = 0; j < 256; j++) 39274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 ig = (j << (8-shift)) + i; 39294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (shift != 0) 39314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ig = (ig * 65535U + max_by_2)/max; 39324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sub_table[j] = (png_uint_16)ig; 39344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 39384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* NOTE: this function expects the *inverse* of the overall gamma transformation 39404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * required. 39414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 39434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, 39444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) 39454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 39464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int num = 1U << (8U - shift); 39474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST unsigned int max = (1U << (16U - shift))-1U; 39484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 39494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 last; 39504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16pp table = *ptable = 39524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); 39534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 'num' is the number of tables and also the number of low bits of low 39554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * bits of the input 16-bit value used to select a table. Each table is 39564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * itself indexed by the high 8 bits of the value. 39574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < num; i++) 39594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann table[i] = (png_uint_16p)png_malloc(png_ptr, 39604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 256 * (sizeof (png_uint_16))); 39614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 'gamma_val' is set to the reciprocal of the value calculated above, so 39634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pow(out,g) is an *input* value. 'last' is the last input value set. 39644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 39654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * In the loop 'i' is used to find output values. Since the output is 39664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 8-bit there are only 256 possible values. The tables are set up to 39674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * select the closest possible output value for each input by finding 39684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the input value at the boundary between each pair of output values 39694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * and filling the table up to that boundary with the lower output 39704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * value. 39714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 39724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit 39734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * values the code below uses a 16-bit value in i; the values start at 39744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last 39754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * entries are filled with 255). Start i at 128 and fill all 'last' 39764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * table entries <= 'max' 39774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 39784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann last = 0; 39794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < 255; ++i) /* 8-bit output value */ 39804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Find the corresponding maximum input value */ 39824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ 39834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Find the boundary value in 16 bits: */ 39854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); 39864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Adjust (round) to (16-shift) bits: */ 39884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann bound = (bound * max + 32768U)/65535U + 1U; 39894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (last < bound) 39914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 39924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann table[last & (0xffU >> shift)][last >> (8U - shift)] = out; 39934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann last++; 39944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 39964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* And fill in the final entries. */ 39984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (last < (num << 8)) 39994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; 40014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann last++; 40024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 40044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 40054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Build a single 8-bit table: same as the 16-bit case but much simpler (and 40074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * typically much faster). Note that libpng currently does no sBIT processing 40084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (apparently contrary to the spec) so a 256-entry table is always generated. 40094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic void 40114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, 40124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann PNG_CONST png_fixed_point gamma_val) 40134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 40144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann unsigned int i; 40154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); 40164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_gamma_significant(gamma_val) != 0) 40184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i<256; i++) 40194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann table[i] = png_gamma_8bit_correct(i, gamma_val); 40204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 40224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i=0; i<256; ++i) 40234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann table[i] = (png_byte)(i & 0xff); 40244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 40254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* Used from png_read_destroy and below to release the memory used by the gamma 40274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tables. 40284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 40304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_destroy_gamma_table(png_structrp png_ptr) 40314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 40324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_table); 40334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_table = NULL; 40344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 40364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->gamma_16_table != NULL) 40374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 40394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int istop = (1 << (8 - png_ptr->gamma_shift)); 40404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < istop; i++) 40414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_table[i]); 40434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_table); 40454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_16_table = NULL; 40464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 40484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 40504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 40514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 40524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_from_1); 40534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_from_1 = NULL; 40544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_to_1); 40554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_to_1 = NULL; 40564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 40584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->gamma_16_from_1 != NULL) 40594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 40614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int istop = (1 << (8 - png_ptr->gamma_shift)); 40624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < istop; i++) 40634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_from_1[i]); 40654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_from_1); 40674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_16_from_1 = NULL; 40684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->gamma_16_to_1 != NULL) 40704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int i; 40724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int istop = (1 << (8 - png_ptr->gamma_shift)); 40734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (i = 0; i < istop; i++) 40744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 40754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_to_1[i]); 40764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(png_ptr, png_ptr->gamma_16_to_1); 40784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_16_to_1 = NULL; 40794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 40804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 40814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 40824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 40834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit 40854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * tables, we don't make a full table if we are reducing to 8-bit in 40864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the future. Note also how the gamma_16 tables are segmented so that 40874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * we don't need to allocate > 64K chunks for a full 16-bit table. 40884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 40894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid /* PRIVATE */ 40904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_build_gamma_table(png_structrp png_ptr, int bit_depth) 40914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 40924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_debug(1, "in png_build_gamma_table"); 40934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Remove any existing table; this copes with multiple calls to 40954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_read_update_info. The warning is because building the gamma tables 40964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * multiple times is a performance hit - it's harmless but the ability to call 40974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible 40984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to warn if the app introduces such a hit. 40994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) 41014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_warning(png_ptr, "gamma table being rebuilt"); 41034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_gamma_table(png_ptr); 41044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (bit_depth <= 8) 41074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_8bit_table(png_ptr, &png_ptr->gamma_table, 41094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, 41104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma) : PNG_FP_1); 41114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 41134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 41144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 41154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) 41164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, 41184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_reciprocal(png_ptr->colorspace.gamma)); 41194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, 41214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : 41224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); 41234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 41254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_16BIT_SUPPORTED 41274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_byte shift, sig_bit; 41304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) 41324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sig_bit = png_ptr->sig_bit.red; 41344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->sig_bit.green > sig_bit) 41364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sig_bit = png_ptr->sig_bit.green; 41374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr->sig_bit.blue > sig_bit) 41394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sig_bit = png_ptr->sig_bit.blue; 41404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sig_bit = png_ptr->sig_bit.gray; 41434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* 16-bit gamma code uses this equation: 41454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] 41474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Where 'iv' is the input color value and 'ov' is the output value - 41494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * pow(iv, gamma). 41504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * Thus the gamma table consists of up to 256 256-entry tables. The table 41524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is selected by the (8-gamma_shift) most significant of the low 8 bits of 41534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the color value then indexed by the upper 8 bits: 41544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * table[low bits][high 8 bits] 41564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * So the table 'n' corresponds to all those 'iv' of: 41584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1> 41604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 41614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (sig_bit > 0 && sig_bit < 16U) 41634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* shift == insignificant bits */ 41644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann shift = (png_byte)((16U - sig_bit) & 0xff); 41654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann shift = 0; /* keep all 16 bits */ 41684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) 41704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 41714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively 41724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the significant bits in the *input* when the output will 41734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * eventually be 8 bits. By default it is 11. 41744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (shift < (16U - PNG_MAX_GAMMA_8)) 41764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann shift = (16U - PNG_MAX_GAMMA_8); 41774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 41784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (shift > 8U) 41804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann shift = 8U; /* Guarantees at least one table! */ 41814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->gamma_shift = shift; 41834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now 41854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * PNG_COMPOSE). This effectively smashed the background calculation for 41864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 16-bit output because the 8-bit table assumes the result will be reduced 41874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * to 8 bits. 41884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 41894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) 41904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, 41914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, 41924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma) : PNG_FP_1); 41934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 41954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, 41964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, 41974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma) : PNG_FP_1); 41984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 42004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 42014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 42024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) 42034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 42044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, 42054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_reciprocal(png_ptr->colorspace.gamma)); 42064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Notice that the '16 from 1' table should be full precision, however 42084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * the lookup on this table still uses gamma_shift, so it can't be. 42094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * TODO: fix this. 42104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 42114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, 42124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : 42134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); 42144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 42154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 42164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 42174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* 16BIT */ 42184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 42194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ_GAMMA */ 42204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* HARDWARE OR SOFTWARE OPTION SUPPORT */ 42224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SET_OPTION_SUPPORTED 42234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint PNGAPI 42244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_set_option(png_structrp png_ptr, int option, int onoff) 42254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 42264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && 42274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (option & 1) == 0) 42284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 42294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int mask = 3 << option; 42304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int setting = (2 + (onoff != 0)) << option; 42314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int current = png_ptr->options; 42324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_ptr->options = (png_byte)(((current & ~mask) | setting) & 0xff); 42344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return (current & mask) >> option; 42364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 42374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return PNG_OPTION_INVALID; 42394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 42404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif 42414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* sRGB support */ 42434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ 42444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) 42454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* sRGB conversion tables; these are machine generated with the code in 42464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the 42474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * specification (see the article at http://en.wikipedia.org/wiki/SRGB) 42484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. 42494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). 42504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * The inverse (linear to sRGB) table has accuracies as follows: 42514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 42524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For all possible (255*65535+1) input values: 42534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 42544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact 42554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 42564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * For the input values corresponding to the 65536 16-bit values: 42574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 42584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact 42594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * 42604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * In all cases the inexact readings are only off by one. 42614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 42624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#ifdef PNG_SIMPLIFIED_READ_SUPPORTED 42644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The convert-to-sRGB table is only currently required for read. */ 42654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_uint_16 png_sRGB_table[256] = 42664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 42674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 0,20,40,60,80,99,119,139, 42684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 159,179,199,219,241,264,288,313, 42694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 340,367,396,427,458,491,526,562, 42704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 599,637,677,718,761,805,851,898, 42714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 947,997,1048,1101,1156,1212,1270,1330, 42724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1391,1453,1517,1583,1651,1720,1790,1863, 42734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1937,2013,2090,2170,2250,2333,2418,2504, 42744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 2592,2681,2773,2866,2961,3058,3157,3258, 42754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 3360,3464,3570,3678,3788,3900,4014,4129, 42764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 4247,4366,4488,4611,4736,4864,4993,5124, 42774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 5257,5392,5530,5669,5810,5953,6099,6246, 42784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 6395,6547,6700,6856,7014,7174,7335,7500, 42794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7666,7834,8004,8177,8352,8528,8708,8889, 42804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9072,9258,9445,9635,9828,10022,10219,10417, 42814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10619,10822,11028,11235,11446,11658,11873,12090, 42824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12309,12530,12754,12980,13209,13440,13673,13909, 42834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14146,14387,14629,14874,15122,15371,15623,15878, 42844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16135,16394,16656,16920,17187,17456,17727,18001, 42854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18277,18556,18837,19121,19407,19696,19987,20281, 42864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20577,20876,21177,21481,21787,22096,22407,22721, 42874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23038,23357,23678,24002,24329,24658,24990,25325, 42884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25662,26001,26344,26688,27036,27386,27739,28094, 42894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28452,28813,29176,29542,29911,30282,30656,31033, 42904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 31412,31794,32179,32567,32957,33350,33745,34143, 42914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34544,34948,35355,35764,36176,36591,37008,37429, 42924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37852,38278,38706,39138,39572,40009,40449,40891, 42934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41337,41785,42236,42690,43147,43606,44069,44534, 42944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 45002,45473,45947,46423,46903,47385,47871,48359, 42954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 48850,49344,49841,50341,50844,51349,51858,52369, 42964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 52884,53401,53921,54445,54971,55500,56032,56567, 42974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 57105,57646,58190,58737,59287,59840,60396,60955, 42984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 61517,62082,62650,63221,63795,64372,64952,65535 42994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 43004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED_READ */ 43014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 43024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* The base/delta tables are required for both read and write (but currently 43034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * only the simplified versions.) 43044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 43054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_uint_16 png_sRGB_base[512] = 43064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 43074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 128,1782,3383,4644,5675,6564,7357,8074, 43084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8732,9346,9921,10463,10977,11466,11935,12384, 43094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12816,13233,13634,14024,14402,14769,15125,15473, 43104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15812,16142,16466,16781,17090,17393,17690,17981, 43114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 18266,18546,18822,19093,19359,19621,19879,20133, 43124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 20383,20630,20873,21113,21349,21583,21813,22041, 43134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 22265,22487,22707,22923,23138,23350,23559,23767, 43144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23972,24175,24376,24575,24772,24967,25160,25352, 43154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 25542,25730,25916,26101,26284,26465,26645,26823, 43164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 27000,27176,27350,27523,27695,27865,28034,28201, 43174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28368,28533,28697,28860,29021,29182,29341,29500, 43184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 29657,29813,29969,30123,30276,30429,30580,30730, 43194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 30880,31028,31176,31323,31469,31614,31758,31902, 43204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 32045,32186,32327,32468,32607,32746,32884,33021, 43214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 33158,33294,33429,33564,33697,33831,33963,34095, 43224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 34226,34357,34486,34616,34744,34873,35000,35127, 43234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35253,35379,35504,35629,35753,35876,35999,36122, 43244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 36244,36365,36486,36606,36726,36845,36964,37083, 43254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 37201,37318,37435,37551,37668,37783,37898,38013, 43264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 38127,38241,38354,38467,38580,38692,38803,38915, 43274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39026,39136,39246,39356,39465,39574,39682,39790, 43284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 39898,40005,40112,40219,40325,40431,40537,40642, 43294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 40747,40851,40955,41059,41163,41266,41369,41471, 43304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 41573,41675,41777,41878,41979,42079,42179,42279, 43314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 42379,42478,42577,42676,42775,42873,42971,43068, 43324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 43165,43262,43359,43456,43552,43648,43743,43839, 43334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 43934,44028,44123,44217,44311,44405,44499,44592, 43344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44685,44778,44870,44962,45054,45146,45238,45329, 43354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 45420,45511,45601,45692,45782,45872,45961,46051, 43364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 46140,46229,46318,46406,46494,46583,46670,46758, 43374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 46846,46933,47020,47107,47193,47280,47366,47452, 43384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 47538,47623,47709,47794,47879,47964,48048,48133, 43394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 48217,48301,48385,48468,48552,48635,48718,48801, 43404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 48884,48966,49048,49131,49213,49294,49376,49458, 43414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 49539,49620,49701,49782,49862,49943,50023,50103, 43424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 50183,50263,50342,50422,50501,50580,50659,50738, 43434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 50816,50895,50973,51051,51129,51207,51285,51362, 43444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 51439,51517,51594,51671,51747,51824,51900,51977, 43454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 52053,52129,52205,52280,52356,52432,52507,52582, 43464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 52657,52732,52807,52881,52956,53030,53104,53178, 43474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 53252,53326,53400,53473,53546,53620,53693,53766, 43484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 53839,53911,53984,54056,54129,54201,54273,54345, 43494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54417,54489,54560,54632,54703,54774,54845,54916, 43504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54987,55058,55129,55199,55269,55340,55410,55480, 43514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 55550,55620,55689,55759,55828,55898,55967,56036, 43524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 56105,56174,56243,56311,56380,56448,56517,56585, 43534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 56653,56721,56789,56857,56924,56992,57059,57127, 43544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 57194,57261,57328,57395,57462,57529,57595,57662, 43554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 57728,57795,57861,57927,57993,58059,58125,58191, 43564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 58256,58322,58387,58453,58518,58583,58648,58713, 43574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 58778,58843,58908,58972,59037,59101,59165,59230, 43584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 59294,59358,59422,59486,59549,59613,59677,59740, 43594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 59804,59867,59930,59993,60056,60119,60182,60245, 43604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 60308,60370,60433,60495,60558,60620,60682,60744, 43614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 60806,60868,60930,60992,61054,61115,61177,61238, 43624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 61300,61361,61422,61483,61544,61605,61666,61727, 43634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 61788,61848,61909,61969,62030,62090,62150,62211, 43644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 62271,62331,62391,62450,62510,62570,62630,62689, 43654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 62749,62808,62867,62927,62986,63045,63104,63163, 43664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 63222,63281,63340,63398,63457,63515,63574,63632, 43674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 63691,63749,63807,63865,63923,63981,64039,64097, 43684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 64155,64212,64270,64328,64385,64443,64500,64557, 43694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 64614,64672,64729,64786,64843,64900,64956,65013, 43704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 65070,65126,65183,65239,65296,65352,65409,65465 43714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 43724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 43734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannconst png_byte png_sRGB_delta[512] = 43744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 43754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, 43764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, 43774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, 43784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, 43794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, 43804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, 43814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, 43824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, 43834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, 43844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, 43854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, 43864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, 43874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 43884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, 43894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 43904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 43914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 43924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 43934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 43944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 43954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 43964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 43974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 43984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 43994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 44004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 44014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 44024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 44034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, 44044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 44054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 44064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 44074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann}; 44084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED READ/WRITE sRGB support */ 44094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann/* SIMPLIFIED READ/WRITE SUPPORT */ 44114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ 44124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) 44134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannstatic int 44144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_free_function(png_voidp argument) 44154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 44164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_imagep image = png_voidcast(png_imagep, argument); 44174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_controlp cp = image->opaque; 44184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_control c; 44194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Double check that we have a png_ptr - it should be impossible to get here 44214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * without one. 44224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 44234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cp->png_ptr == NULL) 44244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 44254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* First free any data held in the control structure. */ 44274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_STDIO_SUPPORTED 44284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (cp->owned_file != 0) 44294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 44304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); 44314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cp->owned_file = 0; 44324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Ignore errors here. */ 44344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fp != NULL) 44354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 44364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cp->png_ptr->io_ptr = NULL; 44374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)fclose(fp); 44384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 44394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 44404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 44414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Copy the control structure so that the original, allocated, version can be 44434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * safely freed. Notice that a png_error here stops the remainder of the 44444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * cleanup, but this is probably fine because that would indicate bad memory 44454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * problems anyway. 44464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 44474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann c = *cp; 44484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque = &c; 44494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_free(c.png_ptr, cp); 44504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Then the structures, calling the correct API. */ 44524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (c.for_write != 0) 44534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 44544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED 44554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_write_struct(&c.png_ptr, &c.info_ptr); 44564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 44574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(c.png_ptr, "simplified write not supported"); 44584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 44594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 44604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 44614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 44624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# ifdef PNG_SIMPLIFIED_READ_SUPPORTED 44634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); 44644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# else 44654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_error(c.png_ptr, "simplified read not supported"); 44664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann# endif 44674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 44684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Success. */ 44704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 1; 44714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 44724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid PNGAPI 44744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_free(png_imagep image) 44754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 44764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Safely call the real function, but only if doing so is safe at this point 44774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * (if not inside an error handling context). Otherwise assume 44784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann * png_safe_execute will call this API after the return. 44794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann */ 44804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (image != NULL && image->opaque != NULL && 44814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque->error_buf == NULL) 44824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann { 44834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Ignore errors here: */ 44844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann (void)png_safe_execute(image, png_image_free_function, image); 44854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->opaque = NULL; 44864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 44874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 44884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannint /* PRIVATE */ 44904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannpng_image_error(png_imagep image, png_const_charp error_message) 44914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann{ 44924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann /* Utility to log an error. */ 44934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_safecat(image->message, (sizeof image->message), 0, error_message); 44944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann image->warning_or_error |= PNG_IMAGE_ERROR; 44954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann png_image_free(image); 44964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return 0; 44974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 44984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 44994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* SIMPLIFIED READ/WRITE */ 45004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#endif /* READ || WRITE */ 4501