1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libpng/png.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,4375 @@ 1.4 + 1.5 +/* png.c - location for general purpose libpng functions 1.6 + * 1.7 + * Last changed in libpng 1.6.9 [February 6, 2014] 1.8 + * Copyright (c) 1998-2014 Glenn Randers-Pehrson 1.9 + * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 1.10 + * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 1.11 + * 1.12 + * This code is released under the libpng license. 1.13 + * For conditions of distribution and use, see the disclaimer 1.14 + * and license in png.h 1.15 + */ 1.16 + 1.17 +#include "pngpriv.h" 1.18 + 1.19 +/* Generate a compiler error if there is an old png.h in the search path. */ 1.20 +typedef png_libpng_version_1_6_10 Your_png_h_is_not_version_1_6_10; 1.21 + 1.22 +/* Tells libpng that we have already handled the first "num_bytes" bytes 1.23 + * of the PNG file signature. If the PNG data is embedded into another 1.24 + * stream we can set num_bytes = 8 so that libpng will not attempt to read 1.25 + * or write any of the magic bytes before it starts on the IHDR. 1.26 + */ 1.27 + 1.28 +#ifdef PNG_READ_SUPPORTED 1.29 +void PNGAPI 1.30 +png_set_sig_bytes(png_structrp png_ptr, int num_bytes) 1.31 +{ 1.32 + png_debug(1, "in png_set_sig_bytes"); 1.33 + 1.34 + if (png_ptr == NULL) 1.35 + return; 1.36 + 1.37 + if (num_bytes > 8) 1.38 + png_error(png_ptr, "Too many bytes for PNG signature"); 1.39 + 1.40 + png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes); 1.41 +} 1.42 + 1.43 +/* Checks whether the supplied bytes match the PNG signature. We allow 1.44 + * checking less than the full 8-byte signature so that those apps that 1.45 + * already read the first few bytes of a file to determine the file type 1.46 + * can simply check the remaining bytes for extra assurance. Returns 1.47 + * an integer less than, equal to, or greater than zero if sig is found, 1.48 + * respectively, to be less than, to match, or be greater than the correct 1.49 + * PNG signature (this is the same behavior as strcmp, memcmp, etc). 1.50 + */ 1.51 +int PNGAPI 1.52 +png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) 1.53 +{ 1.54 + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 1.55 + 1.56 + if (num_to_check > 8) 1.57 + num_to_check = 8; 1.58 + 1.59 + else if (num_to_check < 1) 1.60 + return (-1); 1.61 + 1.62 + if (start > 7) 1.63 + return (-1); 1.64 + 1.65 + if (start + num_to_check > 8) 1.66 + num_to_check = 8 - start; 1.67 + 1.68 + return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); 1.69 +} 1.70 + 1.71 +#endif /* PNG_READ_SUPPORTED */ 1.72 + 1.73 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 1.74 +/* Function to allocate memory for zlib */ 1.75 +PNG_FUNCTION(voidpf /* PRIVATE */, 1.76 +png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) 1.77 +{ 1.78 + png_alloc_size_t num_bytes = size; 1.79 + 1.80 + if (png_ptr == NULL) 1.81 + return NULL; 1.82 + 1.83 + if (items >= (~(png_alloc_size_t)0)/size) 1.84 + { 1.85 + png_warning (png_voidcast(png_structrp, png_ptr), 1.86 + "Potential overflow in png_zalloc()"); 1.87 + return NULL; 1.88 + } 1.89 + 1.90 + num_bytes *= items; 1.91 + return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); 1.92 +} 1.93 + 1.94 +/* Function to free memory for zlib */ 1.95 +void /* PRIVATE */ 1.96 +png_zfree(voidpf png_ptr, voidpf ptr) 1.97 +{ 1.98 + png_free(png_voidcast(png_const_structrp,png_ptr), ptr); 1.99 +} 1.100 + 1.101 +/* Reset the CRC variable to 32 bits of 1's. Care must be taken 1.102 + * in case CRC is > 32 bits to leave the top bits 0. 1.103 + */ 1.104 +void /* PRIVATE */ 1.105 +png_reset_crc(png_structrp png_ptr) 1.106 +{ 1.107 + /* The cast is safe because the crc is a 32 bit value. */ 1.108 + png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); 1.109 +} 1.110 + 1.111 +/* Calculate the CRC over a section of data. We can only pass as 1.112 + * much data to this routine as the largest single buffer size. We 1.113 + * also check that this data will actually be used before going to the 1.114 + * trouble of calculating it. 1.115 + */ 1.116 +void /* PRIVATE */ 1.117 +png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) 1.118 +{ 1.119 + int need_crc = 1; 1.120 + 1.121 + if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)) 1.122 + { 1.123 + if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 1.124 + (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 1.125 + need_crc = 0; 1.126 + } 1.127 + 1.128 + else /* critical */ 1.129 + { 1.130 + if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 1.131 + need_crc = 0; 1.132 + } 1.133 + 1.134 + /* 'uLong' is defined in zlib.h as unsigned long; this means that on some 1.135 + * systems it is a 64 bit value. crc32, however, returns 32 bits so the 1.136 + * following cast is safe. 'uInt' may be no more than 16 bits, so it is 1.137 + * necessary to perform a loop here. 1.138 + */ 1.139 + if (need_crc && length > 0) 1.140 + { 1.141 + uLong crc = png_ptr->crc; /* Should never issue a warning */ 1.142 + 1.143 + do 1.144 + { 1.145 + uInt safe_length = (uInt)length; 1.146 + if (safe_length == 0) 1.147 + safe_length = (uInt)-1; /* evil, but safe */ 1.148 + 1.149 + crc = crc32(crc, ptr, safe_length); 1.150 + 1.151 + /* The following should never issue compiler warnings; if they do the 1.152 + * target system has characteristics that will probably violate other 1.153 + * assumptions within the libpng code. 1.154 + */ 1.155 + ptr += safe_length; 1.156 + length -= safe_length; 1.157 + } 1.158 + while (length > 0); 1.159 + 1.160 + /* And the following is always safe because the crc is only 32 bits. */ 1.161 + png_ptr->crc = (png_uint_32)crc; 1.162 + } 1.163 +} 1.164 + 1.165 +/* Check a user supplied version number, called from both read and write 1.166 + * functions that create a png_struct. 1.167 + */ 1.168 +int 1.169 +png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) 1.170 +{ 1.171 + if (user_png_ver) 1.172 + { 1.173 + int i = 0; 1.174 + 1.175 + do 1.176 + { 1.177 + if (user_png_ver[i] != png_libpng_ver[i]) 1.178 + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 1.179 + } while (png_libpng_ver[i++]); 1.180 + } 1.181 + 1.182 + else 1.183 + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; 1.184 + 1.185 + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) 1.186 + { 1.187 + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so 1.188 + * we must recompile any applications that use any older library version. 1.189 + * For versions after libpng 1.0, we will be compatible, so we need 1.190 + * only check the first and third digits (note that when we reach version 1.191 + * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]). 1.192 + */ 1.193 + if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || 1.194 + (user_png_ver[0] == '1' && (user_png_ver[2] != png_libpng_ver[2] || 1.195 + user_png_ver[3] != png_libpng_ver[3])) || 1.196 + (user_png_ver[0] == '0' && user_png_ver[2] < '9')) 1.197 + { 1.198 +#ifdef PNG_WARNINGS_SUPPORTED 1.199 + size_t pos = 0; 1.200 + char m[128]; 1.201 + 1.202 + pos = png_safecat(m, (sizeof m), pos, 1.203 + "Application built with libpng-"); 1.204 + pos = png_safecat(m, (sizeof m), pos, user_png_ver); 1.205 + pos = png_safecat(m, (sizeof m), pos, " but running with "); 1.206 + pos = png_safecat(m, (sizeof m), pos, png_libpng_ver); 1.207 + PNG_UNUSED(pos) 1.208 + 1.209 + png_warning(png_ptr, m); 1.210 +#endif 1.211 + 1.212 +#ifdef PNG_ERROR_NUMBERS_SUPPORTED 1.213 + png_ptr->flags = 0; 1.214 +#endif 1.215 + 1.216 + return 0; 1.217 + } 1.218 + } 1.219 + 1.220 + /* Success return. */ 1.221 + return 1; 1.222 +} 1.223 + 1.224 +/* Generic function to create a png_struct for either read or write - this 1.225 + * contains the common initialization. 1.226 + */ 1.227 +PNG_FUNCTION(png_structp /* PRIVATE */, 1.228 +png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, 1.229 + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, 1.230 + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) 1.231 +{ 1.232 + png_struct create_struct; 1.233 +# ifdef PNG_SETJMP_SUPPORTED 1.234 + jmp_buf create_jmp_buf; 1.235 +# endif 1.236 + 1.237 + /* This temporary stack-allocated structure is used to provide a place to 1.238 + * build enough context to allow the user provided memory allocator (if any) 1.239 + * to be called. 1.240 + */ 1.241 + memset(&create_struct, 0, (sizeof create_struct)); 1.242 + 1.243 + /* Added at libpng-1.2.6 */ 1.244 +# ifdef PNG_USER_LIMITS_SUPPORTED 1.245 + create_struct.user_width_max = PNG_USER_WIDTH_MAX; 1.246 + create_struct.user_height_max = PNG_USER_HEIGHT_MAX; 1.247 + 1.248 +# ifdef PNG_USER_CHUNK_CACHE_MAX 1.249 + /* Added at libpng-1.2.43 and 1.4.0 */ 1.250 + create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; 1.251 +# endif 1.252 + 1.253 +# ifdef PNG_USER_CHUNK_MALLOC_MAX 1.254 + /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists 1.255 + * in png_struct regardless. 1.256 + */ 1.257 + create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; 1.258 +# endif 1.259 +# endif 1.260 + 1.261 + /* The following two API calls simply set fields in png_struct, so it is safe 1.262 + * to do them now even though error handling is not yet set up. 1.263 + */ 1.264 +# ifdef PNG_USER_MEM_SUPPORTED 1.265 + png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); 1.266 +# else 1.267 + PNG_UNUSED(mem_ptr) 1.268 + PNG_UNUSED(malloc_fn) 1.269 + PNG_UNUSED(free_fn) 1.270 +# endif 1.271 + 1.272 + /* (*error_fn) can return control to the caller after the error_ptr is set, 1.273 + * this will result in a memory leak unless the error_fn does something 1.274 + * extremely sophisticated. The design lacks merit but is implicit in the 1.275 + * API. 1.276 + */ 1.277 + png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); 1.278 + 1.279 +# ifdef PNG_SETJMP_SUPPORTED 1.280 + if (!setjmp(create_jmp_buf)) 1.281 + { 1.282 + /* Temporarily fake out the longjmp information until we have 1.283 + * successfully completed this function. This only works if we have 1.284 + * setjmp() support compiled in, but it is safe - this stuff should 1.285 + * never happen. 1.286 + */ 1.287 + create_struct.jmp_buf_ptr = &create_jmp_buf; 1.288 + create_struct.jmp_buf_size = 0; /*stack allocation*/ 1.289 + create_struct.longjmp_fn = longjmp; 1.290 +# else 1.291 + { 1.292 +# endif 1.293 + /* Call the general version checker (shared with read and write code): 1.294 + */ 1.295 + if (png_user_version_check(&create_struct, user_png_ver)) 1.296 + { 1.297 + png_structrp png_ptr = png_voidcast(png_structrp, 1.298 + png_malloc_warn(&create_struct, (sizeof *png_ptr))); 1.299 + 1.300 + if (png_ptr != NULL) 1.301 + { 1.302 + /* png_ptr->zstream holds a back-pointer to the png_struct, so 1.303 + * this can only be done now: 1.304 + */ 1.305 + create_struct.zstream.zalloc = png_zalloc; 1.306 + create_struct.zstream.zfree = png_zfree; 1.307 + create_struct.zstream.opaque = png_ptr; 1.308 + 1.309 +# ifdef PNG_SETJMP_SUPPORTED 1.310 + /* Eliminate the local error handling: */ 1.311 + create_struct.jmp_buf_ptr = NULL; 1.312 + create_struct.jmp_buf_size = 0; 1.313 + create_struct.longjmp_fn = 0; 1.314 +# endif 1.315 + 1.316 + *png_ptr = create_struct; 1.317 + 1.318 + /* This is the successful return point */ 1.319 + return png_ptr; 1.320 + } 1.321 + } 1.322 + } 1.323 + 1.324 + /* A longjmp because of a bug in the application storage allocator or a 1.325 + * simple failure to allocate the png_struct. 1.326 + */ 1.327 + return NULL; 1.328 +} 1.329 + 1.330 +/* Allocate the memory for an info_struct for the application. */ 1.331 +PNG_FUNCTION(png_infop,PNGAPI 1.332 +png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) 1.333 +{ 1.334 + png_inforp info_ptr; 1.335 + 1.336 + png_debug(1, "in png_create_info_struct"); 1.337 + 1.338 + if (png_ptr == NULL) 1.339 + return NULL; 1.340 + 1.341 + /* Use the internal API that does not (or at least should not) error out, so 1.342 + * that this call always returns ok. The application typically sets up the 1.343 + * error handling *after* creating the info_struct because this is the way it 1.344 + * has always been done in 'example.c'. 1.345 + */ 1.346 + info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, 1.347 + (sizeof *info_ptr))); 1.348 + 1.349 + if (info_ptr != NULL) 1.350 + memset(info_ptr, 0, (sizeof *info_ptr)); 1.351 + 1.352 + return info_ptr; 1.353 +} 1.354 + 1.355 +/* This function frees the memory associated with a single info struct. 1.356 + * Normally, one would use either png_destroy_read_struct() or 1.357 + * png_destroy_write_struct() to free an info struct, but this may be 1.358 + * useful for some applications. From libpng 1.6.0 this function is also used 1.359 + * internally to implement the png_info release part of the 'struct' destroy 1.360 + * APIs. This ensures that all possible approaches free the same data (all of 1.361 + * it). 1.362 + */ 1.363 +void PNGAPI 1.364 +png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) 1.365 +{ 1.366 + png_inforp info_ptr = NULL; 1.367 + 1.368 + png_debug(1, "in png_destroy_info_struct"); 1.369 + 1.370 + if (png_ptr == NULL) 1.371 + return; 1.372 + 1.373 + if (info_ptr_ptr != NULL) 1.374 + info_ptr = *info_ptr_ptr; 1.375 + 1.376 + if (info_ptr != NULL) 1.377 + { 1.378 + /* Do this first in case of an error below; if the app implements its own 1.379 + * memory management this can lead to png_free calling png_error, which 1.380 + * will abort this routine and return control to the app error handler. 1.381 + * An infinite loop may result if it then tries to free the same info 1.382 + * ptr. 1.383 + */ 1.384 + *info_ptr_ptr = NULL; 1.385 + 1.386 + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 1.387 + memset(info_ptr, 0, (sizeof *info_ptr)); 1.388 + png_free(png_ptr, info_ptr); 1.389 + } 1.390 +} 1.391 + 1.392 +/* Initialize the info structure. This is now an internal function (0.89) 1.393 + * and applications using it are urged to use png_create_info_struct() 1.394 + * instead. Use deprecated in 1.6.0, internal use removed (used internally it 1.395 + * is just a memset). 1.396 + * 1.397 + * NOTE: it is almost inconceivable that this API is used because it bypasses 1.398 + * the user-memory mechanism and the user error handling/warning mechanisms in 1.399 + * those cases where it does anything other than a memset. 1.400 + */ 1.401 +PNG_FUNCTION(void,PNGAPI 1.402 +png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), 1.403 + PNG_DEPRECATED) 1.404 +{ 1.405 + png_inforp info_ptr = *ptr_ptr; 1.406 + 1.407 + png_debug(1, "in png_info_init_3"); 1.408 + 1.409 + if (info_ptr == NULL) 1.410 + return; 1.411 + 1.412 + if ((sizeof (png_info)) > png_info_struct_size) 1.413 + { 1.414 + *ptr_ptr = NULL; 1.415 + /* The following line is why this API should not be used: */ 1.416 + free(info_ptr); 1.417 + info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, 1.418 + (sizeof *info_ptr))); 1.419 + *ptr_ptr = info_ptr; 1.420 + } 1.421 + 1.422 + /* Set everything to 0 */ 1.423 + memset(info_ptr, 0, (sizeof *info_ptr)); 1.424 +} 1.425 + 1.426 +/* The following API is not called internally */ 1.427 +void PNGAPI 1.428 +png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, 1.429 + int freer, png_uint_32 mask) 1.430 +{ 1.431 + png_debug(1, "in png_data_freer"); 1.432 + 1.433 + if (png_ptr == NULL || info_ptr == NULL) 1.434 + return; 1.435 + 1.436 + if (freer == PNG_DESTROY_WILL_FREE_DATA) 1.437 + info_ptr->free_me |= mask; 1.438 + 1.439 + else if (freer == PNG_USER_WILL_FREE_DATA) 1.440 + info_ptr->free_me &= ~mask; 1.441 + 1.442 + else 1.443 + png_error(png_ptr, "Unknown freer parameter in png_data_freer"); 1.444 +} 1.445 + 1.446 +void PNGAPI 1.447 +png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, 1.448 + int num) 1.449 +{ 1.450 + png_debug(1, "in png_free_data"); 1.451 + 1.452 + if (png_ptr == NULL || info_ptr == NULL) 1.453 + return; 1.454 + 1.455 +#ifdef PNG_TEXT_SUPPORTED 1.456 + /* Free text item num or (if num == -1) all text items */ 1.457 + if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) 1.458 + { 1.459 + if (num != -1) 1.460 + { 1.461 + if (info_ptr->text && info_ptr->text[num].key) 1.462 + { 1.463 + png_free(png_ptr, info_ptr->text[num].key); 1.464 + info_ptr->text[num].key = NULL; 1.465 + } 1.466 + } 1.467 + 1.468 + else 1.469 + { 1.470 + int i; 1.471 + for (i = 0; i < info_ptr->num_text; i++) 1.472 + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); 1.473 + png_free(png_ptr, info_ptr->text); 1.474 + info_ptr->text = NULL; 1.475 + info_ptr->num_text=0; 1.476 + } 1.477 + } 1.478 +#endif 1.479 + 1.480 +#ifdef PNG_tRNS_SUPPORTED 1.481 + /* Free any tRNS entry */ 1.482 + if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) 1.483 + { 1.484 + png_free(png_ptr, info_ptr->trans_alpha); 1.485 + info_ptr->trans_alpha = NULL; 1.486 + info_ptr->valid &= ~PNG_INFO_tRNS; 1.487 + } 1.488 +#endif 1.489 + 1.490 +#ifdef PNG_sCAL_SUPPORTED 1.491 + /* Free any sCAL entry */ 1.492 + if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) 1.493 + { 1.494 + png_free(png_ptr, info_ptr->scal_s_width); 1.495 + png_free(png_ptr, info_ptr->scal_s_height); 1.496 + info_ptr->scal_s_width = NULL; 1.497 + info_ptr->scal_s_height = NULL; 1.498 + info_ptr->valid &= ~PNG_INFO_sCAL; 1.499 + } 1.500 +#endif 1.501 + 1.502 +#ifdef PNG_pCAL_SUPPORTED 1.503 + /* Free any pCAL entry */ 1.504 + if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) 1.505 + { 1.506 + png_free(png_ptr, info_ptr->pcal_purpose); 1.507 + png_free(png_ptr, info_ptr->pcal_units); 1.508 + info_ptr->pcal_purpose = NULL; 1.509 + info_ptr->pcal_units = NULL; 1.510 + if (info_ptr->pcal_params != NULL) 1.511 + { 1.512 + unsigned int i; 1.513 + for (i = 0; i < info_ptr->pcal_nparams; i++) 1.514 + { 1.515 + png_free(png_ptr, info_ptr->pcal_params[i]); 1.516 + info_ptr->pcal_params[i] = NULL; 1.517 + } 1.518 + png_free(png_ptr, info_ptr->pcal_params); 1.519 + info_ptr->pcal_params = NULL; 1.520 + } 1.521 + info_ptr->valid &= ~PNG_INFO_pCAL; 1.522 + } 1.523 +#endif 1.524 + 1.525 +#ifdef PNG_iCCP_SUPPORTED 1.526 + /* Free any profile entry */ 1.527 + if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) 1.528 + { 1.529 + png_free(png_ptr, info_ptr->iccp_name); 1.530 + png_free(png_ptr, info_ptr->iccp_profile); 1.531 + info_ptr->iccp_name = NULL; 1.532 + info_ptr->iccp_profile = NULL; 1.533 + info_ptr->valid &= ~PNG_INFO_iCCP; 1.534 + } 1.535 +#endif 1.536 + 1.537 +#ifdef PNG_sPLT_SUPPORTED 1.538 + /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ 1.539 + if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) 1.540 + { 1.541 + if (num != -1) 1.542 + { 1.543 + if (info_ptr->splt_palettes) 1.544 + { 1.545 + png_free(png_ptr, info_ptr->splt_palettes[num].name); 1.546 + png_free(png_ptr, info_ptr->splt_palettes[num].entries); 1.547 + info_ptr->splt_palettes[num].name = NULL; 1.548 + info_ptr->splt_palettes[num].entries = NULL; 1.549 + } 1.550 + } 1.551 + 1.552 + else 1.553 + { 1.554 + if (info_ptr->splt_palettes_num) 1.555 + { 1.556 + int i; 1.557 + for (i = 0; i < info_ptr->splt_palettes_num; i++) 1.558 + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)i); 1.559 + 1.560 + png_free(png_ptr, info_ptr->splt_palettes); 1.561 + info_ptr->splt_palettes = NULL; 1.562 + info_ptr->splt_palettes_num = 0; 1.563 + } 1.564 + info_ptr->valid &= ~PNG_INFO_sPLT; 1.565 + } 1.566 + } 1.567 +#endif 1.568 + 1.569 +#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED 1.570 + if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) 1.571 + { 1.572 + if (num != -1) 1.573 + { 1.574 + if (info_ptr->unknown_chunks) 1.575 + { 1.576 + png_free(png_ptr, info_ptr->unknown_chunks[num].data); 1.577 + info_ptr->unknown_chunks[num].data = NULL; 1.578 + } 1.579 + } 1.580 + 1.581 + else 1.582 + { 1.583 + int i; 1.584 + 1.585 + if (info_ptr->unknown_chunks_num) 1.586 + { 1.587 + for (i = 0; i < info_ptr->unknown_chunks_num; i++) 1.588 + png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, (int)i); 1.589 + 1.590 + png_free(png_ptr, info_ptr->unknown_chunks); 1.591 + info_ptr->unknown_chunks = NULL; 1.592 + info_ptr->unknown_chunks_num = 0; 1.593 + } 1.594 + } 1.595 + } 1.596 +#endif 1.597 + 1.598 +#ifdef PNG_hIST_SUPPORTED 1.599 + /* Free any hIST entry */ 1.600 + if ((mask & PNG_FREE_HIST) & info_ptr->free_me) 1.601 + { 1.602 + png_free(png_ptr, info_ptr->hist); 1.603 + info_ptr->hist = NULL; 1.604 + info_ptr->valid &= ~PNG_INFO_hIST; 1.605 + } 1.606 +#endif 1.607 + 1.608 + /* Free any PLTE entry that was internally allocated */ 1.609 + if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) 1.610 + { 1.611 + png_free(png_ptr, info_ptr->palette); 1.612 + info_ptr->palette = NULL; 1.613 + info_ptr->valid &= ~PNG_INFO_PLTE; 1.614 + info_ptr->num_palette = 0; 1.615 + } 1.616 + 1.617 +#ifdef PNG_INFO_IMAGE_SUPPORTED 1.618 + /* Free any image bits attached to the info structure */ 1.619 + if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) 1.620 + { 1.621 + if (info_ptr->row_pointers) 1.622 + { 1.623 + png_uint_32 row; 1.624 + for (row = 0; row < info_ptr->height; row++) 1.625 + { 1.626 + png_free(png_ptr, info_ptr->row_pointers[row]); 1.627 + info_ptr->row_pointers[row] = NULL; 1.628 + } 1.629 + png_free(png_ptr, info_ptr->row_pointers); 1.630 + info_ptr->row_pointers = NULL; 1.631 + } 1.632 + info_ptr->valid &= ~PNG_INFO_IDAT; 1.633 + } 1.634 +#endif 1.635 + 1.636 + if (num != -1) 1.637 + mask &= ~PNG_FREE_MUL; 1.638 + 1.639 + info_ptr->free_me &= ~mask; 1.640 +} 1.641 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ 1.642 + 1.643 +/* This function returns a pointer to the io_ptr associated with the user 1.644 + * functions. The application should free any memory associated with this 1.645 + * pointer before png_write_destroy() or png_read_destroy() are called. 1.646 + */ 1.647 +png_voidp PNGAPI 1.648 +png_get_io_ptr(png_const_structrp png_ptr) 1.649 +{ 1.650 + if (png_ptr == NULL) 1.651 + return (NULL); 1.652 + 1.653 + return (png_ptr->io_ptr); 1.654 +} 1.655 + 1.656 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 1.657 +# ifdef PNG_STDIO_SUPPORTED 1.658 +/* Initialize the default input/output functions for the PNG file. If you 1.659 + * use your own read or write routines, you can call either png_set_read_fn() 1.660 + * or png_set_write_fn() instead of png_init_io(). If you have defined 1.661 + * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a 1.662 + * function of your own because "FILE *" isn't necessarily available. 1.663 + */ 1.664 +void PNGAPI 1.665 +png_init_io(png_structrp png_ptr, png_FILE_p fp) 1.666 +{ 1.667 + png_debug(1, "in png_init_io"); 1.668 + 1.669 + if (png_ptr == NULL) 1.670 + return; 1.671 + 1.672 + png_ptr->io_ptr = (png_voidp)fp; 1.673 +} 1.674 +# endif 1.675 + 1.676 +#ifdef PNG_SAVE_INT_32_SUPPORTED 1.677 +/* The png_save_int_32 function assumes integers are stored in two's 1.678 + * complement format. If this isn't the case, then this routine needs to 1.679 + * be modified to write data in two's complement format. Note that, 1.680 + * the following works correctly even if png_int_32 has more than 32 bits 1.681 + * (compare the more complex code required on read for sign extension.) 1.682 + */ 1.683 +void PNGAPI 1.684 +png_save_int_32(png_bytep buf, png_int_32 i) 1.685 +{ 1.686 + buf[0] = (png_byte)((i >> 24) & 0xff); 1.687 + buf[1] = (png_byte)((i >> 16) & 0xff); 1.688 + buf[2] = (png_byte)((i >> 8) & 0xff); 1.689 + buf[3] = (png_byte)(i & 0xff); 1.690 +} 1.691 +#endif 1.692 + 1.693 +# ifdef PNG_TIME_RFC1123_SUPPORTED 1.694 +/* Convert the supplied time into an RFC 1123 string suitable for use in 1.695 + * a "Creation Time" or other text-based time string. 1.696 + */ 1.697 +int PNGAPI 1.698 +png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) 1.699 +{ 1.700 + static PNG_CONST char short_months[12][4] = 1.701 + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 1.702 + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 1.703 + 1.704 + if (out == NULL) 1.705 + return 0; 1.706 + 1.707 + if (ptime->year > 9999 /* RFC1123 limitation */ || 1.708 + ptime->month == 0 || ptime->month > 12 || 1.709 + ptime->day == 0 || ptime->day > 31 || 1.710 + ptime->hour > 23 || ptime->minute > 59 || 1.711 + ptime->second > 60) 1.712 + return 0; 1.713 + 1.714 + { 1.715 + size_t pos = 0; 1.716 + char number_buf[5]; /* enough for a four-digit year */ 1.717 + 1.718 +# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) 1.719 +# define APPEND_NUMBER(format, value)\ 1.720 + APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) 1.721 +# define APPEND(ch) if (pos < 28) out[pos++] = (ch) 1.722 + 1.723 + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); 1.724 + APPEND(' '); 1.725 + APPEND_STRING(short_months[(ptime->month - 1)]); 1.726 + APPEND(' '); 1.727 + APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); 1.728 + APPEND(' '); 1.729 + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); 1.730 + APPEND(':'); 1.731 + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); 1.732 + APPEND(':'); 1.733 + APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); 1.734 + APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ 1.735 + 1.736 +# undef APPEND 1.737 +# undef APPEND_NUMBER 1.738 +# undef APPEND_STRING 1.739 + } 1.740 + 1.741 + return 1; 1.742 +} 1.743 + 1.744 +# if PNG_LIBPNG_VER < 10700 1.745 +/* To do: remove the following from libpng-1.7 */ 1.746 +/* Original API that uses a private buffer in png_struct. 1.747 + * Deprecated because it causes png_struct to carry a spurious temporary 1.748 + * buffer (png_struct::time_buffer), better to have the caller pass this in. 1.749 + */ 1.750 +png_const_charp PNGAPI 1.751 +png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) 1.752 +{ 1.753 + if (png_ptr != NULL) 1.754 + { 1.755 + /* The only failure above if png_ptr != NULL is from an invalid ptime */ 1.756 + if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime)) 1.757 + png_warning(png_ptr, "Ignoring invalid time value"); 1.758 + 1.759 + else 1.760 + return png_ptr->time_buffer; 1.761 + } 1.762 + 1.763 + return NULL; 1.764 +} 1.765 +# endif 1.766 +# endif /* PNG_TIME_RFC1123_SUPPORTED */ 1.767 + 1.768 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ 1.769 + 1.770 +png_const_charp PNGAPI 1.771 +png_get_copyright(png_const_structrp png_ptr) 1.772 +{ 1.773 + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 1.774 +#ifdef PNG_STRING_COPYRIGHT 1.775 + return PNG_STRING_COPYRIGHT 1.776 +#else 1.777 +# ifdef __STDC__ 1.778 + return PNG_STRING_NEWLINE \ 1.779 + "libpng version 1.6.10 - March 6, 2014" PNG_STRING_NEWLINE \ 1.780 + "Copyright (c) 1998-2014 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ 1.781 + "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ 1.782 + "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ 1.783 + PNG_STRING_NEWLINE; 1.784 +# else 1.785 + return "libpng version 1.6.10 - March 6, 2014\ 1.786 + Copyright (c) 1998-2014 Glenn Randers-Pehrson\ 1.787 + Copyright (c) 1996-1997 Andreas Dilger\ 1.788 + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; 1.789 +# endif 1.790 +#endif 1.791 +} 1.792 + 1.793 +/* The following return the library version as a short string in the 1.794 + * format 1.0.0 through 99.99.99zz. To get the version of *.h files 1.795 + * used with your application, print out PNG_LIBPNG_VER_STRING, which 1.796 + * is defined in png.h. 1.797 + * Note: now there is no difference between png_get_libpng_ver() and 1.798 + * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, 1.799 + * it is guaranteed that png.c uses the correct version of png.h. 1.800 + */ 1.801 +png_const_charp PNGAPI 1.802 +png_get_libpng_ver(png_const_structrp png_ptr) 1.803 +{ 1.804 + /* Version of *.c files used when building libpng */ 1.805 + return png_get_header_ver(png_ptr); 1.806 +} 1.807 + 1.808 +png_const_charp PNGAPI 1.809 +png_get_header_ver(png_const_structrp png_ptr) 1.810 +{ 1.811 + /* Version of *.h files used when building libpng */ 1.812 + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 1.813 + return PNG_LIBPNG_VER_STRING; 1.814 +} 1.815 + 1.816 +png_const_charp PNGAPI 1.817 +png_get_header_version(png_const_structrp png_ptr) 1.818 +{ 1.819 + /* Returns longer string containing both version and date */ 1.820 + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ 1.821 +#ifdef __STDC__ 1.822 + return PNG_HEADER_VERSION_STRING 1.823 +# ifndef PNG_READ_SUPPORTED 1.824 + " (NO READ SUPPORT)" 1.825 +# endif 1.826 + PNG_STRING_NEWLINE; 1.827 +#else 1.828 + return PNG_HEADER_VERSION_STRING; 1.829 +#endif 1.830 +} 1.831 + 1.832 +#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED 1.833 +/* NOTE: this routine is not used internally! */ 1.834 +/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth 1.835 + * large of png_color. This lets grayscale images be treated as 1.836 + * paletted. Most useful for gamma correction and simplification 1.837 + * of code. This API is not used internally. 1.838 + */ 1.839 +void PNGAPI 1.840 +png_build_grayscale_palette(int bit_depth, png_colorp palette) 1.841 +{ 1.842 + int num_palette; 1.843 + int color_inc; 1.844 + int i; 1.845 + int v; 1.846 + 1.847 + png_debug(1, "in png_do_build_grayscale_palette"); 1.848 + 1.849 + if (palette == NULL) 1.850 + return; 1.851 + 1.852 + switch (bit_depth) 1.853 + { 1.854 + case 1: 1.855 + num_palette = 2; 1.856 + color_inc = 0xff; 1.857 + break; 1.858 + 1.859 + case 2: 1.860 + num_palette = 4; 1.861 + color_inc = 0x55; 1.862 + break; 1.863 + 1.864 + case 4: 1.865 + num_palette = 16; 1.866 + color_inc = 0x11; 1.867 + break; 1.868 + 1.869 + case 8: 1.870 + num_palette = 256; 1.871 + color_inc = 1; 1.872 + break; 1.873 + 1.874 + default: 1.875 + num_palette = 0; 1.876 + color_inc = 0; 1.877 + break; 1.878 + } 1.879 + 1.880 + for (i = 0, v = 0; i < num_palette; i++, v += color_inc) 1.881 + { 1.882 + palette[i].red = (png_byte)v; 1.883 + palette[i].green = (png_byte)v; 1.884 + palette[i].blue = (png_byte)v; 1.885 + } 1.886 +} 1.887 +#endif 1.888 + 1.889 +#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED 1.890 +int PNGAPI 1.891 +png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) 1.892 +{ 1.893 + /* Check chunk_name and return "keep" value if it's on the list, else 0 */ 1.894 + png_const_bytep p, p_end; 1.895 + 1.896 + if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) 1.897 + return PNG_HANDLE_CHUNK_AS_DEFAULT; 1.898 + 1.899 + p_end = png_ptr->chunk_list; 1.900 + p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ 1.901 + 1.902 + /* The code is the fifth byte after each four byte string. Historically this 1.903 + * code was always searched from the end of the list, this is no longer 1.904 + * necessary because the 'set' routine handles duplicate entries correcty. 1.905 + */ 1.906 + do /* num_chunk_list > 0, so at least one */ 1.907 + { 1.908 + p -= 5; 1.909 + 1.910 + if (!memcmp(chunk_name, p, 4)) 1.911 + return p[4]; 1.912 + } 1.913 + while (p > p_end); 1.914 + 1.915 + /* This means that known chunks should be processed and unknown chunks should 1.916 + * be handled according to the value of png_ptr->unknown_default; this can be 1.917 + * confusing because, as a result, there are two levels of defaulting for 1.918 + * unknown chunks. 1.919 + */ 1.920 + return PNG_HANDLE_CHUNK_AS_DEFAULT; 1.921 +} 1.922 + 1.923 +#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ 1.924 + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) 1.925 +int /* PRIVATE */ 1.926 +png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) 1.927 +{ 1.928 + png_byte chunk_string[5]; 1.929 + 1.930 + PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); 1.931 + return png_handle_as_unknown(png_ptr, chunk_string); 1.932 +} 1.933 +#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ 1.934 +#endif /* SET_UNKNOWN_CHUNKS */ 1.935 + 1.936 +#ifdef PNG_READ_SUPPORTED 1.937 +/* This function, added to libpng-1.0.6g, is untested. */ 1.938 +int PNGAPI 1.939 +png_reset_zstream(png_structrp png_ptr) 1.940 +{ 1.941 + if (png_ptr == NULL) 1.942 + return Z_STREAM_ERROR; 1.943 + 1.944 + /* WARNING: this resets the window bits to the maximum! */ 1.945 + return (inflateReset(&png_ptr->zstream)); 1.946 +} 1.947 +#endif /* PNG_READ_SUPPORTED */ 1.948 + 1.949 +/* This function was added to libpng-1.0.7 */ 1.950 +png_uint_32 PNGAPI 1.951 +png_access_version_number(void) 1.952 +{ 1.953 + /* Version of *.c files used when building libpng */ 1.954 + return((png_uint_32)PNG_LIBPNG_VER); 1.955 +} 1.956 + 1.957 + 1.958 + 1.959 +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) 1.960 +/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. 1.961 + * If it doesn't 'ret' is used to set it to something appropriate, even in cases 1.962 + * like Z_OK or Z_STREAM_END where the error code is apparently a success code. 1.963 + */ 1.964 +void /* PRIVATE */ 1.965 +png_zstream_error(png_structrp png_ptr, int ret) 1.966 +{ 1.967 + /* Translate 'ret' into an appropriate error string, priority is given to the 1.968 + * one in zstream if set. This always returns a string, even in cases like 1.969 + * Z_OK or Z_STREAM_END where the error code is a success code. 1.970 + */ 1.971 + if (png_ptr->zstream.msg == NULL) switch (ret) 1.972 + { 1.973 + default: 1.974 + case Z_OK: 1.975 + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); 1.976 + break; 1.977 + 1.978 + case Z_STREAM_END: 1.979 + /* Normal exit */ 1.980 + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); 1.981 + break; 1.982 + 1.983 + case Z_NEED_DICT: 1.984 + /* This means the deflate stream did not have a dictionary; this 1.985 + * indicates a bogus PNG. 1.986 + */ 1.987 + png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); 1.988 + break; 1.989 + 1.990 + case Z_ERRNO: 1.991 + /* gz APIs only: should not happen */ 1.992 + png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); 1.993 + break; 1.994 + 1.995 + case Z_STREAM_ERROR: 1.996 + /* internal libpng error */ 1.997 + png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); 1.998 + break; 1.999 + 1.1000 + case Z_DATA_ERROR: 1.1001 + png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); 1.1002 + break; 1.1003 + 1.1004 + case Z_MEM_ERROR: 1.1005 + png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); 1.1006 + break; 1.1007 + 1.1008 + case Z_BUF_ERROR: 1.1009 + /* End of input or output; not a problem if the caller is doing 1.1010 + * incremental read or write. 1.1011 + */ 1.1012 + png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); 1.1013 + break; 1.1014 + 1.1015 + case Z_VERSION_ERROR: 1.1016 + png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); 1.1017 + break; 1.1018 + 1.1019 + case PNG_UNEXPECTED_ZLIB_RETURN: 1.1020 + /* Compile errors here mean that zlib now uses the value co-opted in 1.1021 + * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above 1.1022 + * and change pngpriv.h. Note that this message is "... return", 1.1023 + * whereas the default/Z_OK one is "... return code". 1.1024 + */ 1.1025 + png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); 1.1026 + break; 1.1027 + } 1.1028 +} 1.1029 + 1.1030 +/* png_convert_size: a PNGAPI but no longer in png.h, so deleted 1.1031 + * at libpng 1.5.5! 1.1032 + */ 1.1033 + 1.1034 +/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ 1.1035 +#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ 1.1036 +static int 1.1037 +png_colorspace_check_gamma(png_const_structrp png_ptr, 1.1038 + png_colorspacerp colorspace, png_fixed_point gAMA, int from) 1.1039 + /* This is called to check a new gamma value against an existing one. The 1.1040 + * routine returns false if the new gamma value should not be written. 1.1041 + * 1.1042 + * 'from' says where the new gamma value comes from: 1.1043 + * 1.1044 + * 0: the new gamma value is the libpng estimate for an ICC profile 1.1045 + * 1: the new gamma value comes from a gAMA chunk 1.1046 + * 2: the new gamma value comes from an sRGB chunk 1.1047 + */ 1.1048 +{ 1.1049 + png_fixed_point gtest; 1.1050 + 1.1051 + if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && 1.1052 + (!png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) || 1.1053 + png_gamma_significant(gtest))) 1.1054 + { 1.1055 + /* Either this is an sRGB image, in which case the calculated gamma 1.1056 + * approximation should match, or this is an image with a profile and the 1.1057 + * value libpng calculates for the gamma of the profile does not match the 1.1058 + * value recorded in the file. The former, sRGB, case is an error, the 1.1059 + * latter is just a warning. 1.1060 + */ 1.1061 + if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) 1.1062 + { 1.1063 + png_chunk_report(png_ptr, "gamma value does not match sRGB", 1.1064 + PNG_CHUNK_ERROR); 1.1065 + /* Do not overwrite an sRGB value */ 1.1066 + return from == 2; 1.1067 + } 1.1068 + 1.1069 + else /* sRGB tag not involved */ 1.1070 + { 1.1071 + png_chunk_report(png_ptr, "gamma value does not match libpng estimate", 1.1072 + PNG_CHUNK_WARNING); 1.1073 + return from == 1; 1.1074 + } 1.1075 + } 1.1076 + 1.1077 + return 1; 1.1078 +} 1.1079 + 1.1080 +void /* PRIVATE */ 1.1081 +png_colorspace_set_gamma(png_const_structrp png_ptr, 1.1082 + png_colorspacerp colorspace, png_fixed_point gAMA) 1.1083 +{ 1.1084 + /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't 1.1085 + * occur. Since the fixed point representation is assymetrical it is 1.1086 + * possible for 1/gamma to overflow the limit of 21474 and this means the 1.1087 + * gamma value must be at least 5/100000 and hence at most 20000.0. For 1.1088 + * safety the limits here are a little narrower. The values are 0.00016 to 1.1089 + * 6250.0, which are truly ridiculous gamma values (and will produce 1.1090 + * displays that are all black or all white.) 1.1091 + * 1.1092 + * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk 1.1093 + * handling code, which only required the value to be >0. 1.1094 + */ 1.1095 + png_const_charp errmsg; 1.1096 + 1.1097 + if (gAMA < 16 || gAMA > 625000000) 1.1098 + errmsg = "gamma value out of range"; 1.1099 + 1.1100 +# ifdef PNG_READ_gAMA_SUPPORTED 1.1101 + /* Allow the application to set the gamma value more than once */ 1.1102 + else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && 1.1103 + (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) 1.1104 + errmsg = "duplicate"; 1.1105 +# endif 1.1106 + 1.1107 + /* Do nothing if the colorspace is already invalid */ 1.1108 + else if (colorspace->flags & PNG_COLORSPACE_INVALID) 1.1109 + return; 1.1110 + 1.1111 + else 1.1112 + { 1.1113 + if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/)) 1.1114 + { 1.1115 + /* Store this gamma value. */ 1.1116 + colorspace->gamma = gAMA; 1.1117 + colorspace->flags |= 1.1118 + (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); 1.1119 + } 1.1120 + 1.1121 + /* At present if the check_gamma test fails the gamma of the colorspace is 1.1122 + * not updated however the colorspace is not invalidated. This 1.1123 + * corresponds to the case where the existing gamma comes from an sRGB 1.1124 + * chunk or profile. An error message has already been output. 1.1125 + */ 1.1126 + return; 1.1127 + } 1.1128 + 1.1129 + /* Error exit - errmsg has been set. */ 1.1130 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1131 + png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); 1.1132 +} 1.1133 + 1.1134 +void /* PRIVATE */ 1.1135 +png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) 1.1136 +{ 1.1137 + if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) 1.1138 + { 1.1139 + /* Everything is invalid */ 1.1140 + info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| 1.1141 + PNG_INFO_iCCP); 1.1142 + 1.1143 +# ifdef PNG_COLORSPACE_SUPPORTED 1.1144 + /* Clean up the iCCP profile now if it won't be used. */ 1.1145 + png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); 1.1146 +# else 1.1147 + PNG_UNUSED(png_ptr) 1.1148 +# endif 1.1149 + } 1.1150 + 1.1151 + else 1.1152 + { 1.1153 +# ifdef PNG_COLORSPACE_SUPPORTED 1.1154 + /* Leave the INFO_iCCP flag set if the pngset.c code has already set 1.1155 + * it; this allows a PNG to contain a profile which matches sRGB and 1.1156 + * yet still have that profile retrievable by the application. 1.1157 + */ 1.1158 + if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) 1.1159 + info_ptr->valid |= PNG_INFO_sRGB; 1.1160 + 1.1161 + else 1.1162 + info_ptr->valid &= ~PNG_INFO_sRGB; 1.1163 + 1.1164 + if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) 1.1165 + info_ptr->valid |= PNG_INFO_cHRM; 1.1166 + 1.1167 + else 1.1168 + info_ptr->valid &= ~PNG_INFO_cHRM; 1.1169 +# endif 1.1170 + 1.1171 + if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) 1.1172 + info_ptr->valid |= PNG_INFO_gAMA; 1.1173 + 1.1174 + else 1.1175 + info_ptr->valid &= ~PNG_INFO_gAMA; 1.1176 + } 1.1177 +} 1.1178 + 1.1179 +#ifdef PNG_READ_SUPPORTED 1.1180 +void /* PRIVATE */ 1.1181 +png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) 1.1182 +{ 1.1183 + if (info_ptr == NULL) /* reduce code size; check here not in the caller */ 1.1184 + return; 1.1185 + 1.1186 + info_ptr->colorspace = png_ptr->colorspace; 1.1187 + png_colorspace_sync_info(png_ptr, info_ptr); 1.1188 +} 1.1189 +#endif 1.1190 +#endif 1.1191 + 1.1192 +#ifdef PNG_COLORSPACE_SUPPORTED 1.1193 +/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for 1.1194 + * cHRM, as opposed to using chromaticities. These internal APIs return 1.1195 + * non-zero on a parameter error. The X, Y and Z values are required to be 1.1196 + * positive and less than 1.0. 1.1197 + */ 1.1198 +static int 1.1199 +png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) 1.1200 +{ 1.1201 + png_int_32 d, dwhite, whiteX, whiteY; 1.1202 + 1.1203 + d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; 1.1204 + if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1; 1.1205 + if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1; 1.1206 + dwhite = d; 1.1207 + whiteX = XYZ->red_X; 1.1208 + whiteY = XYZ->red_Y; 1.1209 + 1.1210 + d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; 1.1211 + if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1; 1.1212 + if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1; 1.1213 + dwhite += d; 1.1214 + whiteX += XYZ->green_X; 1.1215 + whiteY += XYZ->green_Y; 1.1216 + 1.1217 + d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; 1.1218 + if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1; 1.1219 + if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1; 1.1220 + dwhite += d; 1.1221 + whiteX += XYZ->blue_X; 1.1222 + whiteY += XYZ->blue_Y; 1.1223 + 1.1224 + /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, 1.1225 + * thus: 1.1226 + */ 1.1227 + if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1; 1.1228 + if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1; 1.1229 + 1.1230 + return 0; 1.1231 +} 1.1232 + 1.1233 +static int 1.1234 +png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) 1.1235 +{ 1.1236 + png_fixed_point red_inverse, green_inverse, blue_scale; 1.1237 + png_fixed_point left, right, denominator; 1.1238 + 1.1239 + /* Check xy and, implicitly, z. Note that wide gamut color spaces typically 1.1240 + * have end points with 0 tristimulus values (these are impossible end 1.1241 + * points, but they are used to cover the possible colors.) 1.1242 + */ 1.1243 + if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; 1.1244 + if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; 1.1245 + if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; 1.1246 + if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; 1.1247 + if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; 1.1248 + if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; 1.1249 + if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; 1.1250 + if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1; 1.1251 + 1.1252 + /* The reverse calculation is more difficult because the original tristimulus 1.1253 + * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 1.1254 + * derived values were recorded in the cHRM chunk; 1.1255 + * (red,green,blue,white)x(x,y). This loses one degree of freedom and 1.1256 + * therefore an arbitrary ninth value has to be introduced to undo the 1.1257 + * original transformations. 1.1258 + * 1.1259 + * Think of the original end-points as points in (X,Y,Z) space. The 1.1260 + * chromaticity values (c) have the property: 1.1261 + * 1.1262 + * C 1.1263 + * c = --------- 1.1264 + * X + Y + Z 1.1265 + * 1.1266 + * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the 1.1267 + * three chromaticity values (x,y,z) for each end-point obey the 1.1268 + * relationship: 1.1269 + * 1.1270 + * x + y + z = 1 1.1271 + * 1.1272 + * This describes the plane in (X,Y,Z) space that intersects each axis at the 1.1273 + * value 1.0; call this the chromaticity plane. Thus the chromaticity 1.1274 + * calculation has scaled each end-point so that it is on the x+y+z=1 plane 1.1275 + * and chromaticity is the intersection of the vector from the origin to the 1.1276 + * (X,Y,Z) value with the chromaticity plane. 1.1277 + * 1.1278 + * To fully invert the chromaticity calculation we would need the three 1.1279 + * end-point scale factors, (red-scale, green-scale, blue-scale), but these 1.1280 + * were not recorded. Instead we calculated the reference white (X,Y,Z) and 1.1281 + * recorded the chromaticity of this. The reference white (X,Y,Z) would have 1.1282 + * given all three of the scale factors since: 1.1283 + * 1.1284 + * color-C = color-c * color-scale 1.1285 + * white-C = red-C + green-C + blue-C 1.1286 + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale 1.1287 + * 1.1288 + * But cHRM records only white-x and white-y, so we have lost the white scale 1.1289 + * factor: 1.1290 + * 1.1291 + * white-C = white-c*white-scale 1.1292 + * 1.1293 + * To handle this the inverse transformation makes an arbitrary assumption 1.1294 + * about white-scale: 1.1295 + * 1.1296 + * Assume: white-Y = 1.0 1.1297 + * Hence: white-scale = 1/white-y 1.1298 + * Or: red-Y + green-Y + blue-Y = 1.0 1.1299 + * 1.1300 + * Notice the last statement of the assumption gives an equation in three of 1.1301 + * the nine values we want to calculate. 8 more equations come from the 1.1302 + * above routine as summarised at the top above (the chromaticity 1.1303 + * calculation): 1.1304 + * 1.1305 + * Given: color-x = color-X / (color-X + color-Y + color-Z) 1.1306 + * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 1.1307 + * 1.1308 + * This is 9 simultaneous equations in the 9 variables "color-C" and can be 1.1309 + * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix 1.1310 + * determinants, however this is not as bad as it seems because only 28 of 1.1311 + * the total of 90 terms in the various matrices are non-zero. Nevertheless 1.1312 + * Cramer's rule is notoriously numerically unstable because the determinant 1.1313 + * calculation involves the difference of large, but similar, numbers. It is 1.1314 + * difficult to be sure that the calculation is stable for real world values 1.1315 + * and it is certain that it becomes unstable where the end points are close 1.1316 + * together. 1.1317 + * 1.1318 + * So this code uses the perhaps slightly less optimal but more 1.1319 + * understandable and totally obvious approach of calculating color-scale. 1.1320 + * 1.1321 + * This algorithm depends on the precision in white-scale and that is 1.1322 + * (1/white-y), so we can immediately see that as white-y approaches 0 the 1.1323 + * accuracy inherent in the cHRM chunk drops off substantially. 1.1324 + * 1.1325 + * libpng arithmetic: a simple invertion of the above equations 1.1326 + * ------------------------------------------------------------ 1.1327 + * 1.1328 + * white_scale = 1/white-y 1.1329 + * white-X = white-x * white-scale 1.1330 + * white-Y = 1.0 1.1331 + * white-Z = (1 - white-x - white-y) * white_scale 1.1332 + * 1.1333 + * white-C = red-C + green-C + blue-C 1.1334 + * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale 1.1335 + * 1.1336 + * This gives us three equations in (red-scale,green-scale,blue-scale) where 1.1337 + * all the coefficients are now known: 1.1338 + * 1.1339 + * red-x*red-scale + green-x*green-scale + blue-x*blue-scale 1.1340 + * = white-x/white-y 1.1341 + * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 1.1342 + * red-z*red-scale + green-z*green-scale + blue-z*blue-scale 1.1343 + * = (1 - white-x - white-y)/white-y 1.1344 + * 1.1345 + * In the last equation color-z is (1 - color-x - color-y) so we can add all 1.1346 + * three equations together to get an alternative third: 1.1347 + * 1.1348 + * red-scale + green-scale + blue-scale = 1/white-y = white-scale 1.1349 + * 1.1350 + * So now we have a Cramer's rule solution where the determinants are just 1.1351 + * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve 1.1352 + * multiplication of three coefficients so we can't guarantee to avoid 1.1353 + * overflow in the libpng fixed point representation. Using Cramer's rule in 1.1354 + * floating point is probably a good choice here, but it's not an option for 1.1355 + * fixed point. Instead proceed to simplify the first two equations by 1.1356 + * eliminating what is likely to be the largest value, blue-scale: 1.1357 + * 1.1358 + * blue-scale = white-scale - red-scale - green-scale 1.1359 + * 1.1360 + * Hence: 1.1361 + * 1.1362 + * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = 1.1363 + * (white-x - blue-x)*white-scale 1.1364 + * 1.1365 + * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = 1.1366 + * 1 - blue-y*white-scale 1.1367 + * 1.1368 + * And now we can trivially solve for (red-scale,green-scale): 1.1369 + * 1.1370 + * green-scale = 1.1371 + * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale 1.1372 + * ----------------------------------------------------------- 1.1373 + * green-x - blue-x 1.1374 + * 1.1375 + * red-scale = 1.1376 + * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale 1.1377 + * --------------------------------------------------------- 1.1378 + * red-y - blue-y 1.1379 + * 1.1380 + * Hence: 1.1381 + * 1.1382 + * red-scale = 1.1383 + * ( (green-x - blue-x) * (white-y - blue-y) - 1.1384 + * (green-y - blue-y) * (white-x - blue-x) ) / white-y 1.1385 + * ------------------------------------------------------------------------- 1.1386 + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) 1.1387 + * 1.1388 + * green-scale = 1.1389 + * ( (red-y - blue-y) * (white-x - blue-x) - 1.1390 + * (red-x - blue-x) * (white-y - blue-y) ) / white-y 1.1391 + * ------------------------------------------------------------------------- 1.1392 + * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) 1.1393 + * 1.1394 + * Accuracy: 1.1395 + * The input values have 5 decimal digits of accuracy. The values are all in 1.1396 + * the range 0 < value < 1, so simple products are in the same range but may 1.1397 + * need up to 10 decimal digits to preserve the original precision and avoid 1.1398 + * underflow. Because we are using a 32-bit signed representation we cannot 1.1399 + * match this; the best is a little over 9 decimal digits, less than 10. 1.1400 + * 1.1401 + * The approach used here is to preserve the maximum precision within the 1.1402 + * signed representation. Because the red-scale calculation above uses the 1.1403 + * difference between two products of values that must be in the range -1..+1 1.1404 + * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The 1.1405 + * factor is irrelevant in the calculation because it is applied to both 1.1406 + * numerator and denominator. 1.1407 + * 1.1408 + * Note that the values of the differences of the products of the 1.1409 + * chromaticities in the above equations tend to be small, for example for 1.1410 + * the sRGB chromaticities they are: 1.1411 + * 1.1412 + * red numerator: -0.04751 1.1413 + * green numerator: -0.08788 1.1414 + * denominator: -0.2241 (without white-y multiplication) 1.1415 + * 1.1416 + * The resultant Y coefficients from the chromaticities of some widely used 1.1417 + * color space definitions are (to 15 decimal places): 1.1418 + * 1.1419 + * sRGB 1.1420 + * 0.212639005871510 0.715168678767756 0.072192315360734 1.1421 + * Kodak ProPhoto 1.1422 + * 0.288071128229293 0.711843217810102 0.000085653960605 1.1423 + * Adobe RGB 1.1424 + * 0.297344975250536 0.627363566255466 0.075291458493998 1.1425 + * Adobe Wide Gamut RGB 1.1426 + * 0.258728243040113 0.724682314948566 0.016589442011321 1.1427 + */ 1.1428 + /* By the argument, above overflow should be impossible here. The return 1.1429 + * value of 2 indicates an internal error to the caller. 1.1430 + */ 1.1431 + if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7)) 1.1432 + return 2; 1.1433 + if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7)) 1.1434 + return 2; 1.1435 + denominator = left - right; 1.1436 + 1.1437 + /* Now find the red numerator. */ 1.1438 + if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7)) 1.1439 + return 2; 1.1440 + if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7)) 1.1441 + return 2; 1.1442 + 1.1443 + /* Overflow is possible here and it indicates an extreme set of PNG cHRM 1.1444 + * chunk values. This calculation actually returns the reciprocal of the 1.1445 + * scale value because this allows us to delay the multiplication of white-y 1.1446 + * into the denominator, which tends to produce a small number. 1.1447 + */ 1.1448 + if (!png_muldiv(&red_inverse, xy->whitey, denominator, left-right) || 1.1449 + red_inverse <= xy->whitey /* r+g+b scales = white scale */) 1.1450 + return 1; 1.1451 + 1.1452 + /* Similarly for green_inverse: */ 1.1453 + if (!png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7)) 1.1454 + return 2; 1.1455 + if (!png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7)) 1.1456 + return 2; 1.1457 + if (!png_muldiv(&green_inverse, xy->whitey, denominator, left-right) || 1.1458 + green_inverse <= xy->whitey) 1.1459 + return 1; 1.1460 + 1.1461 + /* And the blue scale, the checks above guarantee this can't overflow but it 1.1462 + * can still produce 0 for extreme cHRM values. 1.1463 + */ 1.1464 + blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - 1.1465 + png_reciprocal(green_inverse); 1.1466 + if (blue_scale <= 0) return 1; 1.1467 + 1.1468 + 1.1469 + /* And fill in the png_XYZ: */ 1.1470 + if (!png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1; 1.1471 + if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1; 1.1472 + if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, 1.1473 + red_inverse)) 1.1474 + return 1; 1.1475 + 1.1476 + if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse)) 1.1477 + return 1; 1.1478 + if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse)) 1.1479 + return 1; 1.1480 + if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, 1.1481 + green_inverse)) 1.1482 + return 1; 1.1483 + 1.1484 + if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1; 1.1485 + if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1; 1.1486 + if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, 1.1487 + PNG_FP_1)) 1.1488 + return 1; 1.1489 + 1.1490 + return 0; /*success*/ 1.1491 +} 1.1492 + 1.1493 +static int 1.1494 +png_XYZ_normalize(png_XYZ *XYZ) 1.1495 +{ 1.1496 + png_int_32 Y; 1.1497 + 1.1498 + if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || 1.1499 + XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || 1.1500 + XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) 1.1501 + return 1; 1.1502 + 1.1503 + /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. 1.1504 + * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore 1.1505 + * relying on addition of two positive values producing a negative one is not 1.1506 + * safe. 1.1507 + */ 1.1508 + Y = XYZ->red_Y; 1.1509 + if (0x7fffffff - Y < XYZ->green_X) return 1; 1.1510 + Y += XYZ->green_Y; 1.1511 + if (0x7fffffff - Y < XYZ->blue_X) return 1; 1.1512 + Y += XYZ->blue_Y; 1.1513 + 1.1514 + if (Y != PNG_FP_1) 1.1515 + { 1.1516 + if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1; 1.1517 + if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1; 1.1518 + if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1; 1.1519 + 1.1520 + if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1; 1.1521 + if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1; 1.1522 + if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1; 1.1523 + 1.1524 + if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1; 1.1525 + if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1; 1.1526 + if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1; 1.1527 + } 1.1528 + 1.1529 + return 0; 1.1530 +} 1.1531 + 1.1532 +static int 1.1533 +png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) 1.1534 +{ 1.1535 + /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ 1.1536 + return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || 1.1537 + PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || 1.1538 + PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || 1.1539 + PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || 1.1540 + PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || 1.1541 + PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || 1.1542 + PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || 1.1543 + PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)); 1.1544 +} 1.1545 + 1.1546 +/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM 1.1547 + * chunk chromaticities. Earlier checks used to simply look for the overflow 1.1548 + * condition (where the determinant of the matrix to solve for XYZ ends up zero 1.1549 + * because the chromaticity values are not all distinct.) Despite this it is 1.1550 + * theoretically possible to produce chromaticities that are apparently valid 1.1551 + * but that rapidly degrade to invalid, potentially crashing, sets because of 1.1552 + * arithmetic inaccuracies when calculations are performed on them. The new 1.1553 + * check is to round-trip xy -> XYZ -> xy and then check that the result is 1.1554 + * within a small percentage of the original. 1.1555 + */ 1.1556 +static int 1.1557 +png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) 1.1558 +{ 1.1559 + int result; 1.1560 + png_xy xy_test; 1.1561 + 1.1562 + /* As a side-effect this routine also returns the XYZ endpoints. */ 1.1563 + result = png_XYZ_from_xy(XYZ, xy); 1.1564 + if (result) return result; 1.1565 + 1.1566 + result = png_xy_from_XYZ(&xy_test, XYZ); 1.1567 + if (result) return result; 1.1568 + 1.1569 + if (png_colorspace_endpoints_match(xy, &xy_test, 1.1570 + 5/*actually, the math is pretty accurate*/)) 1.1571 + return 0; 1.1572 + 1.1573 + /* Too much slip */ 1.1574 + return 1; 1.1575 +} 1.1576 + 1.1577 +/* This is the check going the other way. The XYZ is modified to normalize it 1.1578 + * (another side-effect) and the xy chromaticities are returned. 1.1579 + */ 1.1580 +static int 1.1581 +png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) 1.1582 +{ 1.1583 + int result; 1.1584 + png_XYZ XYZtemp; 1.1585 + 1.1586 + result = png_XYZ_normalize(XYZ); 1.1587 + if (result) return result; 1.1588 + 1.1589 + result = png_xy_from_XYZ(xy, XYZ); 1.1590 + if (result) return result; 1.1591 + 1.1592 + XYZtemp = *XYZ; 1.1593 + return png_colorspace_check_xy(&XYZtemp, xy); 1.1594 +} 1.1595 + 1.1596 +/* Used to check for an endpoint match against sRGB */ 1.1597 +static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ 1.1598 +{ 1.1599 + /* color x y */ 1.1600 + /* red */ 64000, 33000, 1.1601 + /* green */ 30000, 60000, 1.1602 + /* blue */ 15000, 6000, 1.1603 + /* white */ 31270, 32900 1.1604 +}; 1.1605 + 1.1606 +static int 1.1607 +png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, 1.1608 + png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, 1.1609 + int preferred) 1.1610 +{ 1.1611 + if (colorspace->flags & PNG_COLORSPACE_INVALID) 1.1612 + return 0; 1.1613 + 1.1614 + /* The consistency check is performed on the chromaticities; this factors out 1.1615 + * variations because of the normalization (or not) of the end point Y 1.1616 + * values. 1.1617 + */ 1.1618 + if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS)) 1.1619 + { 1.1620 + /* The end points must be reasonably close to any we already have. The 1.1621 + * following allows an error of up to +/-.001 1.1622 + */ 1.1623 + if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100)) 1.1624 + { 1.1625 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1626 + png_benign_error(png_ptr, "inconsistent chromaticities"); 1.1627 + return 0; /* failed */ 1.1628 + } 1.1629 + 1.1630 + /* Only overwrite with preferred values */ 1.1631 + if (!preferred) 1.1632 + return 1; /* ok, but no change */ 1.1633 + } 1.1634 + 1.1635 + colorspace->end_points_xy = *xy; 1.1636 + colorspace->end_points_XYZ = *XYZ; 1.1637 + colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; 1.1638 + 1.1639 + /* The end points are normally quoted to two decimal digits, so allow +/-0.01 1.1640 + * on this test. 1.1641 + */ 1.1642 + if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000)) 1.1643 + colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; 1.1644 + 1.1645 + else 1.1646 + colorspace->flags &= PNG_COLORSPACE_CANCEL( 1.1647 + PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); 1.1648 + 1.1649 + return 2; /* ok and changed */ 1.1650 +} 1.1651 + 1.1652 +int /* PRIVATE */ 1.1653 +png_colorspace_set_chromaticities(png_const_structrp png_ptr, 1.1654 + png_colorspacerp colorspace, const png_xy *xy, int preferred) 1.1655 +{ 1.1656 + /* We must check the end points to ensure they are reasonable - in the past 1.1657 + * color management systems have crashed as a result of getting bogus 1.1658 + * colorant values, while this isn't the fault of libpng it is the 1.1659 + * responsibility of libpng because PNG carries the bomb and libpng is in a 1.1660 + * position to protect against it. 1.1661 + */ 1.1662 + png_XYZ XYZ; 1.1663 + 1.1664 + switch (png_colorspace_check_xy(&XYZ, xy)) 1.1665 + { 1.1666 + case 0: /* success */ 1.1667 + return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, 1.1668 + preferred); 1.1669 + 1.1670 + case 1: 1.1671 + /* We can't invert the chromaticities so we can't produce value XYZ 1.1672 + * values. Likely as not a color management system will fail too. 1.1673 + */ 1.1674 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1675 + png_benign_error(png_ptr, "invalid chromaticities"); 1.1676 + break; 1.1677 + 1.1678 + default: 1.1679 + /* libpng is broken; this should be a warning but if it happens we 1.1680 + * want error reports so for the moment it is an error. 1.1681 + */ 1.1682 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1683 + png_error(png_ptr, "internal error checking chromaticities"); 1.1684 + break; 1.1685 + } 1.1686 + 1.1687 + return 0; /* failed */ 1.1688 +} 1.1689 + 1.1690 +int /* PRIVATE */ 1.1691 +png_colorspace_set_endpoints(png_const_structrp png_ptr, 1.1692 + png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) 1.1693 +{ 1.1694 + png_XYZ XYZ = *XYZ_in; 1.1695 + png_xy xy; 1.1696 + 1.1697 + switch (png_colorspace_check_XYZ(&xy, &XYZ)) 1.1698 + { 1.1699 + case 0: 1.1700 + return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, 1.1701 + preferred); 1.1702 + 1.1703 + case 1: 1.1704 + /* End points are invalid. */ 1.1705 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1706 + png_benign_error(png_ptr, "invalid end points"); 1.1707 + break; 1.1708 + 1.1709 + default: 1.1710 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1711 + png_error(png_ptr, "internal error checking chromaticities"); 1.1712 + break; 1.1713 + } 1.1714 + 1.1715 + return 0; /* failed */ 1.1716 +} 1.1717 + 1.1718 +#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) 1.1719 +/* Error message generation */ 1.1720 +static char 1.1721 +png_icc_tag_char(png_uint_32 byte) 1.1722 +{ 1.1723 + byte &= 0xff; 1.1724 + if (byte >= 32 && byte <= 126) 1.1725 + return (char)byte; 1.1726 + else 1.1727 + return '?'; 1.1728 +} 1.1729 + 1.1730 +static void 1.1731 +png_icc_tag_name(char *name, png_uint_32 tag) 1.1732 +{ 1.1733 + name[0] = '\''; 1.1734 + name[1] = png_icc_tag_char(tag >> 24); 1.1735 + name[2] = png_icc_tag_char(tag >> 16); 1.1736 + name[3] = png_icc_tag_char(tag >> 8); 1.1737 + name[4] = png_icc_tag_char(tag ); 1.1738 + name[5] = '\''; 1.1739 +} 1.1740 + 1.1741 +static int 1.1742 +is_ICC_signature_char(png_alloc_size_t it) 1.1743 +{ 1.1744 + return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || 1.1745 + (it >= 97 && it <= 122); 1.1746 +} 1.1747 + 1.1748 +static int 1.1749 +is_ICC_signature(png_alloc_size_t it) 1.1750 +{ 1.1751 + return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && 1.1752 + is_ICC_signature_char((it >> 16) & 0xff) && 1.1753 + is_ICC_signature_char((it >> 8) & 0xff) && 1.1754 + is_ICC_signature_char(it & 0xff); 1.1755 +} 1.1756 + 1.1757 +static int 1.1758 +png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.1759 + png_const_charp name, png_alloc_size_t value, png_const_charp reason) 1.1760 +{ 1.1761 + size_t pos; 1.1762 + char message[196]; /* see below for calculation */ 1.1763 + 1.1764 + if (colorspace != NULL) 1.1765 + colorspace->flags |= PNG_COLORSPACE_INVALID; 1.1766 + 1.1767 + pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ 1.1768 + pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ 1.1769 + pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ 1.1770 + if (is_ICC_signature(value)) 1.1771 + { 1.1772 + /* So 'value' is at most 4 bytes and the following cast is safe */ 1.1773 + png_icc_tag_name(message+pos, (png_uint_32)value); 1.1774 + pos += 6; /* total +8; less than the else clause */ 1.1775 + message[pos++] = ':'; 1.1776 + message[pos++] = ' '; 1.1777 + } 1.1778 +# ifdef PNG_WARNINGS_SUPPORTED 1.1779 + else 1.1780 + { 1.1781 + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ 1.1782 + 1.1783 + pos = png_safecat(message, (sizeof message), pos, 1.1784 + png_format_number(number, number+(sizeof number), 1.1785 + PNG_NUMBER_FORMAT_x, value)); 1.1786 + pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ 1.1787 + } 1.1788 +# endif 1.1789 + /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ 1.1790 + pos = png_safecat(message, (sizeof message), pos, reason); 1.1791 + PNG_UNUSED(pos) 1.1792 + 1.1793 + /* This is recoverable, but make it unconditionally an app_error on write to 1.1794 + * avoid writing invalid ICC profiles into PNG files. (I.e. we handle them 1.1795 + * on read, with a warning, but on write unless the app turns off 1.1796 + * application errors the PNG won't be written.) 1.1797 + */ 1.1798 + png_chunk_report(png_ptr, message, 1.1799 + (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); 1.1800 + 1.1801 + return 0; 1.1802 +} 1.1803 +#endif /* sRGB || iCCP */ 1.1804 + 1.1805 +#ifdef PNG_sRGB_SUPPORTED 1.1806 +int /* PRIVATE */ 1.1807 +png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.1808 + int intent) 1.1809 +{ 1.1810 + /* sRGB sets known gamma, end points and (from the chunk) intent. */ 1.1811 + /* IMPORTANT: these are not necessarily the values found in an ICC profile 1.1812 + * because ICC profiles store values adapted to a D50 environment; it is 1.1813 + * expected that the ICC profile mediaWhitePointTag will be D50, see the 1.1814 + * checks and code elsewhere to understand this better. 1.1815 + * 1.1816 + * These XYZ values, which are accurate to 5dp, produce rgb to gray 1.1817 + * coefficients of (6968,23435,2366), which are reduced (because they add up 1.1818 + * to 32769 not 32768) to (6968,23434,2366). These are the values that 1.1819 + * libpng has traditionally used (and are the best values given the 15bit 1.1820 + * algorithm used by the rgb to gray code.) 1.1821 + */ 1.1822 + static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ 1.1823 + { 1.1824 + /* color X Y Z */ 1.1825 + /* red */ 41239, 21264, 1933, 1.1826 + /* green */ 35758, 71517, 11919, 1.1827 + /* blue */ 18048, 7219, 95053 1.1828 + }; 1.1829 + 1.1830 + /* Do nothing if the colorspace is already invalidated. */ 1.1831 + if (colorspace->flags & PNG_COLORSPACE_INVALID) 1.1832 + return 0; 1.1833 + 1.1834 + /* Check the intent, then check for existing settings. It is valid for the 1.1835 + * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must 1.1836 + * be consistent with the correct values. If, however, this function is 1.1837 + * called below because an iCCP chunk matches sRGB then it is quite 1.1838 + * conceivable that an older app recorded incorrect gAMA and cHRM because of 1.1839 + * an incorrect calculation based on the values in the profile - this does 1.1840 + * *not* invalidate the profile (though it still produces an error, which can 1.1841 + * be ignored.) 1.1842 + */ 1.1843 + if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) 1.1844 + return png_icc_profile_error(png_ptr, colorspace, "sRGB", 1.1845 + (unsigned)intent, "invalid sRGB rendering intent"); 1.1846 + 1.1847 + if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && 1.1848 + colorspace->rendering_intent != intent) 1.1849 + return png_icc_profile_error(png_ptr, colorspace, "sRGB", 1.1850 + (unsigned)intent, "inconsistent rendering intents"); 1.1851 + 1.1852 + if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) 1.1853 + { 1.1854 + png_benign_error(png_ptr, "duplicate sRGB information ignored"); 1.1855 + return 0; 1.1856 + } 1.1857 + 1.1858 + /* If the standard sRGB cHRM chunk does not match the one from the PNG file 1.1859 + * warn but overwrite the value with the correct one. 1.1860 + */ 1.1861 + if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && 1.1862 + !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, 1.1863 + 100)) 1.1864 + png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", 1.1865 + PNG_CHUNK_ERROR); 1.1866 + 1.1867 + /* This check is just done for the error reporting - the routine always 1.1868 + * returns true when the 'from' argument corresponds to sRGB (2). 1.1869 + */ 1.1870 + (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, 1.1871 + 2/*from sRGB*/); 1.1872 + 1.1873 + /* intent: bugs in GCC force 'int' to be used as the parameter type. */ 1.1874 + colorspace->rendering_intent = (png_uint_16)intent; 1.1875 + colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; 1.1876 + 1.1877 + /* endpoints */ 1.1878 + colorspace->end_points_xy = sRGB_xy; 1.1879 + colorspace->end_points_XYZ = sRGB_XYZ; 1.1880 + colorspace->flags |= 1.1881 + (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); 1.1882 + 1.1883 + /* gamma */ 1.1884 + colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; 1.1885 + colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; 1.1886 + 1.1887 + /* Finally record that we have an sRGB profile */ 1.1888 + colorspace->flags |= 1.1889 + (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); 1.1890 + 1.1891 + return 1; /* set */ 1.1892 +} 1.1893 +#endif /* sRGB */ 1.1894 + 1.1895 +#ifdef PNG_iCCP_SUPPORTED 1.1896 +/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value 1.1897 + * is XYZ(0.9642,1.0,0.8249), which scales to: 1.1898 + * 1.1899 + * (63189.8112, 65536, 54060.6464) 1.1900 + */ 1.1901 +static const png_byte D50_nCIEXYZ[12] = 1.1902 + { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; 1.1903 + 1.1904 +int /* PRIVATE */ 1.1905 +png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.1906 + png_const_charp name, png_uint_32 profile_length) 1.1907 +{ 1.1908 + if (profile_length < 132) 1.1909 + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, 1.1910 + "too short"); 1.1911 + 1.1912 + if (profile_length & 3) 1.1913 + return png_icc_profile_error(png_ptr, colorspace, name, profile_length, 1.1914 + "invalid length"); 1.1915 + 1.1916 + return 1; 1.1917 +} 1.1918 + 1.1919 +int /* PRIVATE */ 1.1920 +png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.1921 + png_const_charp name, png_uint_32 profile_length, 1.1922 + png_const_bytep profile/* first 132 bytes only */, int color_type) 1.1923 +{ 1.1924 + png_uint_32 temp; 1.1925 + 1.1926 + /* Length check; this cannot be ignored in this code because profile_length 1.1927 + * is used later to check the tag table, so even if the profile seems over 1.1928 + * long profile_length from the caller must be correct. The caller can fix 1.1929 + * this up on read or write by just passing in the profile header length. 1.1930 + */ 1.1931 + temp = png_get_uint_32(profile); 1.1932 + if (temp != profile_length) 1.1933 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.1934 + "length does not match profile"); 1.1935 + 1.1936 + temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ 1.1937 + if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ 1.1938 + profile_length < 132+12*temp) /* truncated tag table */ 1.1939 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.1940 + "tag count too large"); 1.1941 + 1.1942 + /* The 'intent' must be valid or we can't store it, ICC limits the intent to 1.1943 + * 16 bits. 1.1944 + */ 1.1945 + temp = png_get_uint_32(profile+64); 1.1946 + if (temp >= 0xffff) /* The ICC limit */ 1.1947 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.1948 + "invalid rendering intent"); 1.1949 + 1.1950 + /* This is just a warning because the profile may be valid in future 1.1951 + * versions. 1.1952 + */ 1.1953 + if (temp >= PNG_sRGB_INTENT_LAST) 1.1954 + (void)png_icc_profile_error(png_ptr, NULL, name, temp, 1.1955 + "intent outside defined range"); 1.1956 + 1.1957 + /* At this point the tag table can't be checked because it hasn't necessarily 1.1958 + * been loaded; however, various header fields can be checked. These checks 1.1959 + * are for values permitted by the PNG spec in an ICC profile; the PNG spec 1.1960 + * restricts the profiles that can be passed in an iCCP chunk (they must be 1.1961 + * appropriate to processing PNG data!) 1.1962 + */ 1.1963 + 1.1964 + /* Data checks (could be skipped). These checks must be independent of the 1.1965 + * version number; however, the version number doesn't accomodate changes in 1.1966 + * the header fields (just the known tags and the interpretation of the 1.1967 + * data.) 1.1968 + */ 1.1969 + temp = png_get_uint_32(profile+36); /* signature 'ascp' */ 1.1970 + if (temp != 0x61637370) 1.1971 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.1972 + "invalid signature"); 1.1973 + 1.1974 + /* Currently the PCS illuminant/adopted white point (the computational 1.1975 + * white point) are required to be D50, 1.1976 + * however the profile contains a record of the illuminant so perhaps ICC 1.1977 + * expects to be able to change this in the future (despite the rationale in 1.1978 + * the introduction for using a fixed PCS adopted white.) Consequently the 1.1979 + * following is just a warning. 1.1980 + */ 1.1981 + if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) 1.1982 + (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, 1.1983 + "PCS illuminant is not D50"); 1.1984 + 1.1985 + /* The PNG spec requires this: 1.1986 + * "If the iCCP chunk is present, the image samples conform to the colour 1.1987 + * space represented by the embedded ICC profile as defined by the 1.1988 + * International Color Consortium [ICC]. The colour space of the ICC profile 1.1989 + * shall be an RGB colour space for colour images (PNG colour types 2, 3, and 1.1990 + * 6), or a greyscale colour space for greyscale images (PNG colour types 0 1.1991 + * and 4)." 1.1992 + * 1.1993 + * This checking code ensures the embedded profile (on either read or write) 1.1994 + * conforms to the specification requirements. Notice that an ICC 'gray' 1.1995 + * color-space profile contains the information to transform the monochrome 1.1996 + * data to XYZ or L*a*b (according to which PCS the profile uses) and this 1.1997 + * should be used in preference to the standard libpng K channel replication 1.1998 + * into R, G and B channels. 1.1999 + * 1.2000 + * Previously it was suggested that an RGB profile on grayscale data could be 1.2001 + * handled. However it it is clear that using an RGB profile in this context 1.2002 + * must be an error - there is no specification of what it means. Thus it is 1.2003 + * almost certainly more correct to ignore the profile. 1.2004 + */ 1.2005 + temp = png_get_uint_32(profile+16); /* data colour space field */ 1.2006 + switch (temp) 1.2007 + { 1.2008 + case 0x52474220: /* 'RGB ' */ 1.2009 + if (!(color_type & PNG_COLOR_MASK_COLOR)) 1.2010 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2011 + "RGB color space not permitted on grayscale PNG"); 1.2012 + break; 1.2013 + 1.2014 + case 0x47524159: /* 'GRAY' */ 1.2015 + if (color_type & PNG_COLOR_MASK_COLOR) 1.2016 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2017 + "Gray color space not permitted on RGB PNG"); 1.2018 + break; 1.2019 + 1.2020 + default: 1.2021 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2022 + "invalid ICC profile color space"); 1.2023 + } 1.2024 + 1.2025 + /* It is up to the application to check that the profile class matches the 1.2026 + * application requirements; the spec provides no guidance, but it's pretty 1.2027 + * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer 1.2028 + * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these 1.2029 + * cases. Issue an error for device link or abstract profiles - these don't 1.2030 + * contain the records necessary to transform the color-space to anything 1.2031 + * other than the target device (and not even that for an abstract profile). 1.2032 + * Profiles of these classes may not be embedded in images. 1.2033 + */ 1.2034 + temp = png_get_uint_32(profile+12); /* profile/device class */ 1.2035 + switch (temp) 1.2036 + { 1.2037 + case 0x73636E72: /* 'scnr' */ 1.2038 + case 0x6D6E7472: /* 'mntr' */ 1.2039 + case 0x70727472: /* 'prtr' */ 1.2040 + case 0x73706163: /* 'spac' */ 1.2041 + /* All supported */ 1.2042 + break; 1.2043 + 1.2044 + case 0x61627374: /* 'abst' */ 1.2045 + /* May not be embedded in an image */ 1.2046 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2047 + "invalid embedded Abstract ICC profile"); 1.2048 + 1.2049 + case 0x6C696E6B: /* 'link' */ 1.2050 + /* DeviceLink profiles cannnot be interpreted in a non-device specific 1.2051 + * fashion, if an app uses the AToB0Tag in the profile the results are 1.2052 + * undefined unless the result is sent to the intended device, 1.2053 + * therefore a DeviceLink profile should not be found embedded in a 1.2054 + * PNG. 1.2055 + */ 1.2056 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2057 + "unexpected DeviceLink ICC profile class"); 1.2058 + 1.2059 + case 0x6E6D636C: /* 'nmcl' */ 1.2060 + /* A NamedColor profile is also device specific, however it doesn't 1.2061 + * contain an AToB0 tag that is open to misintrepretation. Almost 1.2062 + * certainly it will fail the tests below. 1.2063 + */ 1.2064 + (void)png_icc_profile_error(png_ptr, NULL, name, temp, 1.2065 + "unexpected NamedColor ICC profile class"); 1.2066 + break; 1.2067 + 1.2068 + default: 1.2069 + /* To allow for future enhancements to the profile accept unrecognized 1.2070 + * profile classes with a warning, these then hit the test below on the 1.2071 + * tag content to ensure they are backward compatible with one of the 1.2072 + * understood profiles. 1.2073 + */ 1.2074 + (void)png_icc_profile_error(png_ptr, NULL, name, temp, 1.2075 + "unrecognized ICC profile class"); 1.2076 + break; 1.2077 + } 1.2078 + 1.2079 + /* For any profile other than a device link one the PCS must be encoded 1.2080 + * either in XYZ or Lab. 1.2081 + */ 1.2082 + temp = png_get_uint_32(profile+20); 1.2083 + switch (temp) 1.2084 + { 1.2085 + case 0x58595A20: /* 'XYZ ' */ 1.2086 + case 0x4C616220: /* 'Lab ' */ 1.2087 + break; 1.2088 + 1.2089 + default: 1.2090 + return png_icc_profile_error(png_ptr, colorspace, name, temp, 1.2091 + "unexpected ICC PCS encoding"); 1.2092 + } 1.2093 + 1.2094 + return 1; 1.2095 +} 1.2096 + 1.2097 +int /* PRIVATE */ 1.2098 +png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.2099 + png_const_charp name, png_uint_32 profile_length, 1.2100 + png_const_bytep profile /* header plus whole tag table */) 1.2101 +{ 1.2102 + png_uint_32 tag_count = png_get_uint_32(profile+128); 1.2103 + png_uint_32 itag; 1.2104 + png_const_bytep tag = profile+132; /* The first tag */ 1.2105 + 1.2106 + /* First scan all the tags in the table and add bits to the icc_info value 1.2107 + * (temporarily in 'tags'). 1.2108 + */ 1.2109 + for (itag=0; itag < tag_count; ++itag, tag += 12) 1.2110 + { 1.2111 + png_uint_32 tag_id = png_get_uint_32(tag+0); 1.2112 + png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ 1.2113 + png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ 1.2114 + 1.2115 + /* The ICC specification does not exclude zero length tags, therefore the 1.2116 + * start might actually be anywhere if there is no data, but this would be 1.2117 + * a clear abuse of the intent of the standard so the start is checked for 1.2118 + * being in range. All defined tag types have an 8 byte header - a 4 byte 1.2119 + * type signature then 0. 1.2120 + */ 1.2121 + if ((tag_start & 3) != 0) 1.2122 + { 1.2123 + /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is 1.2124 + * only a warning here because libpng does not care about the 1.2125 + * alignment. 1.2126 + */ 1.2127 + (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, 1.2128 + "ICC profile tag start not a multiple of 4"); 1.2129 + } 1.2130 + 1.2131 + /* This is a hard error; potentially it can cause read outside the 1.2132 + * profile. 1.2133 + */ 1.2134 + if (tag_start > profile_length || tag_length > profile_length - tag_start) 1.2135 + return png_icc_profile_error(png_ptr, colorspace, name, tag_id, 1.2136 + "ICC profile tag outside profile"); 1.2137 + } 1.2138 + 1.2139 + return 1; /* success, maybe with warnings */ 1.2140 +} 1.2141 + 1.2142 +#ifdef PNG_sRGB_SUPPORTED 1.2143 +/* Information about the known ICC sRGB profiles */ 1.2144 +static const struct 1.2145 +{ 1.2146 + png_uint_32 adler, crc, length; 1.2147 + png_uint_32 md5[4]; 1.2148 + png_byte have_md5; 1.2149 + png_byte is_broken; 1.2150 + png_uint_16 intent; 1.2151 + 1.2152 +# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) 1.2153 +# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ 1.2154 + { adler, crc, length, md5, broke, intent }, 1.2155 + 1.2156 +} png_sRGB_checks[] = 1.2157 +{ 1.2158 + /* This data comes from contrib/tools/checksum-icc run on downloads of 1.2159 + * all four ICC sRGB profiles from www.color.org. 1.2160 + */ 1.2161 + /* adler32, crc32, MD5[4], intent, date, length, file-name */ 1.2162 + PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, 1.2163 + PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, 1.2164 + "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") 1.2165 + 1.2166 + /* ICC sRGB v2 perceptual no black-compensation: */ 1.2167 + PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, 1.2168 + PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, 1.2169 + "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") 1.2170 + 1.2171 + PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, 1.2172 + PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, 1.2173 + "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") 1.2174 + 1.2175 + /* ICC sRGB v4 perceptual */ 1.2176 + PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, 1.2177 + PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, 1.2178 + "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") 1.2179 + 1.2180 + /* The following profiles have no known MD5 checksum. If there is a match 1.2181 + * on the (empty) MD5 the other fields are used to attempt a match and 1.2182 + * a warning is produced. The first two of these profiles have a 'cprt' tag 1.2183 + * which suggests that they were also made by Hewlett Packard. 1.2184 + */ 1.2185 + PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, 1.2186 + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, 1.2187 + "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") 1.2188 + 1.2189 + /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not 1.2190 + * match the D50 PCS illuminant in the header (it is in fact the D65 values, 1.2191 + * so the white point is recorded as the un-adapted value.) The profiles 1.2192 + * below only differ in one byte - the intent - and are basically the same as 1.2193 + * the previous profile except for the mediaWhitePointTag error and a missing 1.2194 + * chromaticAdaptationTag. 1.2195 + */ 1.2196 + PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, 1.2197 + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, 1.2198 + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") 1.2199 + 1.2200 + PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, 1.2201 + PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, 1.2202 + "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") 1.2203 +}; 1.2204 + 1.2205 +static int 1.2206 +png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, 1.2207 + png_const_bytep profile, uLong adler) 1.2208 +{ 1.2209 + /* The quick check is to verify just the MD5 signature and trust the 1.2210 + * rest of the data. Because the profile has already been verified for 1.2211 + * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' 1.2212 + * field too, so if the profile has been edited with an intent not defined 1.2213 + * by sRGB (but maybe defined by a later ICC specification) the read of 1.2214 + * the profile will fail at that point. 1.2215 + */ 1.2216 + png_uint_32 length = 0; 1.2217 + png_uint_32 intent = 0x10000; /* invalid */ 1.2218 +#if PNG_sRGB_PROFILE_CHECKS > 1 1.2219 + uLong crc = 0; /* the value for 0 length data */ 1.2220 +#endif 1.2221 + unsigned int i; 1.2222 + 1.2223 + for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) 1.2224 + { 1.2225 + if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && 1.2226 + png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && 1.2227 + png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && 1.2228 + png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) 1.2229 + { 1.2230 + /* This may be one of the old HP profiles without an MD5, in that 1.2231 + * case we can only use the length and Adler32 (note that these 1.2232 + * are not used by default if there is an MD5!) 1.2233 + */ 1.2234 +# if PNG_sRGB_PROFILE_CHECKS == 0 1.2235 + if (png_sRGB_checks[i].have_md5) 1.2236 + return 1+png_sRGB_checks[i].is_broken; 1.2237 +# endif 1.2238 + 1.2239 + /* Profile is unsigned or more checks have been configured in. */ 1.2240 + if (length == 0) 1.2241 + { 1.2242 + length = png_get_uint_32(profile); 1.2243 + intent = png_get_uint_32(profile+64); 1.2244 + } 1.2245 + 1.2246 + /* Length *and* intent must match */ 1.2247 + if (length == png_sRGB_checks[i].length && 1.2248 + intent == png_sRGB_checks[i].intent) 1.2249 + { 1.2250 + /* Now calculate the adler32 if not done already. */ 1.2251 + if (adler == 0) 1.2252 + { 1.2253 + adler = adler32(0, NULL, 0); 1.2254 + adler = adler32(adler, profile, length); 1.2255 + } 1.2256 + 1.2257 + if (adler == png_sRGB_checks[i].adler) 1.2258 + { 1.2259 + /* These basic checks suggest that the data has not been 1.2260 + * modified, but if the check level is more than 1 perform 1.2261 + * our own crc32 checksum on the data. 1.2262 + */ 1.2263 +# if PNG_sRGB_PROFILE_CHECKS > 1 1.2264 + if (crc == 0) 1.2265 + { 1.2266 + crc = crc32(0, NULL, 0); 1.2267 + crc = crc32(crc, profile, length); 1.2268 + } 1.2269 + 1.2270 + /* So this check must pass for the 'return' below to happen. 1.2271 + */ 1.2272 + if (crc == png_sRGB_checks[i].crc) 1.2273 +# endif 1.2274 + { 1.2275 + if (png_sRGB_checks[i].is_broken) 1.2276 + { 1.2277 + /* These profiles are known to have bad data that may cause 1.2278 + * problems if they are used, therefore attempt to 1.2279 + * discourage their use, skip the 'have_md5' warning below, 1.2280 + * which is made irrelevant by this error. 1.2281 + */ 1.2282 + png_chunk_report(png_ptr, "known incorrect sRGB profile", 1.2283 + PNG_CHUNK_ERROR); 1.2284 + } 1.2285 + 1.2286 + /* Warn that this being done; this isn't even an error since 1.2287 + * the profile is perfectly valid, but it would be nice if 1.2288 + * people used the up-to-date ones. 1.2289 + */ 1.2290 + else if (!png_sRGB_checks[i].have_md5) 1.2291 + { 1.2292 + png_chunk_report(png_ptr, 1.2293 + "out-of-date sRGB profile with no signature", 1.2294 + PNG_CHUNK_WARNING); 1.2295 + } 1.2296 + 1.2297 + return 1+png_sRGB_checks[i].is_broken; 1.2298 + } 1.2299 + } 1.2300 + } 1.2301 + 1.2302 +# if PNG_sRGB_PROFILE_CHECKS > 0 1.2303 + /* The signature matched, but the profile had been changed in some 1.2304 + * way. This probably indicates a data error or uninformed hacking. 1.2305 + * Fall through to "no match". 1.2306 + */ 1.2307 + png_chunk_report(png_ptr, 1.2308 + "Not recognizing known sRGB profile that has been edited", 1.2309 + PNG_CHUNK_WARNING); 1.2310 + break; 1.2311 +# endif 1.2312 + } 1.2313 + } 1.2314 + 1.2315 + return 0; /* no match */ 1.2316 +} 1.2317 +#endif 1.2318 + 1.2319 +#ifdef PNG_sRGB_SUPPORTED 1.2320 +void /* PRIVATE */ 1.2321 +png_icc_set_sRGB(png_const_structrp png_ptr, 1.2322 + png_colorspacerp colorspace, png_const_bytep profile, uLong adler) 1.2323 +{ 1.2324 + /* Is this profile one of the known ICC sRGB profiles? If it is, just set 1.2325 + * the sRGB information. 1.2326 + */ 1.2327 + if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler)) 1.2328 + (void)png_colorspace_set_sRGB(png_ptr, colorspace, 1.2329 + (int)/*already checked*/png_get_uint_32(profile+64)); 1.2330 +} 1.2331 +#endif /* PNG_READ_sRGB_SUPPORTED */ 1.2332 + 1.2333 +int /* PRIVATE */ 1.2334 +png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, 1.2335 + png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, 1.2336 + int color_type) 1.2337 +{ 1.2338 + if (colorspace->flags & PNG_COLORSPACE_INVALID) 1.2339 + return 0; 1.2340 + 1.2341 + if (png_icc_check_length(png_ptr, colorspace, name, profile_length) && 1.2342 + png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, 1.2343 + color_type) && 1.2344 + png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, 1.2345 + profile)) 1.2346 + { 1.2347 +# ifdef PNG_sRGB_SUPPORTED 1.2348 + /* If no sRGB support, don't try storing sRGB information */ 1.2349 + png_icc_set_sRGB(png_ptr, colorspace, profile, 0); 1.2350 +# endif 1.2351 + return 1; 1.2352 + } 1.2353 + 1.2354 + /* Failure case */ 1.2355 + return 0; 1.2356 +} 1.2357 +#endif /* iCCP */ 1.2358 + 1.2359 +#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED 1.2360 +void /* PRIVATE */ 1.2361 +png_colorspace_set_rgb_coefficients(png_structrp png_ptr) 1.2362 +{ 1.2363 + /* Set the rgb_to_gray coefficients from the colorspace. */ 1.2364 + if (!png_ptr->rgb_to_gray_coefficients_set && 1.2365 + (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) 1.2366 + { 1.2367 + /* png_set_background has not been called, get the coefficients from the Y 1.2368 + * values of the colorspace colorants. 1.2369 + */ 1.2370 + png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; 1.2371 + png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; 1.2372 + png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; 1.2373 + png_fixed_point total = r+g+b; 1.2374 + 1.2375 + if (total > 0 && 1.2376 + r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && 1.2377 + g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && 1.2378 + b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && 1.2379 + r+g+b <= 32769) 1.2380 + { 1.2381 + /* We allow 0 coefficients here. r+g+b may be 32769 if two or 1.2382 + * all of the coefficients were rounded up. Handle this by 1.2383 + * reducing the *largest* coefficient by 1; this matches the 1.2384 + * approach used for the default coefficients in pngrtran.c 1.2385 + */ 1.2386 + int add = 0; 1.2387 + 1.2388 + if (r+g+b > 32768) 1.2389 + add = -1; 1.2390 + else if (r+g+b < 32768) 1.2391 + add = 1; 1.2392 + 1.2393 + if (add != 0) 1.2394 + { 1.2395 + if (g >= r && g >= b) 1.2396 + g += add; 1.2397 + else if (r >= g && r >= b) 1.2398 + r += add; 1.2399 + else 1.2400 + b += add; 1.2401 + } 1.2402 + 1.2403 + /* Check for an internal error. */ 1.2404 + if (r+g+b != 32768) 1.2405 + png_error(png_ptr, 1.2406 + "internal error handling cHRM coefficients"); 1.2407 + 1.2408 + else 1.2409 + { 1.2410 + png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; 1.2411 + png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; 1.2412 + } 1.2413 + } 1.2414 + 1.2415 + /* This is a png_error at present even though it could be ignored - 1.2416 + * it should never happen, but it is important that if it does, the 1.2417 + * bug is fixed. 1.2418 + */ 1.2419 + else 1.2420 + png_error(png_ptr, "internal error handling cHRM->XYZ"); 1.2421 + } 1.2422 +} 1.2423 +#endif 1.2424 + 1.2425 +#endif /* COLORSPACE */ 1.2426 + 1.2427 +void /* PRIVATE */ 1.2428 +png_check_IHDR(png_const_structrp png_ptr, 1.2429 + png_uint_32 width, png_uint_32 height, int bit_depth, 1.2430 + int color_type, int interlace_type, int compression_type, 1.2431 + int filter_type) 1.2432 +{ 1.2433 + int error = 0; 1.2434 + 1.2435 + /* Check for width and height valid values */ 1.2436 + if (width == 0) 1.2437 + { 1.2438 + png_warning(png_ptr, "Image width is zero in IHDR"); 1.2439 + error = 1; 1.2440 + } 1.2441 + 1.2442 + if (height == 0) 1.2443 + { 1.2444 + png_warning(png_ptr, "Image height is zero in IHDR"); 1.2445 + error = 1; 1.2446 + } 1.2447 + 1.2448 +# ifdef PNG_SET_USER_LIMITS_SUPPORTED 1.2449 + if (width > png_ptr->user_width_max) 1.2450 + 1.2451 +# else 1.2452 + if (width > PNG_USER_WIDTH_MAX) 1.2453 +# endif 1.2454 + { 1.2455 + png_warning(png_ptr, "Image width exceeds user limit in IHDR"); 1.2456 + error = 1; 1.2457 + } 1.2458 + 1.2459 +# ifdef PNG_SET_USER_LIMITS_SUPPORTED 1.2460 + if (height > png_ptr->user_height_max) 1.2461 +# else 1.2462 + if (height > PNG_USER_HEIGHT_MAX) 1.2463 +# endif 1.2464 + { 1.2465 + png_warning(png_ptr, "Image height exceeds user limit in IHDR"); 1.2466 + error = 1; 1.2467 + } 1.2468 + 1.2469 + if (width > PNG_UINT_31_MAX) 1.2470 + { 1.2471 + png_warning(png_ptr, "Invalid image width in IHDR"); 1.2472 + error = 1; 1.2473 + } 1.2474 + 1.2475 + if (height > PNG_UINT_31_MAX) 1.2476 + { 1.2477 + png_warning(png_ptr, "Invalid image height in IHDR"); 1.2478 + error = 1; 1.2479 + } 1.2480 + 1.2481 + /* Check other values */ 1.2482 + if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && 1.2483 + bit_depth != 8 && bit_depth != 16) 1.2484 + { 1.2485 + png_warning(png_ptr, "Invalid bit depth in IHDR"); 1.2486 + error = 1; 1.2487 + } 1.2488 + 1.2489 + if (color_type < 0 || color_type == 1 || 1.2490 + color_type == 5 || color_type > 6) 1.2491 + { 1.2492 + png_warning(png_ptr, "Invalid color type in IHDR"); 1.2493 + error = 1; 1.2494 + } 1.2495 + 1.2496 + if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || 1.2497 + ((color_type == PNG_COLOR_TYPE_RGB || 1.2498 + color_type == PNG_COLOR_TYPE_GRAY_ALPHA || 1.2499 + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) 1.2500 + { 1.2501 + png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); 1.2502 + error = 1; 1.2503 + } 1.2504 + 1.2505 + if (interlace_type >= PNG_INTERLACE_LAST) 1.2506 + { 1.2507 + png_warning(png_ptr, "Unknown interlace method in IHDR"); 1.2508 + error = 1; 1.2509 + } 1.2510 + 1.2511 + if (compression_type != PNG_COMPRESSION_TYPE_BASE) 1.2512 + { 1.2513 + png_warning(png_ptr, "Unknown compression method in IHDR"); 1.2514 + error = 1; 1.2515 + } 1.2516 + 1.2517 +# ifdef PNG_MNG_FEATURES_SUPPORTED 1.2518 + /* Accept filter_method 64 (intrapixel differencing) only if 1.2519 + * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and 1.2520 + * 2. Libpng did not read a PNG signature (this filter_method is only 1.2521 + * used in PNG datastreams that are embedded in MNG datastreams) and 1.2522 + * 3. The application called png_permit_mng_features with a mask that 1.2523 + * included PNG_FLAG_MNG_FILTER_64 and 1.2524 + * 4. The filter_method is 64 and 1.2525 + * 5. The color_type is RGB or RGBA 1.2526 + */ 1.2527 + if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) && 1.2528 + png_ptr->mng_features_permitted) 1.2529 + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); 1.2530 + 1.2531 + if (filter_type != PNG_FILTER_TYPE_BASE) 1.2532 + { 1.2533 + if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && 1.2534 + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && 1.2535 + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && 1.2536 + (color_type == PNG_COLOR_TYPE_RGB || 1.2537 + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) 1.2538 + { 1.2539 + png_warning(png_ptr, "Unknown filter method in IHDR"); 1.2540 + error = 1; 1.2541 + } 1.2542 + 1.2543 + if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) 1.2544 + { 1.2545 + png_warning(png_ptr, "Invalid filter method in IHDR"); 1.2546 + error = 1; 1.2547 + } 1.2548 + } 1.2549 + 1.2550 +# else 1.2551 + if (filter_type != PNG_FILTER_TYPE_BASE) 1.2552 + { 1.2553 + png_warning(png_ptr, "Unknown filter method in IHDR"); 1.2554 + error = 1; 1.2555 + } 1.2556 +# endif 1.2557 + 1.2558 + if (error == 1) 1.2559 + png_error(png_ptr, "Invalid IHDR data"); 1.2560 +} 1.2561 + 1.2562 +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) 1.2563 +/* ASCII to fp functions */ 1.2564 +/* Check an ASCII formated floating point value, see the more detailed 1.2565 + * comments in pngpriv.h 1.2566 + */ 1.2567 +/* The following is used internally to preserve the sticky flags */ 1.2568 +#define png_fp_add(state, flags) ((state) |= (flags)) 1.2569 +#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) 1.2570 + 1.2571 +int /* PRIVATE */ 1.2572 +png_check_fp_number(png_const_charp string, png_size_t size, int *statep, 1.2573 + png_size_tp whereami) 1.2574 +{ 1.2575 + int state = *statep; 1.2576 + png_size_t i = *whereami; 1.2577 + 1.2578 + while (i < size) 1.2579 + { 1.2580 + int type; 1.2581 + /* First find the type of the next character */ 1.2582 + switch (string[i]) 1.2583 + { 1.2584 + case 43: type = PNG_FP_SAW_SIGN; break; 1.2585 + case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; 1.2586 + case 46: type = PNG_FP_SAW_DOT; break; 1.2587 + case 48: type = PNG_FP_SAW_DIGIT; break; 1.2588 + case 49: case 50: case 51: case 52: 1.2589 + case 53: case 54: case 55: case 56: 1.2590 + case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; 1.2591 + case 69: 1.2592 + case 101: type = PNG_FP_SAW_E; break; 1.2593 + default: goto PNG_FP_End; 1.2594 + } 1.2595 + 1.2596 + /* Now deal with this type according to the current 1.2597 + * state, the type is arranged to not overlap the 1.2598 + * bits of the PNG_FP_STATE. 1.2599 + */ 1.2600 + switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) 1.2601 + { 1.2602 + case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: 1.2603 + if (state & PNG_FP_SAW_ANY) 1.2604 + goto PNG_FP_End; /* not a part of the number */ 1.2605 + 1.2606 + png_fp_add(state, type); 1.2607 + break; 1.2608 + 1.2609 + case PNG_FP_INTEGER + PNG_FP_SAW_DOT: 1.2610 + /* Ok as trailer, ok as lead of fraction. */ 1.2611 + if (state & PNG_FP_SAW_DOT) /* two dots */ 1.2612 + goto PNG_FP_End; 1.2613 + 1.2614 + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ 1.2615 + png_fp_add(state, type); 1.2616 + 1.2617 + else 1.2618 + png_fp_set(state, PNG_FP_FRACTION | type); 1.2619 + 1.2620 + break; 1.2621 + 1.2622 + case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: 1.2623 + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ 1.2624 + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); 1.2625 + 1.2626 + png_fp_add(state, type | PNG_FP_WAS_VALID); 1.2627 + 1.2628 + break; 1.2629 + 1.2630 + case PNG_FP_INTEGER + PNG_FP_SAW_E: 1.2631 + if ((state & PNG_FP_SAW_DIGIT) == 0) 1.2632 + goto PNG_FP_End; 1.2633 + 1.2634 + png_fp_set(state, PNG_FP_EXPONENT); 1.2635 + 1.2636 + break; 1.2637 + 1.2638 + /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: 1.2639 + goto PNG_FP_End; ** no sign in fraction */ 1.2640 + 1.2641 + /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: 1.2642 + goto PNG_FP_End; ** Because SAW_DOT is always set */ 1.2643 + 1.2644 + case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: 1.2645 + png_fp_add(state, type | PNG_FP_WAS_VALID); 1.2646 + break; 1.2647 + 1.2648 + case PNG_FP_FRACTION + PNG_FP_SAW_E: 1.2649 + /* This is correct because the trailing '.' on an 1.2650 + * integer is handled above - so we can only get here 1.2651 + * with the sequence ".E" (with no preceding digits). 1.2652 + */ 1.2653 + if ((state & PNG_FP_SAW_DIGIT) == 0) 1.2654 + goto PNG_FP_End; 1.2655 + 1.2656 + png_fp_set(state, PNG_FP_EXPONENT); 1.2657 + 1.2658 + break; 1.2659 + 1.2660 + case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: 1.2661 + if (state & PNG_FP_SAW_ANY) 1.2662 + goto PNG_FP_End; /* not a part of the number */ 1.2663 + 1.2664 + png_fp_add(state, PNG_FP_SAW_SIGN); 1.2665 + 1.2666 + break; 1.2667 + 1.2668 + /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: 1.2669 + goto PNG_FP_End; */ 1.2670 + 1.2671 + case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: 1.2672 + png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); 1.2673 + 1.2674 + break; 1.2675 + 1.2676 + /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: 1.2677 + goto PNG_FP_End; */ 1.2678 + 1.2679 + default: goto PNG_FP_End; /* I.e. break 2 */ 1.2680 + } 1.2681 + 1.2682 + /* The character seems ok, continue. */ 1.2683 + ++i; 1.2684 + } 1.2685 + 1.2686 +PNG_FP_End: 1.2687 + /* Here at the end, update the state and return the correct 1.2688 + * return code. 1.2689 + */ 1.2690 + *statep = state; 1.2691 + *whereami = i; 1.2692 + 1.2693 + return (state & PNG_FP_SAW_DIGIT) != 0; 1.2694 +} 1.2695 + 1.2696 + 1.2697 +/* The same but for a complete string. */ 1.2698 +int 1.2699 +png_check_fp_string(png_const_charp string, png_size_t size) 1.2700 +{ 1.2701 + int state=0; 1.2702 + png_size_t char_index=0; 1.2703 + 1.2704 + if (png_check_fp_number(string, size, &state, &char_index) && 1.2705 + (char_index == size || string[char_index] == 0)) 1.2706 + return state /* must be non-zero - see above */; 1.2707 + 1.2708 + return 0; /* i.e. fail */ 1.2709 +} 1.2710 +#endif /* pCAL or sCAL */ 1.2711 + 1.2712 +#ifdef PNG_sCAL_SUPPORTED 1.2713 +# ifdef PNG_FLOATING_POINT_SUPPORTED 1.2714 +/* Utility used below - a simple accurate power of ten from an integral 1.2715 + * exponent. 1.2716 + */ 1.2717 +static double 1.2718 +png_pow10(int power) 1.2719 +{ 1.2720 + int recip = 0; 1.2721 + double d = 1; 1.2722 + 1.2723 + /* Handle negative exponent with a reciprocal at the end because 1.2724 + * 10 is exact whereas .1 is inexact in base 2 1.2725 + */ 1.2726 + if (power < 0) 1.2727 + { 1.2728 + if (power < DBL_MIN_10_EXP) return 0; 1.2729 + recip = 1, power = -power; 1.2730 + } 1.2731 + 1.2732 + if (power > 0) 1.2733 + { 1.2734 + /* Decompose power bitwise. */ 1.2735 + double mult = 10; 1.2736 + do 1.2737 + { 1.2738 + if (power & 1) d *= mult; 1.2739 + mult *= mult; 1.2740 + power >>= 1; 1.2741 + } 1.2742 + while (power > 0); 1.2743 + 1.2744 + if (recip) d = 1/d; 1.2745 + } 1.2746 + /* else power is 0 and d is 1 */ 1.2747 + 1.2748 + return d; 1.2749 +} 1.2750 + 1.2751 +/* Function to format a floating point value in ASCII with a given 1.2752 + * precision. 1.2753 + */ 1.2754 +void /* PRIVATE */ 1.2755 +png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, 1.2756 + double fp, unsigned int precision) 1.2757 +{ 1.2758 + /* We use standard functions from math.h, but not printf because 1.2759 + * that would require stdio. The caller must supply a buffer of 1.2760 + * sufficient size or we will png_error. The tests on size and 1.2761 + * the space in ascii[] consumed are indicated below. 1.2762 + */ 1.2763 + if (precision < 1) 1.2764 + precision = DBL_DIG; 1.2765 + 1.2766 + /* Enforce the limit of the implementation precision too. */ 1.2767 + if (precision > DBL_DIG+1) 1.2768 + precision = DBL_DIG+1; 1.2769 + 1.2770 + /* Basic sanity checks */ 1.2771 + if (size >= precision+5) /* See the requirements below. */ 1.2772 + { 1.2773 + if (fp < 0) 1.2774 + { 1.2775 + fp = -fp; 1.2776 + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ 1.2777 + --size; 1.2778 + } 1.2779 + 1.2780 + if (fp >= DBL_MIN && fp <= DBL_MAX) 1.2781 + { 1.2782 + int exp_b10; /* A base 10 exponent */ 1.2783 + double base; /* 10^exp_b10 */ 1.2784 + 1.2785 + /* First extract a base 10 exponent of the number, 1.2786 + * the calculation below rounds down when converting 1.2787 + * from base 2 to base 10 (multiply by log10(2) - 1.2788 + * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to 1.2789 + * be increased. Note that the arithmetic shift 1.2790 + * performs a floor() unlike C arithmetic - using a 1.2791 + * C multiply would break the following for negative 1.2792 + * exponents. 1.2793 + */ 1.2794 + (void)frexp(fp, &exp_b10); /* exponent to base 2 */ 1.2795 + 1.2796 + exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ 1.2797 + 1.2798 + /* Avoid underflow here. */ 1.2799 + base = png_pow10(exp_b10); /* May underflow */ 1.2800 + 1.2801 + while (base < DBL_MIN || base < fp) 1.2802 + { 1.2803 + /* And this may overflow. */ 1.2804 + double test = png_pow10(exp_b10+1); 1.2805 + 1.2806 + if (test <= DBL_MAX) 1.2807 + ++exp_b10, base = test; 1.2808 + 1.2809 + else 1.2810 + break; 1.2811 + } 1.2812 + 1.2813 + /* Normalize fp and correct exp_b10, after this fp is in the 1.2814 + * range [.1,1) and exp_b10 is both the exponent and the digit 1.2815 + * *before* which the decimal point should be inserted 1.2816 + * (starting with 0 for the first digit). Note that this 1.2817 + * works even if 10^exp_b10 is out of range because of the 1.2818 + * test on DBL_MAX above. 1.2819 + */ 1.2820 + fp /= base; 1.2821 + while (fp >= 1) fp /= 10, ++exp_b10; 1.2822 + 1.2823 + /* Because of the code above fp may, at this point, be 1.2824 + * less than .1, this is ok because the code below can 1.2825 + * handle the leading zeros this generates, so no attempt 1.2826 + * is made to correct that here. 1.2827 + */ 1.2828 + 1.2829 + { 1.2830 + int czero, clead, cdigits; 1.2831 + char exponent[10]; 1.2832 + 1.2833 + /* Allow up to two leading zeros - this will not lengthen 1.2834 + * the number compared to using E-n. 1.2835 + */ 1.2836 + if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ 1.2837 + { 1.2838 + czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */ 1.2839 + exp_b10 = 0; /* Dot added below before first output. */ 1.2840 + } 1.2841 + else 1.2842 + czero = 0; /* No zeros to add */ 1.2843 + 1.2844 + /* Generate the digit list, stripping trailing zeros and 1.2845 + * inserting a '.' before a digit if the exponent is 0. 1.2846 + */ 1.2847 + clead = czero; /* Count of leading zeros */ 1.2848 + cdigits = 0; /* Count of digits in list. */ 1.2849 + 1.2850 + do 1.2851 + { 1.2852 + double d; 1.2853 + 1.2854 + fp *= 10; 1.2855 + /* Use modf here, not floor and subtract, so that 1.2856 + * the separation is done in one step. At the end 1.2857 + * of the loop don't break the number into parts so 1.2858 + * that the final digit is rounded. 1.2859 + */ 1.2860 + if (cdigits+czero-clead+1 < (int)precision) 1.2861 + fp = modf(fp, &d); 1.2862 + 1.2863 + else 1.2864 + { 1.2865 + d = floor(fp + .5); 1.2866 + 1.2867 + if (d > 9) 1.2868 + { 1.2869 + /* Rounding up to 10, handle that here. */ 1.2870 + if (czero > 0) 1.2871 + { 1.2872 + --czero, d = 1; 1.2873 + if (cdigits == 0) --clead; 1.2874 + } 1.2875 + else 1.2876 + { 1.2877 + while (cdigits > 0 && d > 9) 1.2878 + { 1.2879 + int ch = *--ascii; 1.2880 + 1.2881 + if (exp_b10 != (-1)) 1.2882 + ++exp_b10; 1.2883 + 1.2884 + else if (ch == 46) 1.2885 + { 1.2886 + ch = *--ascii, ++size; 1.2887 + /* Advance exp_b10 to '1', so that the 1.2888 + * decimal point happens after the 1.2889 + * previous digit. 1.2890 + */ 1.2891 + exp_b10 = 1; 1.2892 + } 1.2893 + 1.2894 + --cdigits; 1.2895 + d = ch - 47; /* I.e. 1+(ch-48) */ 1.2896 + } 1.2897 + 1.2898 + /* Did we reach the beginning? If so adjust the 1.2899 + * exponent but take into account the leading 1.2900 + * decimal point. 1.2901 + */ 1.2902 + if (d > 9) /* cdigits == 0 */ 1.2903 + { 1.2904 + if (exp_b10 == (-1)) 1.2905 + { 1.2906 + /* Leading decimal point (plus zeros?), if 1.2907 + * we lose the decimal point here it must 1.2908 + * be reentered below. 1.2909 + */ 1.2910 + int ch = *--ascii; 1.2911 + 1.2912 + if (ch == 46) 1.2913 + ++size, exp_b10 = 1; 1.2914 + 1.2915 + /* Else lost a leading zero, so 'exp_b10' is 1.2916 + * still ok at (-1) 1.2917 + */ 1.2918 + } 1.2919 + else 1.2920 + ++exp_b10; 1.2921 + 1.2922 + /* In all cases we output a '1' */ 1.2923 + d = 1; 1.2924 + } 1.2925 + } 1.2926 + } 1.2927 + fp = 0; /* Guarantees termination below. */ 1.2928 + } 1.2929 + 1.2930 + if (d == 0) 1.2931 + { 1.2932 + ++czero; 1.2933 + if (cdigits == 0) ++clead; 1.2934 + } 1.2935 + else 1.2936 + { 1.2937 + /* Included embedded zeros in the digit count. */ 1.2938 + cdigits += czero - clead; 1.2939 + clead = 0; 1.2940 + 1.2941 + while (czero > 0) 1.2942 + { 1.2943 + /* exp_b10 == (-1) means we just output the decimal 1.2944 + * place - after the DP don't adjust 'exp_b10' any 1.2945 + * more! 1.2946 + */ 1.2947 + if (exp_b10 != (-1)) 1.2948 + { 1.2949 + if (exp_b10 == 0) *ascii++ = 46, --size; 1.2950 + /* PLUS 1: TOTAL 4 */ 1.2951 + --exp_b10; 1.2952 + } 1.2953 + *ascii++ = 48, --czero; 1.2954 + } 1.2955 + 1.2956 + if (exp_b10 != (-1)) 1.2957 + { 1.2958 + if (exp_b10 == 0) *ascii++ = 46, --size; /* counted 1.2959 + above */ 1.2960 + --exp_b10; 1.2961 + } 1.2962 + *ascii++ = (char)(48 + (int)d), ++cdigits; 1.2963 + } 1.2964 + } 1.2965 + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); 1.2966 + 1.2967 + /* The total output count (max) is now 4+precision */ 1.2968 + 1.2969 + /* Check for an exponent, if we don't need one we are 1.2970 + * done and just need to terminate the string. At 1.2971 + * this point exp_b10==(-1) is effectively if flag - it got 1.2972 + * to '-1' because of the decrement after outputing 1.2973 + * the decimal point above (the exponent required is 1.2974 + * *not* -1!) 1.2975 + */ 1.2976 + if (exp_b10 >= (-1) && exp_b10 <= 2) 1.2977 + { 1.2978 + /* The following only happens if we didn't output the 1.2979 + * leading zeros above for negative exponent, so this 1.2980 + * doest add to the digit requirement. Note that the 1.2981 + * two zeros here can only be output if the two leading 1.2982 + * zeros were *not* output, so this doesn't increase 1.2983 + * the output count. 1.2984 + */ 1.2985 + while (--exp_b10 >= 0) *ascii++ = 48; 1.2986 + 1.2987 + *ascii = 0; 1.2988 + 1.2989 + /* Total buffer requirement (including the '\0') is 1.2990 + * 5+precision - see check at the start. 1.2991 + */ 1.2992 + return; 1.2993 + } 1.2994 + 1.2995 + /* Here if an exponent is required, adjust size for 1.2996 + * the digits we output but did not count. The total 1.2997 + * digit output here so far is at most 1+precision - no 1.2998 + * decimal point and no leading or trailing zeros have 1.2999 + * been output. 1.3000 + */ 1.3001 + size -= cdigits; 1.3002 + 1.3003 + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */ 1.3004 + 1.3005 + /* The following use of an unsigned temporary avoids ambiguities in 1.3006 + * the signed arithmetic on exp_b10 and permits GCC at least to do 1.3007 + * better optimization. 1.3008 + */ 1.3009 + { 1.3010 + unsigned int uexp_b10; 1.3011 + 1.3012 + if (exp_b10 < 0) 1.3013 + { 1.3014 + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ 1.3015 + uexp_b10 = -exp_b10; 1.3016 + } 1.3017 + 1.3018 + else 1.3019 + uexp_b10 = exp_b10; 1.3020 + 1.3021 + cdigits = 0; 1.3022 + 1.3023 + while (uexp_b10 > 0) 1.3024 + { 1.3025 + exponent[cdigits++] = (char)(48 + uexp_b10 % 10); 1.3026 + uexp_b10 /= 10; 1.3027 + } 1.3028 + } 1.3029 + 1.3030 + /* Need another size check here for the exponent digits, so 1.3031 + * this need not be considered above. 1.3032 + */ 1.3033 + if ((int)size > cdigits) 1.3034 + { 1.3035 + while (cdigits > 0) *ascii++ = exponent[--cdigits]; 1.3036 + 1.3037 + *ascii = 0; 1.3038 + 1.3039 + return; 1.3040 + } 1.3041 + } 1.3042 + } 1.3043 + else if (!(fp >= DBL_MIN)) 1.3044 + { 1.3045 + *ascii++ = 48; /* '0' */ 1.3046 + *ascii = 0; 1.3047 + return; 1.3048 + } 1.3049 + else 1.3050 + { 1.3051 + *ascii++ = 105; /* 'i' */ 1.3052 + *ascii++ = 110; /* 'n' */ 1.3053 + *ascii++ = 102; /* 'f' */ 1.3054 + *ascii = 0; 1.3055 + return; 1.3056 + } 1.3057 + } 1.3058 + 1.3059 + /* Here on buffer too small. */ 1.3060 + png_error(png_ptr, "ASCII conversion buffer too small"); 1.3061 +} 1.3062 + 1.3063 +# endif /* FLOATING_POINT */ 1.3064 + 1.3065 +# ifdef PNG_FIXED_POINT_SUPPORTED 1.3066 +/* Function to format a fixed point value in ASCII. 1.3067 + */ 1.3068 +void /* PRIVATE */ 1.3069 +png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, 1.3070 + png_size_t size, png_fixed_point fp) 1.3071 +{ 1.3072 + /* Require space for 10 decimal digits, a decimal point, a minus sign and a 1.3073 + * trailing \0, 13 characters: 1.3074 + */ 1.3075 + if (size > 12) 1.3076 + { 1.3077 + png_uint_32 num; 1.3078 + 1.3079 + /* Avoid overflow here on the minimum integer. */ 1.3080 + if (fp < 0) 1.3081 + *ascii++ = 45, --size, num = -fp; 1.3082 + else 1.3083 + num = fp; 1.3084 + 1.3085 + if (num <= 0x80000000) /* else overflowed */ 1.3086 + { 1.3087 + unsigned int ndigits = 0, first = 16 /* flag value */; 1.3088 + char digits[10]; 1.3089 + 1.3090 + while (num) 1.3091 + { 1.3092 + /* Split the low digit off num: */ 1.3093 + unsigned int tmp = num/10; 1.3094 + num -= tmp*10; 1.3095 + digits[ndigits++] = (char)(48 + num); 1.3096 + /* Record the first non-zero digit, note that this is a number 1.3097 + * starting at 1, it's not actually the array index. 1.3098 + */ 1.3099 + if (first == 16 && num > 0) 1.3100 + first = ndigits; 1.3101 + num = tmp; 1.3102 + } 1.3103 + 1.3104 + if (ndigits > 0) 1.3105 + { 1.3106 + while (ndigits > 5) *ascii++ = digits[--ndigits]; 1.3107 + /* The remaining digits are fractional digits, ndigits is '5' or 1.3108 + * smaller at this point. It is certainly not zero. Check for a 1.3109 + * non-zero fractional digit: 1.3110 + */ 1.3111 + if (first <= 5) 1.3112 + { 1.3113 + unsigned int i; 1.3114 + *ascii++ = 46; /* decimal point */ 1.3115 + /* ndigits may be <5 for small numbers, output leading zeros 1.3116 + * then ndigits digits to first: 1.3117 + */ 1.3118 + i = 5; 1.3119 + while (ndigits < i) *ascii++ = 48, --i; 1.3120 + while (ndigits >= first) *ascii++ = digits[--ndigits]; 1.3121 + /* Don't output the trailing zeros! */ 1.3122 + } 1.3123 + } 1.3124 + else 1.3125 + *ascii++ = 48; 1.3126 + 1.3127 + /* And null terminate the string: */ 1.3128 + *ascii = 0; 1.3129 + return; 1.3130 + } 1.3131 + } 1.3132 + 1.3133 + /* Here on buffer too small. */ 1.3134 + png_error(png_ptr, "ASCII conversion buffer too small"); 1.3135 +} 1.3136 +# endif /* FIXED_POINT */ 1.3137 +#endif /* READ_SCAL */ 1.3138 + 1.3139 +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ 1.3140 + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ 1.3141 + (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ 1.3142 + defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 1.3143 + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ 1.3144 + (defined(PNG_sCAL_SUPPORTED) && \ 1.3145 + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) 1.3146 +png_fixed_point 1.3147 +png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) 1.3148 +{ 1.3149 + double r = floor(100000 * fp + .5); 1.3150 + 1.3151 + if (r > 2147483647. || r < -2147483648.) 1.3152 + png_fixed_error(png_ptr, text); 1.3153 + 1.3154 +# ifndef PNG_ERROR_TEXT_SUPPORTED 1.3155 + PNG_UNUSED(text) 1.3156 +# endif 1.3157 + 1.3158 + return (png_fixed_point)r; 1.3159 +} 1.3160 +#endif 1.3161 + 1.3162 +#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ 1.3163 + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) 1.3164 +/* muldiv functions */ 1.3165 +/* This API takes signed arguments and rounds the result to the nearest 1.3166 + * integer (or, for a fixed point number - the standard argument - to 1.3167 + * the nearest .00001). Overflow and divide by zero are signalled in 1.3168 + * the result, a boolean - true on success, false on overflow. 1.3169 + */ 1.3170 +int 1.3171 +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, 1.3172 + png_int_32 divisor) 1.3173 +{ 1.3174 + /* Return a * times / divisor, rounded. */ 1.3175 + if (divisor != 0) 1.3176 + { 1.3177 + if (a == 0 || times == 0) 1.3178 + { 1.3179 + *res = 0; 1.3180 + return 1; 1.3181 + } 1.3182 + else 1.3183 + { 1.3184 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3185 + double r = a; 1.3186 + r *= times; 1.3187 + r /= divisor; 1.3188 + r = floor(r+.5); 1.3189 + 1.3190 + /* A png_fixed_point is a 32-bit integer. */ 1.3191 + if (r <= 2147483647. && r >= -2147483648.) 1.3192 + { 1.3193 + *res = (png_fixed_point)r; 1.3194 + return 1; 1.3195 + } 1.3196 +#else 1.3197 + int negative = 0; 1.3198 + png_uint_32 A, T, D; 1.3199 + png_uint_32 s16, s32, s00; 1.3200 + 1.3201 + if (a < 0) 1.3202 + negative = 1, A = -a; 1.3203 + else 1.3204 + A = a; 1.3205 + 1.3206 + if (times < 0) 1.3207 + negative = !negative, T = -times; 1.3208 + else 1.3209 + T = times; 1.3210 + 1.3211 + if (divisor < 0) 1.3212 + negative = !negative, D = -divisor; 1.3213 + else 1.3214 + D = divisor; 1.3215 + 1.3216 + /* Following can't overflow because the arguments only 1.3217 + * have 31 bits each, however the result may be 32 bits. 1.3218 + */ 1.3219 + s16 = (A >> 16) * (T & 0xffff) + 1.3220 + (A & 0xffff) * (T >> 16); 1.3221 + /* Can't overflow because the a*times bit is only 30 1.3222 + * bits at most. 1.3223 + */ 1.3224 + s32 = (A >> 16) * (T >> 16) + (s16 >> 16); 1.3225 + s00 = (A & 0xffff) * (T & 0xffff); 1.3226 + 1.3227 + s16 = (s16 & 0xffff) << 16; 1.3228 + s00 += s16; 1.3229 + 1.3230 + if (s00 < s16) 1.3231 + ++s32; /* carry */ 1.3232 + 1.3233 + if (s32 < D) /* else overflow */ 1.3234 + { 1.3235 + /* s32.s00 is now the 64-bit product, do a standard 1.3236 + * division, we know that s32 < D, so the maximum 1.3237 + * required shift is 31. 1.3238 + */ 1.3239 + int bitshift = 32; 1.3240 + png_fixed_point result = 0; /* NOTE: signed */ 1.3241 + 1.3242 + while (--bitshift >= 0) 1.3243 + { 1.3244 + png_uint_32 d32, d00; 1.3245 + 1.3246 + if (bitshift > 0) 1.3247 + d32 = D >> (32-bitshift), d00 = D << bitshift; 1.3248 + 1.3249 + else 1.3250 + d32 = 0, d00 = D; 1.3251 + 1.3252 + if (s32 > d32) 1.3253 + { 1.3254 + if (s00 < d00) --s32; /* carry */ 1.3255 + s32 -= d32, s00 -= d00, result += 1<<bitshift; 1.3256 + } 1.3257 + 1.3258 + else 1.3259 + if (s32 == d32 && s00 >= d00) 1.3260 + s32 = 0, s00 -= d00, result += 1<<bitshift; 1.3261 + } 1.3262 + 1.3263 + /* Handle the rounding. */ 1.3264 + if (s00 >= (D >> 1)) 1.3265 + ++result; 1.3266 + 1.3267 + if (negative) 1.3268 + result = -result; 1.3269 + 1.3270 + /* Check for overflow. */ 1.3271 + if ((negative && result <= 0) || (!negative && result >= 0)) 1.3272 + { 1.3273 + *res = result; 1.3274 + return 1; 1.3275 + } 1.3276 + } 1.3277 +#endif 1.3278 + } 1.3279 + } 1.3280 + 1.3281 + return 0; 1.3282 +} 1.3283 +#endif /* READ_GAMMA || INCH_CONVERSIONS */ 1.3284 + 1.3285 +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) 1.3286 +/* The following is for when the caller doesn't much care about the 1.3287 + * result. 1.3288 + */ 1.3289 +png_fixed_point 1.3290 +png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, 1.3291 + png_int_32 divisor) 1.3292 +{ 1.3293 + png_fixed_point result; 1.3294 + 1.3295 + if (png_muldiv(&result, a, times, divisor)) 1.3296 + return result; 1.3297 + 1.3298 + png_warning(png_ptr, "fixed point overflow ignored"); 1.3299 + return 0; 1.3300 +} 1.3301 +#endif 1.3302 + 1.3303 +#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ 1.3304 +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ 1.3305 +png_fixed_point 1.3306 +png_reciprocal(png_fixed_point a) 1.3307 +{ 1.3308 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3309 + double r = floor(1E10/a+.5); 1.3310 + 1.3311 + if (r <= 2147483647. && r >= -2147483648.) 1.3312 + return (png_fixed_point)r; 1.3313 +#else 1.3314 + png_fixed_point res; 1.3315 + 1.3316 + if (png_muldiv(&res, 100000, 100000, a)) 1.3317 + return res; 1.3318 +#endif 1.3319 + 1.3320 + return 0; /* error/overflow */ 1.3321 +} 1.3322 + 1.3323 +/* This is the shared test on whether a gamma value is 'significant' - whether 1.3324 + * it is worth doing gamma correction. 1.3325 + */ 1.3326 +int /* PRIVATE */ 1.3327 +png_gamma_significant(png_fixed_point gamma_val) 1.3328 +{ 1.3329 + return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || 1.3330 + gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; 1.3331 +} 1.3332 +#endif 1.3333 + 1.3334 +#ifdef PNG_READ_GAMMA_SUPPORTED 1.3335 +# ifdef PNG_16BIT_SUPPORTED 1.3336 +/* A local convenience routine. */ 1.3337 +static png_fixed_point 1.3338 +png_product2(png_fixed_point a, png_fixed_point b) 1.3339 +{ 1.3340 + /* The required result is 1/a * 1/b; the following preserves accuracy. */ 1.3341 +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3342 + double r = a * 1E-5; 1.3343 + r *= b; 1.3344 + r = floor(r+.5); 1.3345 + 1.3346 + if (r <= 2147483647. && r >= -2147483648.) 1.3347 + return (png_fixed_point)r; 1.3348 +# else 1.3349 + png_fixed_point res; 1.3350 + 1.3351 + if (png_muldiv(&res, a, b, 100000)) 1.3352 + return res; 1.3353 +# endif 1.3354 + 1.3355 + return 0; /* overflow */ 1.3356 +} 1.3357 +# endif /* 16BIT */ 1.3358 + 1.3359 +/* The inverse of the above. */ 1.3360 +png_fixed_point 1.3361 +png_reciprocal2(png_fixed_point a, png_fixed_point b) 1.3362 +{ 1.3363 + /* The required result is 1/a * 1/b; the following preserves accuracy. */ 1.3364 +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3365 + double r = 1E15/a; 1.3366 + r /= b; 1.3367 + r = floor(r+.5); 1.3368 + 1.3369 + if (r <= 2147483647. && r >= -2147483648.) 1.3370 + return (png_fixed_point)r; 1.3371 +#else 1.3372 + /* This may overflow because the range of png_fixed_point isn't symmetric, 1.3373 + * but this API is only used for the product of file and screen gamma so it 1.3374 + * doesn't matter that the smallest number it can produce is 1/21474, not 1.3375 + * 1/100000 1.3376 + */ 1.3377 + png_fixed_point res = png_product2(a, b); 1.3378 + 1.3379 + if (res != 0) 1.3380 + return png_reciprocal(res); 1.3381 +#endif 1.3382 + 1.3383 + return 0; /* overflow */ 1.3384 +} 1.3385 +#endif /* READ_GAMMA */ 1.3386 + 1.3387 +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ 1.3388 +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3389 +/* Fixed point gamma. 1.3390 + * 1.3391 + * The code to calculate the tables used below can be found in the shell script 1.3392 + * contrib/tools/intgamma.sh 1.3393 + * 1.3394 + * To calculate gamma this code implements fast log() and exp() calls using only 1.3395 + * fixed point arithmetic. This code has sufficient precision for either 8-bit 1.3396 + * or 16-bit sample values. 1.3397 + * 1.3398 + * The tables used here were calculated using simple 'bc' programs, but C double 1.3399 + * precision floating point arithmetic would work fine. 1.3400 + * 1.3401 + * 8-bit log table 1.3402 + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to 1.3403 + * 255, so it's the base 2 logarithm of a normalized 8-bit floating point 1.3404 + * mantissa. The numbers are 32-bit fractions. 1.3405 + */ 1.3406 +static const png_uint_32 1.3407 +png_8bit_l2[128] = 1.3408 +{ 1.3409 + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, 1.3410 + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, 1.3411 + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, 1.3412 + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, 1.3413 + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, 1.3414 + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, 1.3415 + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, 1.3416 + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, 1.3417 + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, 1.3418 + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, 1.3419 + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, 1.3420 + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, 1.3421 + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, 1.3422 + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, 1.3423 + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, 1.3424 + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, 1.3425 + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, 1.3426 + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, 1.3427 + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, 1.3428 + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, 1.3429 + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, 1.3430 + 24347096U, 0U 1.3431 + 1.3432 +#if 0 1.3433 + /* The following are the values for 16-bit tables - these work fine for the 1.3434 + * 8-bit conversions but produce very slightly larger errors in the 16-bit 1.3435 + * log (about 1.2 as opposed to 0.7 absolute error in the final value). To 1.3436 + * use these all the shifts below must be adjusted appropriately. 1.3437 + */ 1.3438 + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, 1.3439 + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, 1.3440 + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, 1.3441 + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, 1.3442 + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, 1.3443 + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, 1.3444 + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, 1.3445 + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, 1.3446 + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, 1.3447 + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, 1.3448 + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, 1.3449 + 1119, 744, 372 1.3450 +#endif 1.3451 +}; 1.3452 + 1.3453 +static png_int_32 1.3454 +png_log8bit(unsigned int x) 1.3455 +{ 1.3456 + unsigned int lg2 = 0; 1.3457 + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, 1.3458 + * because the log is actually negate that means adding 1. The final 1.3459 + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 1.3460 + * input), return -1 for the overflow (log 0) case, - so the result is 1.3461 + * always at most 19 bits. 1.3462 + */ 1.3463 + if ((x &= 0xff) == 0) 1.3464 + return -1; 1.3465 + 1.3466 + if ((x & 0xf0) == 0) 1.3467 + lg2 = 4, x <<= 4; 1.3468 + 1.3469 + if ((x & 0xc0) == 0) 1.3470 + lg2 += 2, x <<= 2; 1.3471 + 1.3472 + if ((x & 0x80) == 0) 1.3473 + lg2 += 1, x <<= 1; 1.3474 + 1.3475 + /* result is at most 19 bits, so this cast is safe: */ 1.3476 + return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); 1.3477 +} 1.3478 + 1.3479 +/* The above gives exact (to 16 binary places) log2 values for 8-bit images, 1.3480 + * for 16-bit images we use the most significant 8 bits of the 16-bit value to 1.3481 + * get an approximation then multiply the approximation by a correction factor 1.3482 + * determined by the remaining up to 8 bits. This requires an additional step 1.3483 + * in the 16-bit case. 1.3484 + * 1.3485 + * We want log2(value/65535), we have log2(v'/255), where: 1.3486 + * 1.3487 + * value = v' * 256 + v'' 1.3488 + * = v' * f 1.3489 + * 1.3490 + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 1.3491 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less 1.3492 + * than 258. The final factor also needs to correct for the fact that our 8-bit 1.3493 + * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. 1.3494 + * 1.3495 + * This gives a final formula using a calculated value 'x' which is value/v' and 1.3496 + * scaling by 65536 to match the above table: 1.3497 + * 1.3498 + * log2(x/257) * 65536 1.3499 + * 1.3500 + * Since these numbers are so close to '1' we can use simple linear 1.3501 + * interpolation between the two end values 256/257 (result -368.61) and 258/257 1.3502 + * (result 367.179). The values used below are scaled by a further 64 to give 1.3503 + * 16-bit precision in the interpolation: 1.3504 + * 1.3505 + * Start (256): -23591 1.3506 + * Zero (257): 0 1.3507 + * End (258): 23499 1.3508 + */ 1.3509 +static png_int_32 1.3510 +png_log16bit(png_uint_32 x) 1.3511 +{ 1.3512 + unsigned int lg2 = 0; 1.3513 + 1.3514 + /* As above, but now the input has 16 bits. */ 1.3515 + if ((x &= 0xffff) == 0) 1.3516 + return -1; 1.3517 + 1.3518 + if ((x & 0xff00) == 0) 1.3519 + lg2 = 8, x <<= 8; 1.3520 + 1.3521 + if ((x & 0xf000) == 0) 1.3522 + lg2 += 4, x <<= 4; 1.3523 + 1.3524 + if ((x & 0xc000) == 0) 1.3525 + lg2 += 2, x <<= 2; 1.3526 + 1.3527 + if ((x & 0x8000) == 0) 1.3528 + lg2 += 1, x <<= 1; 1.3529 + 1.3530 + /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional 1.3531 + * value. 1.3532 + */ 1.3533 + lg2 <<= 28; 1.3534 + lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; 1.3535 + 1.3536 + /* Now we need to interpolate the factor, this requires a division by the top 1.3537 + * 8 bits. Do this with maximum precision. 1.3538 + */ 1.3539 + x = ((x << 16) + (x >> 9)) / (x >> 8); 1.3540 + 1.3541 + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, 1.3542 + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly 1.3543 + * 16 bits to interpolate to get the low bits of the result. Round the 1.3544 + * answer. Note that the end point values are scaled by 64 to retain overall 1.3545 + * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust 1.3546 + * the overall scaling by 6-12. Round at every step. 1.3547 + */ 1.3548 + x -= 1U << 24; 1.3549 + 1.3550 + if (x <= 65536U) /* <= '257' */ 1.3551 + lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); 1.3552 + 1.3553 + else 1.3554 + lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); 1.3555 + 1.3556 + /* Safe, because the result can't have more than 20 bits: */ 1.3557 + return (png_int_32)((lg2 + 2048) >> 12); 1.3558 +} 1.3559 + 1.3560 +/* The 'exp()' case must invert the above, taking a 20-bit fixed point 1.3561 + * logarithmic value and returning a 16 or 8-bit number as appropriate. In 1.3562 + * each case only the low 16 bits are relevant - the fraction - since the 1.3563 + * integer bits (the top 4) simply determine a shift. 1.3564 + * 1.3565 + * The worst case is the 16-bit distinction between 65535 and 65534, this 1.3566 + * requires perhaps spurious accuracty in the decoding of the logarithm to 1.3567 + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance 1.3568 + * of getting this accuracy in practice. 1.3569 + * 1.3570 + * To deal with this the following exp() function works out the exponent of the 1.3571 + * frational part of the logarithm by using an accurate 32-bit value from the 1.3572 + * top four fractional bits then multiplying in the remaining bits. 1.3573 + */ 1.3574 +static const png_uint_32 1.3575 +png_32bit_exp[16] = 1.3576 +{ 1.3577 + /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ 1.3578 + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, 1.3579 + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, 1.3580 + 2553802834U, 2445529972U, 2341847524U, 2242560872U 1.3581 +}; 1.3582 + 1.3583 +/* Adjustment table; provided to explain the numbers in the code below. */ 1.3584 +#if 0 1.3585 +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} 1.3586 + 11 44937.64284865548751208448 1.3587 + 10 45180.98734845585101160448 1.3588 + 9 45303.31936980687359311872 1.3589 + 8 45364.65110595323018870784 1.3590 + 7 45395.35850361789624614912 1.3591 + 6 45410.72259715102037508096 1.3592 + 5 45418.40724413220722311168 1.3593 + 4 45422.25021786898173001728 1.3594 + 3 45424.17186732298419044352 1.3595 + 2 45425.13273269940811464704 1.3596 + 1 45425.61317555035558641664 1.3597 + 0 45425.85339951654943850496 1.3598 +#endif 1.3599 + 1.3600 +static png_uint_32 1.3601 +png_exp(png_fixed_point x) 1.3602 +{ 1.3603 + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ 1.3604 + { 1.3605 + /* Obtain a 4-bit approximation */ 1.3606 + png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; 1.3607 + 1.3608 + /* Incorporate the low 12 bits - these decrease the returned value by 1.3609 + * multiplying by a number less than 1 if the bit is set. The multiplier 1.3610 + * is determined by the above table and the shift. Notice that the values 1.3611 + * converge on 45426 and this is used to allow linear interpolation of the 1.3612 + * low bits. 1.3613 + */ 1.3614 + if (x & 0x800) 1.3615 + e -= (((e >> 16) * 44938U) + 16U) >> 5; 1.3616 + 1.3617 + if (x & 0x400) 1.3618 + e -= (((e >> 16) * 45181U) + 32U) >> 6; 1.3619 + 1.3620 + if (x & 0x200) 1.3621 + e -= (((e >> 16) * 45303U) + 64U) >> 7; 1.3622 + 1.3623 + if (x & 0x100) 1.3624 + e -= (((e >> 16) * 45365U) + 128U) >> 8; 1.3625 + 1.3626 + if (x & 0x080) 1.3627 + e -= (((e >> 16) * 45395U) + 256U) >> 9; 1.3628 + 1.3629 + if (x & 0x040) 1.3630 + e -= (((e >> 16) * 45410U) + 512U) >> 10; 1.3631 + 1.3632 + /* And handle the low 6 bits in a single block. */ 1.3633 + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; 1.3634 + 1.3635 + /* Handle the upper bits of x. */ 1.3636 + e >>= x >> 16; 1.3637 + return e; 1.3638 + } 1.3639 + 1.3640 + /* Check for overflow */ 1.3641 + if (x <= 0) 1.3642 + return png_32bit_exp[0]; 1.3643 + 1.3644 + /* Else underflow */ 1.3645 + return 0; 1.3646 +} 1.3647 + 1.3648 +static png_byte 1.3649 +png_exp8bit(png_fixed_point lg2) 1.3650 +{ 1.3651 + /* Get a 32-bit value: */ 1.3652 + png_uint_32 x = png_exp(lg2); 1.3653 + 1.3654 + /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the 1.3655 + * second, rounding, step can't overflow because of the first, subtraction, 1.3656 + * step. 1.3657 + */ 1.3658 + x -= x >> 8; 1.3659 + return (png_byte)((x + 0x7fffffU) >> 24); 1.3660 +} 1.3661 + 1.3662 +#ifdef PNG_16BIT_SUPPORTED 1.3663 +static png_uint_16 1.3664 +png_exp16bit(png_fixed_point lg2) 1.3665 +{ 1.3666 + /* Get a 32-bit value: */ 1.3667 + png_uint_32 x = png_exp(lg2); 1.3668 + 1.3669 + /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ 1.3670 + x -= x >> 16; 1.3671 + return (png_uint_16)((x + 32767U) >> 16); 1.3672 +} 1.3673 +#endif /* 16BIT */ 1.3674 +#endif /* FLOATING_ARITHMETIC */ 1.3675 + 1.3676 +png_byte 1.3677 +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) 1.3678 +{ 1.3679 + if (value > 0 && value < 255) 1.3680 + { 1.3681 +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3682 + double r = floor(255*pow(value/255.,gamma_val*.00001)+.5); 1.3683 + return (png_byte)r; 1.3684 +# else 1.3685 + png_int_32 lg2 = png_log8bit(value); 1.3686 + png_fixed_point res; 1.3687 + 1.3688 + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) 1.3689 + return png_exp8bit(res); 1.3690 + 1.3691 + /* Overflow. */ 1.3692 + value = 0; 1.3693 +# endif 1.3694 + } 1.3695 + 1.3696 + return (png_byte)value; 1.3697 +} 1.3698 + 1.3699 +#ifdef PNG_16BIT_SUPPORTED 1.3700 +png_uint_16 1.3701 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) 1.3702 +{ 1.3703 + if (value > 0 && value < 65535) 1.3704 + { 1.3705 +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3706 + double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5); 1.3707 + return (png_uint_16)r; 1.3708 +# else 1.3709 + png_int_32 lg2 = png_log16bit(value); 1.3710 + png_fixed_point res; 1.3711 + 1.3712 + if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1)) 1.3713 + return png_exp16bit(res); 1.3714 + 1.3715 + /* Overflow. */ 1.3716 + value = 0; 1.3717 +# endif 1.3718 + } 1.3719 + 1.3720 + return (png_uint_16)value; 1.3721 +} 1.3722 +#endif /* 16BIT */ 1.3723 + 1.3724 +/* This does the right thing based on the bit_depth field of the 1.3725 + * png_struct, interpreting values as 8-bit or 16-bit. While the result 1.3726 + * is nominally a 16-bit value if bit depth is 8 then the result is 1.3727 + * 8-bit (as are the arguments.) 1.3728 + */ 1.3729 +png_uint_16 /* PRIVATE */ 1.3730 +png_gamma_correct(png_structrp png_ptr, unsigned int value, 1.3731 + png_fixed_point gamma_val) 1.3732 +{ 1.3733 + if (png_ptr->bit_depth == 8) 1.3734 + return png_gamma_8bit_correct(value, gamma_val); 1.3735 + 1.3736 +#ifdef PNG_16BIT_SUPPORTED 1.3737 + else 1.3738 + return png_gamma_16bit_correct(value, gamma_val); 1.3739 +#else 1.3740 + /* should not reach this */ 1.3741 + return 0; 1.3742 +#endif /* 16BIT */ 1.3743 +} 1.3744 + 1.3745 +#ifdef PNG_16BIT_SUPPORTED 1.3746 +/* Internal function to build a single 16-bit table - the table consists of 1.3747 + * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount 1.3748 + * to shift the input values right (or 16-number_of_signifiant_bits). 1.3749 + * 1.3750 + * The caller is responsible for ensuring that the table gets cleaned up on 1.3751 + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument 1.3752 + * should be somewhere that will be cleaned. 1.3753 + */ 1.3754 +static void 1.3755 +png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, 1.3756 + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) 1.3757 +{ 1.3758 + /* Various values derived from 'shift': */ 1.3759 + PNG_CONST unsigned int num = 1U << (8U - shift); 1.3760 + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; 1.3761 + PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); 1.3762 + unsigned int i; 1.3763 + 1.3764 + png_uint_16pp table = *ptable = 1.3765 + (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); 1.3766 + 1.3767 + for (i = 0; i < num; i++) 1.3768 + { 1.3769 + png_uint_16p sub_table = table[i] = 1.3770 + (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); 1.3771 + 1.3772 + /* The 'threshold' test is repeated here because it can arise for one of 1.3773 + * the 16-bit tables even if the others don't hit it. 1.3774 + */ 1.3775 + if (png_gamma_significant(gamma_val)) 1.3776 + { 1.3777 + /* The old code would overflow at the end and this would cause the 1.3778 + * 'pow' function to return a result >1, resulting in an 1.3779 + * arithmetic error. This code follows the spec exactly; ig is 1.3780 + * the recovered input sample, it always has 8-16 bits. 1.3781 + * 1.3782 + * We want input * 65535/max, rounded, the arithmetic fits in 32 1.3783 + * bits (unsigned) so long as max <= 32767. 1.3784 + */ 1.3785 + unsigned int j; 1.3786 + for (j = 0; j < 256; j++) 1.3787 + { 1.3788 + png_uint_32 ig = (j << (8-shift)) + i; 1.3789 +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED 1.3790 + /* Inline the 'max' scaling operation: */ 1.3791 + double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5); 1.3792 + sub_table[j] = (png_uint_16)d; 1.3793 +# else 1.3794 + if (shift) 1.3795 + ig = (ig * 65535U + max_by_2)/max; 1.3796 + 1.3797 + sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); 1.3798 +# endif 1.3799 + } 1.3800 + } 1.3801 + else 1.3802 + { 1.3803 + /* We must still build a table, but do it the fast way. */ 1.3804 + unsigned int j; 1.3805 + 1.3806 + for (j = 0; j < 256; j++) 1.3807 + { 1.3808 + png_uint_32 ig = (j << (8-shift)) + i; 1.3809 + 1.3810 + if (shift) 1.3811 + ig = (ig * 65535U + max_by_2)/max; 1.3812 + 1.3813 + sub_table[j] = (png_uint_16)ig; 1.3814 + } 1.3815 + } 1.3816 + } 1.3817 +} 1.3818 + 1.3819 +/* NOTE: this function expects the *inverse* of the overall gamma transformation 1.3820 + * required. 1.3821 + */ 1.3822 +static void 1.3823 +png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, 1.3824 + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) 1.3825 +{ 1.3826 + PNG_CONST unsigned int num = 1U << (8U - shift); 1.3827 + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; 1.3828 + unsigned int i; 1.3829 + png_uint_32 last; 1.3830 + 1.3831 + png_uint_16pp table = *ptable = 1.3832 + (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); 1.3833 + 1.3834 + /* 'num' is the number of tables and also the number of low bits of low 1.3835 + * bits of the input 16-bit value used to select a table. Each table is 1.3836 + * itself index by the high 8 bits of the value. 1.3837 + */ 1.3838 + for (i = 0; i < num; i++) 1.3839 + table[i] = (png_uint_16p)png_malloc(png_ptr, 1.3840 + 256 * (sizeof (png_uint_16))); 1.3841 + 1.3842 + /* 'gamma_val' is set to the reciprocal of the value calculated above, so 1.3843 + * pow(out,g) is an *input* value. 'last' is the last input value set. 1.3844 + * 1.3845 + * In the loop 'i' is used to find output values. Since the output is 1.3846 + * 8-bit there are only 256 possible values. The tables are set up to 1.3847 + * select the closest possible output value for each input by finding 1.3848 + * the input value at the boundary between each pair of output values 1.3849 + * and filling the table up to that boundary with the lower output 1.3850 + * value. 1.3851 + * 1.3852 + * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit 1.3853 + * values the code below uses a 16-bit value in i; the values start at 1.3854 + * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last 1.3855 + * entries are filled with 255). Start i at 128 and fill all 'last' 1.3856 + * table entries <= 'max' 1.3857 + */ 1.3858 + last = 0; 1.3859 + for (i = 0; i < 255; ++i) /* 8-bit output value */ 1.3860 + { 1.3861 + /* Find the corresponding maximum input value */ 1.3862 + png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ 1.3863 + 1.3864 + /* Find the boundary value in 16 bits: */ 1.3865 + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); 1.3866 + 1.3867 + /* Adjust (round) to (16-shift) bits: */ 1.3868 + bound = (bound * max + 32768U)/65535U + 1U; 1.3869 + 1.3870 + while (last < bound) 1.3871 + { 1.3872 + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; 1.3873 + last++; 1.3874 + } 1.3875 + } 1.3876 + 1.3877 + /* And fill in the final entries. */ 1.3878 + while (last < (num << 8)) 1.3879 + { 1.3880 + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; 1.3881 + last++; 1.3882 + } 1.3883 +} 1.3884 +#endif /* 16BIT */ 1.3885 + 1.3886 +/* Build a single 8-bit table: same as the 16-bit case but much simpler (and 1.3887 + * typically much faster). Note that libpng currently does no sBIT processing 1.3888 + * (apparently contrary to the spec) so a 256 entry table is always generated. 1.3889 + */ 1.3890 +static void 1.3891 +png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, 1.3892 + PNG_CONST png_fixed_point gamma_val) 1.3893 +{ 1.3894 + unsigned int i; 1.3895 + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); 1.3896 + 1.3897 + if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++) 1.3898 + table[i] = png_gamma_8bit_correct(i, gamma_val); 1.3899 + 1.3900 + else for (i=0; i<256; ++i) 1.3901 + table[i] = (png_byte)i; 1.3902 +} 1.3903 + 1.3904 +/* Used from png_read_destroy and below to release the memory used by the gamma 1.3905 + * tables. 1.3906 + */ 1.3907 +void /* PRIVATE */ 1.3908 +png_destroy_gamma_table(png_structrp png_ptr) 1.3909 +{ 1.3910 + png_free(png_ptr, png_ptr->gamma_table); 1.3911 + png_ptr->gamma_table = NULL; 1.3912 + 1.3913 +#ifdef PNG_16BIT_SUPPORTED 1.3914 + if (png_ptr->gamma_16_table != NULL) 1.3915 + { 1.3916 + int i; 1.3917 + int istop = (1 << (8 - png_ptr->gamma_shift)); 1.3918 + for (i = 0; i < istop; i++) 1.3919 + { 1.3920 + png_free(png_ptr, png_ptr->gamma_16_table[i]); 1.3921 + } 1.3922 + png_free(png_ptr, png_ptr->gamma_16_table); 1.3923 + png_ptr->gamma_16_table = NULL; 1.3924 + } 1.3925 +#endif /* 16BIT */ 1.3926 + 1.3927 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 1.3928 + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 1.3929 + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 1.3930 + png_free(png_ptr, png_ptr->gamma_from_1); 1.3931 + png_ptr->gamma_from_1 = NULL; 1.3932 + png_free(png_ptr, png_ptr->gamma_to_1); 1.3933 + png_ptr->gamma_to_1 = NULL; 1.3934 + 1.3935 +#ifdef PNG_16BIT_SUPPORTED 1.3936 + if (png_ptr->gamma_16_from_1 != NULL) 1.3937 + { 1.3938 + int i; 1.3939 + int istop = (1 << (8 - png_ptr->gamma_shift)); 1.3940 + for (i = 0; i < istop; i++) 1.3941 + { 1.3942 + png_free(png_ptr, png_ptr->gamma_16_from_1[i]); 1.3943 + } 1.3944 + png_free(png_ptr, png_ptr->gamma_16_from_1); 1.3945 + png_ptr->gamma_16_from_1 = NULL; 1.3946 + } 1.3947 + if (png_ptr->gamma_16_to_1 != NULL) 1.3948 + { 1.3949 + int i; 1.3950 + int istop = (1 << (8 - png_ptr->gamma_shift)); 1.3951 + for (i = 0; i < istop; i++) 1.3952 + { 1.3953 + png_free(png_ptr, png_ptr->gamma_16_to_1[i]); 1.3954 + } 1.3955 + png_free(png_ptr, png_ptr->gamma_16_to_1); 1.3956 + png_ptr->gamma_16_to_1 = NULL; 1.3957 + } 1.3958 +#endif /* 16BIT */ 1.3959 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 1.3960 +} 1.3961 + 1.3962 +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit 1.3963 + * tables, we don't make a full table if we are reducing to 8-bit in 1.3964 + * the future. Note also how the gamma_16 tables are segmented so that 1.3965 + * we don't need to allocate > 64K chunks for a full 16-bit table. 1.3966 + */ 1.3967 +void /* PRIVATE */ 1.3968 +png_build_gamma_table(png_structrp png_ptr, int bit_depth) 1.3969 +{ 1.3970 + png_debug(1, "in png_build_gamma_table"); 1.3971 + 1.3972 + /* Remove any existing table; this copes with multiple calls to 1.3973 + * png_read_update_info. The warning is because building the gamma tables 1.3974 + * multiple times is a performance hit - it's harmless but the ability to call 1.3975 + * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible 1.3976 + * to warn if the app introduces such a hit. 1.3977 + */ 1.3978 + if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) 1.3979 + { 1.3980 + png_warning(png_ptr, "gamma table being rebuilt"); 1.3981 + png_destroy_gamma_table(png_ptr); 1.3982 + } 1.3983 + 1.3984 + if (bit_depth <= 8) 1.3985 + { 1.3986 + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, 1.3987 + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, 1.3988 + png_ptr->screen_gamma) : PNG_FP_1); 1.3989 + 1.3990 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 1.3991 + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 1.3992 + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 1.3993 + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) 1.3994 + { 1.3995 + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, 1.3996 + png_reciprocal(png_ptr->colorspace.gamma)); 1.3997 + 1.3998 + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, 1.3999 + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : 1.4000 + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); 1.4001 + } 1.4002 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 1.4003 + } 1.4004 +#ifdef PNG_16BIT_SUPPORTED 1.4005 + else 1.4006 + { 1.4007 + png_byte shift, sig_bit; 1.4008 + 1.4009 + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1.4010 + { 1.4011 + sig_bit = png_ptr->sig_bit.red; 1.4012 + 1.4013 + if (png_ptr->sig_bit.green > sig_bit) 1.4014 + sig_bit = png_ptr->sig_bit.green; 1.4015 + 1.4016 + if (png_ptr->sig_bit.blue > sig_bit) 1.4017 + sig_bit = png_ptr->sig_bit.blue; 1.4018 + } 1.4019 + else 1.4020 + sig_bit = png_ptr->sig_bit.gray; 1.4021 + 1.4022 + /* 16-bit gamma code uses this equation: 1.4023 + * 1.4024 + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] 1.4025 + * 1.4026 + * Where 'iv' is the input color value and 'ov' is the output value - 1.4027 + * pow(iv, gamma). 1.4028 + * 1.4029 + * Thus the gamma table consists of up to 256 256 entry tables. The table 1.4030 + * is selected by the (8-gamma_shift) most significant of the low 8 bits of 1.4031 + * the color value then indexed by the upper 8 bits: 1.4032 + * 1.4033 + * table[low bits][high 8 bits] 1.4034 + * 1.4035 + * So the table 'n' corresponds to all those 'iv' of: 1.4036 + * 1.4037 + * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1> 1.4038 + * 1.4039 + */ 1.4040 + if (sig_bit > 0 && sig_bit < 16U) 1.4041 + shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ 1.4042 + 1.4043 + else 1.4044 + shift = 0; /* keep all 16 bits */ 1.4045 + 1.4046 + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) 1.4047 + { 1.4048 + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively 1.4049 + * the significant bits in the *input* when the output will 1.4050 + * eventually be 8 bits. By default it is 11. 1.4051 + */ 1.4052 + if (shift < (16U - PNG_MAX_GAMMA_8)) 1.4053 + shift = (16U - PNG_MAX_GAMMA_8); 1.4054 + } 1.4055 + 1.4056 + if (shift > 8U) 1.4057 + shift = 8U; /* Guarantees at least one table! */ 1.4058 + 1.4059 + png_ptr->gamma_shift = shift; 1.4060 + 1.4061 + /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now 1.4062 + * PNG_COMPOSE). This effectively smashed the background calculation for 1.4063 + * 16-bit output because the 8-bit table assumes the result will be reduced 1.4064 + * to 8 bits. 1.4065 + */ 1.4066 + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) 1.4067 + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, 1.4068 + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, 1.4069 + png_ptr->screen_gamma) : PNG_FP_1); 1.4070 + 1.4071 + else 1.4072 + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, 1.4073 + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, 1.4074 + png_ptr->screen_gamma) : PNG_FP_1); 1.4075 + 1.4076 +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ 1.4077 + defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ 1.4078 + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) 1.4079 + if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) 1.4080 + { 1.4081 + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, 1.4082 + png_reciprocal(png_ptr->colorspace.gamma)); 1.4083 + 1.4084 + /* Notice that the '16 from 1' table should be full precision, however 1.4085 + * the lookup on this table still uses gamma_shift, so it can't be. 1.4086 + * TODO: fix this. 1.4087 + */ 1.4088 + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, 1.4089 + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : 1.4090 + png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); 1.4091 + } 1.4092 +#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ 1.4093 + } 1.4094 +#endif /* 16BIT */ 1.4095 +} 1.4096 +#endif /* READ_GAMMA */ 1.4097 + 1.4098 +/* HARDWARE OPTION SUPPORT */ 1.4099 +#ifdef PNG_SET_OPTION_SUPPORTED 1.4100 +int PNGAPI 1.4101 +png_set_option(png_structrp png_ptr, int option, int onoff) 1.4102 +{ 1.4103 + if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && 1.4104 + (option & 1) == 0) 1.4105 + { 1.4106 + int mask = 3 << option; 1.4107 + int setting = (2 + (onoff != 0)) << option; 1.4108 + int current = png_ptr->options; 1.4109 + 1.4110 + png_ptr->options = (png_byte)((current & ~mask) | setting); 1.4111 + 1.4112 + return (current & mask) >> option; 1.4113 + } 1.4114 + 1.4115 + return PNG_OPTION_INVALID; 1.4116 +} 1.4117 +#endif 1.4118 + 1.4119 +/* sRGB support */ 1.4120 +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ 1.4121 + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) 1.4122 +/* sRGB conversion tables; these are machine generated with the code in 1.4123 + * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the 1.4124 + * specification (see the article at http://en.wikipedia.org/wiki/SRGB) 1.4125 + * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. 1.4126 + * The sRGB to linear table is exact (to the nearest 16 bit linear fraction). 1.4127 + * The inverse (linear to sRGB) table has accuracies as follows: 1.4128 + * 1.4129 + * For all possible (255*65535+1) input values: 1.4130 + * 1.4131 + * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact 1.4132 + * 1.4133 + * For the input values corresponding to the 65536 16-bit values: 1.4134 + * 1.4135 + * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact 1.4136 + * 1.4137 + * In all cases the inexact readings are off by one. 1.4138 + */ 1.4139 + 1.4140 +#ifdef PNG_SIMPLIFIED_READ_SUPPORTED 1.4141 +/* The convert-to-sRGB table is only currently required for read. */ 1.4142 +const png_uint_16 png_sRGB_table[256] = 1.4143 +{ 1.4144 + 0,20,40,60,80,99,119,139, 1.4145 + 159,179,199,219,241,264,288,313, 1.4146 + 340,367,396,427,458,491,526,562, 1.4147 + 599,637,677,718,761,805,851,898, 1.4148 + 947,997,1048,1101,1156,1212,1270,1330, 1.4149 + 1391,1453,1517,1583,1651,1720,1790,1863, 1.4150 + 1937,2013,2090,2170,2250,2333,2418,2504, 1.4151 + 2592,2681,2773,2866,2961,3058,3157,3258, 1.4152 + 3360,3464,3570,3678,3788,3900,4014,4129, 1.4153 + 4247,4366,4488,4611,4736,4864,4993,5124, 1.4154 + 5257,5392,5530,5669,5810,5953,6099,6246, 1.4155 + 6395,6547,6700,6856,7014,7174,7335,7500, 1.4156 + 7666,7834,8004,8177,8352,8528,8708,8889, 1.4157 + 9072,9258,9445,9635,9828,10022,10219,10417, 1.4158 + 10619,10822,11028,11235,11446,11658,11873,12090, 1.4159 + 12309,12530,12754,12980,13209,13440,13673,13909, 1.4160 + 14146,14387,14629,14874,15122,15371,15623,15878, 1.4161 + 16135,16394,16656,16920,17187,17456,17727,18001, 1.4162 + 18277,18556,18837,19121,19407,19696,19987,20281, 1.4163 + 20577,20876,21177,21481,21787,22096,22407,22721, 1.4164 + 23038,23357,23678,24002,24329,24658,24990,25325, 1.4165 + 25662,26001,26344,26688,27036,27386,27739,28094, 1.4166 + 28452,28813,29176,29542,29911,30282,30656,31033, 1.4167 + 31412,31794,32179,32567,32957,33350,33745,34143, 1.4168 + 34544,34948,35355,35764,36176,36591,37008,37429, 1.4169 + 37852,38278,38706,39138,39572,40009,40449,40891, 1.4170 + 41337,41785,42236,42690,43147,43606,44069,44534, 1.4171 + 45002,45473,45947,46423,46903,47385,47871,48359, 1.4172 + 48850,49344,49841,50341,50844,51349,51858,52369, 1.4173 + 52884,53401,53921,54445,54971,55500,56032,56567, 1.4174 + 57105,57646,58190,58737,59287,59840,60396,60955, 1.4175 + 61517,62082,62650,63221,63795,64372,64952,65535 1.4176 +}; 1.4177 + 1.4178 +#endif /* simplified read only */ 1.4179 + 1.4180 +/* The base/delta tables are required for both read and write (but currently 1.4181 + * only the simplified versions.) 1.4182 + */ 1.4183 +const png_uint_16 png_sRGB_base[512] = 1.4184 +{ 1.4185 + 128,1782,3383,4644,5675,6564,7357,8074, 1.4186 + 8732,9346,9921,10463,10977,11466,11935,12384, 1.4187 + 12816,13233,13634,14024,14402,14769,15125,15473, 1.4188 + 15812,16142,16466,16781,17090,17393,17690,17981, 1.4189 + 18266,18546,18822,19093,19359,19621,19879,20133, 1.4190 + 20383,20630,20873,21113,21349,21583,21813,22041, 1.4191 + 22265,22487,22707,22923,23138,23350,23559,23767, 1.4192 + 23972,24175,24376,24575,24772,24967,25160,25352, 1.4193 + 25542,25730,25916,26101,26284,26465,26645,26823, 1.4194 + 27000,27176,27350,27523,27695,27865,28034,28201, 1.4195 + 28368,28533,28697,28860,29021,29182,29341,29500, 1.4196 + 29657,29813,29969,30123,30276,30429,30580,30730, 1.4197 + 30880,31028,31176,31323,31469,31614,31758,31902, 1.4198 + 32045,32186,32327,32468,32607,32746,32884,33021, 1.4199 + 33158,33294,33429,33564,33697,33831,33963,34095, 1.4200 + 34226,34357,34486,34616,34744,34873,35000,35127, 1.4201 + 35253,35379,35504,35629,35753,35876,35999,36122, 1.4202 + 36244,36365,36486,36606,36726,36845,36964,37083, 1.4203 + 37201,37318,37435,37551,37668,37783,37898,38013, 1.4204 + 38127,38241,38354,38467,38580,38692,38803,38915, 1.4205 + 39026,39136,39246,39356,39465,39574,39682,39790, 1.4206 + 39898,40005,40112,40219,40325,40431,40537,40642, 1.4207 + 40747,40851,40955,41059,41163,41266,41369,41471, 1.4208 + 41573,41675,41777,41878,41979,42079,42179,42279, 1.4209 + 42379,42478,42577,42676,42775,42873,42971,43068, 1.4210 + 43165,43262,43359,43456,43552,43648,43743,43839, 1.4211 + 43934,44028,44123,44217,44311,44405,44499,44592, 1.4212 + 44685,44778,44870,44962,45054,45146,45238,45329, 1.4213 + 45420,45511,45601,45692,45782,45872,45961,46051, 1.4214 + 46140,46229,46318,46406,46494,46583,46670,46758, 1.4215 + 46846,46933,47020,47107,47193,47280,47366,47452, 1.4216 + 47538,47623,47709,47794,47879,47964,48048,48133, 1.4217 + 48217,48301,48385,48468,48552,48635,48718,48801, 1.4218 + 48884,48966,49048,49131,49213,49294,49376,49458, 1.4219 + 49539,49620,49701,49782,49862,49943,50023,50103, 1.4220 + 50183,50263,50342,50422,50501,50580,50659,50738, 1.4221 + 50816,50895,50973,51051,51129,51207,51285,51362, 1.4222 + 51439,51517,51594,51671,51747,51824,51900,51977, 1.4223 + 52053,52129,52205,52280,52356,52432,52507,52582, 1.4224 + 52657,52732,52807,52881,52956,53030,53104,53178, 1.4225 + 53252,53326,53400,53473,53546,53620,53693,53766, 1.4226 + 53839,53911,53984,54056,54129,54201,54273,54345, 1.4227 + 54417,54489,54560,54632,54703,54774,54845,54916, 1.4228 + 54987,55058,55129,55199,55269,55340,55410,55480, 1.4229 + 55550,55620,55689,55759,55828,55898,55967,56036, 1.4230 + 56105,56174,56243,56311,56380,56448,56517,56585, 1.4231 + 56653,56721,56789,56857,56924,56992,57059,57127, 1.4232 + 57194,57261,57328,57395,57462,57529,57595,57662, 1.4233 + 57728,57795,57861,57927,57993,58059,58125,58191, 1.4234 + 58256,58322,58387,58453,58518,58583,58648,58713, 1.4235 + 58778,58843,58908,58972,59037,59101,59165,59230, 1.4236 + 59294,59358,59422,59486,59549,59613,59677,59740, 1.4237 + 59804,59867,59930,59993,60056,60119,60182,60245, 1.4238 + 60308,60370,60433,60495,60558,60620,60682,60744, 1.4239 + 60806,60868,60930,60992,61054,61115,61177,61238, 1.4240 + 61300,61361,61422,61483,61544,61605,61666,61727, 1.4241 + 61788,61848,61909,61969,62030,62090,62150,62211, 1.4242 + 62271,62331,62391,62450,62510,62570,62630,62689, 1.4243 + 62749,62808,62867,62927,62986,63045,63104,63163, 1.4244 + 63222,63281,63340,63398,63457,63515,63574,63632, 1.4245 + 63691,63749,63807,63865,63923,63981,64039,64097, 1.4246 + 64155,64212,64270,64328,64385,64443,64500,64557, 1.4247 + 64614,64672,64729,64786,64843,64900,64956,65013, 1.4248 + 65070,65126,65183,65239,65296,65352,65409,65465 1.4249 +}; 1.4250 + 1.4251 +const png_byte png_sRGB_delta[512] = 1.4252 +{ 1.4253 + 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, 1.4254 + 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, 1.4255 + 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, 1.4256 + 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, 1.4257 + 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, 1.4258 + 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, 1.4259 + 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, 1.4260 + 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, 1.4261 + 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, 1.4262 + 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, 1.4263 + 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, 1.4264 + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, 1.4265 + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 1.4266 + 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, 1.4267 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 1.4268 + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 1.4269 + 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 1.4270 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 1.4271 + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 1.4272 + 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 1.4273 + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 1.4274 + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 1.4275 + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 1.4276 + 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 1.4277 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 1.4278 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 1.4279 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 1.4280 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 1.4281 + 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, 1.4282 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 1.4283 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 1.4284 + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 1.4285 +}; 1.4286 +#endif /* SIMPLIFIED READ/WRITE sRGB support */ 1.4287 + 1.4288 +/* SIMPLIFIED READ/WRITE SUPPORT */ 1.4289 +#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ 1.4290 + defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) 1.4291 +static int 1.4292 +png_image_free_function(png_voidp argument) 1.4293 +{ 1.4294 + png_imagep image = png_voidcast(png_imagep, argument); 1.4295 + png_controlp cp = image->opaque; 1.4296 + png_control c; 1.4297 + 1.4298 + /* Double check that we have a png_ptr - it should be impossible to get here 1.4299 + * without one. 1.4300 + */ 1.4301 + if (cp->png_ptr == NULL) 1.4302 + return 0; 1.4303 + 1.4304 + /* First free any data held in the control structure. */ 1.4305 +# ifdef PNG_STDIO_SUPPORTED 1.4306 + if (cp->owned_file) 1.4307 + { 1.4308 + FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); 1.4309 + cp->owned_file = 0; 1.4310 + 1.4311 + /* Ignore errors here. */ 1.4312 + if (fp != NULL) 1.4313 + { 1.4314 + cp->png_ptr->io_ptr = NULL; 1.4315 + (void)fclose(fp); 1.4316 + } 1.4317 + } 1.4318 +# endif 1.4319 + 1.4320 + /* Copy the control structure so that the original, allocated, version can be 1.4321 + * safely freed. Notice that a png_error here stops the remainder of the 1.4322 + * cleanup, but this is probably fine because that would indicate bad memory 1.4323 + * problems anyway. 1.4324 + */ 1.4325 + c = *cp; 1.4326 + image->opaque = &c; 1.4327 + png_free(c.png_ptr, cp); 1.4328 + 1.4329 + /* Then the structures, calling the correct API. */ 1.4330 + if (c.for_write) 1.4331 + { 1.4332 +# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED 1.4333 + png_destroy_write_struct(&c.png_ptr, &c.info_ptr); 1.4334 +# else 1.4335 + png_error(c.png_ptr, "simplified write not supported"); 1.4336 +# endif 1.4337 + } 1.4338 + else 1.4339 + { 1.4340 +# ifdef PNG_SIMPLIFIED_READ_SUPPORTED 1.4341 + png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); 1.4342 +# else 1.4343 + png_error(c.png_ptr, "simplified read not supported"); 1.4344 +# endif 1.4345 + } 1.4346 + 1.4347 + /* Success. */ 1.4348 + return 1; 1.4349 +} 1.4350 + 1.4351 +void PNGAPI 1.4352 +png_image_free(png_imagep image) 1.4353 +{ 1.4354 + /* Safely call the real function, but only if doing so is safe at this point 1.4355 + * (if not inside an error handling context). Otherwise assume 1.4356 + * png_safe_execute will call this API after the return. 1.4357 + */ 1.4358 + if (image != NULL && image->opaque != NULL && 1.4359 + image->opaque->error_buf == NULL) 1.4360 + { 1.4361 + /* Ignore errors here: */ 1.4362 + (void)png_safe_execute(image, png_image_free_function, image); 1.4363 + image->opaque = NULL; 1.4364 + } 1.4365 +} 1.4366 + 1.4367 +int /* PRIVATE */ 1.4368 +png_image_error(png_imagep image, png_const_charp error_message) 1.4369 +{ 1.4370 + /* Utility to log an error. */ 1.4371 + png_safecat(image->message, (sizeof image->message), 0, error_message); 1.4372 + image->warning_or_error |= PNG_IMAGE_ERROR; 1.4373 + png_image_free(image); 1.4374 + return 0; 1.4375 +} 1.4376 + 1.4377 +#endif /* SIMPLIFIED READ/WRITE */ 1.4378 +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */