1 #if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
\r
2 /* png.c - location for general purpose libpng functions
\r
4 * Last changed in libpng 1.6.2 [April 25, 2013]
\r
5 * Copyright (c) 1998-2013 Glenn Randers-Pehrson
\r
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
\r
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
\r
9 * This code is released under the libpng license.
\r
10 * For conditions of distribution and use, see the disclaimer
\r
11 * and license in png.h
\r
14 #include "pngpriv.h"
\r
16 /* Generate a compiler error if there is an old png.h in the search path. */
\r
17 typedef png_libpng_version_1_6_3 Your_png_h_is_not_version_1_6_3;
\r
19 /* Tells libpng that we have already handled the first "num_bytes" bytes
\r
20 * of the PNG file signature. If the PNG data is embedded into another
\r
21 * stream we can set num_bytes = 8 so that libpng will not attempt to read
\r
22 * or write any of the magic bytes before it starts on the IHDR.
\r
25 #ifdef PNG_READ_SUPPORTED
\r
27 png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
\r
29 png_debug(1, "in png_set_sig_bytes");
\r
31 if (png_ptr == NULL)
\r
35 png_error(png_ptr, "Too many bytes for PNG signature");
\r
37 png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
\r
40 /* Checks whether the supplied bytes match the PNG signature. We allow
\r
41 * checking less than the full 8-byte signature so that those apps that
\r
42 * already read the first few bytes of a file to determine the file type
\r
43 * can simply check the remaining bytes for extra assurance. Returns
\r
44 * an integer less than, equal to, or greater than zero if sig is found,
\r
45 * respectively, to be less than, to match, or be greater than the correct
\r
46 * PNG signature (this is the same behavior as strcmp, memcmp, etc).
\r
49 png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
\r
51 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
\r
53 if (num_to_check > 8)
\r
56 else if (num_to_check < 1)
\r
62 if (start + num_to_check > 8)
\r
63 num_to_check = 8 - start;
\r
65 return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
\r
68 #endif /* PNG_READ_SUPPORTED */
\r
70 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
\r
71 /* Function to allocate memory for zlib */
\r
72 PNG_FUNCTION(voidpf /* PRIVATE */,
\r
73 png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
\r
75 png_alloc_size_t num_bytes = size;
\r
77 if (png_ptr == NULL)
\r
80 if (items >= (~(png_alloc_size_t)0)/size)
\r
82 png_warning (png_voidcast(png_structrp, png_ptr),
\r
83 "Potential overflow in png_zalloc()");
\r
88 return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
\r
91 /* Function to free memory for zlib */
\r
93 png_zfree(voidpf png_ptr, voidpf ptr)
\r
95 png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
\r
98 /* Reset the CRC variable to 32 bits of 1's. Care must be taken
\r
99 * in case CRC is > 32 bits to leave the top bits 0.
\r
102 png_reset_crc(png_structrp png_ptr)
\r
104 /* The cast is safe because the crc is a 32 bit value. */
\r
105 png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
\r
108 /* Calculate the CRC over a section of data. We can only pass as
\r
109 * much data to this routine as the largest single buffer size. We
\r
110 * also check that this data will actually be used before going to the
\r
111 * trouble of calculating it.
\r
114 png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
\r
118 if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
\r
120 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
\r
121 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
\r
125 else /* critical */
\r
127 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
\r
131 /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
\r
132 * systems it is a 64 bit value. crc32, however, returns 32 bits so the
\r
133 * following cast is safe. 'uInt' may be no more than 16 bits, so it is
\r
134 * necessary to perform a loop here.
\r
136 if (need_crc && length > 0)
\r
138 uLong crc = png_ptr->crc; /* Should never issue a warning */
\r
142 uInt safe_length = (uInt)length;
\r
143 if (safe_length == 0)
\r
144 safe_length = (uInt)-1; /* evil, but safe */
\r
146 crc = crc32(crc, ptr, safe_length);
\r
148 /* The following should never issue compiler warnings; if they do the
\r
149 * target system has characteristics that will probably violate other
\r
150 * assumptions within the libpng code.
\r
152 ptr += safe_length;
\r
153 length -= safe_length;
\r
155 while (length > 0);
\r
157 /* And the following is always safe because the crc is only 32 bits. */
\r
158 png_ptr->crc = (png_uint_32)crc;
\r
162 /* Check a user supplied version number, called from both read and write
\r
163 * functions that create a png_struct.
\r
166 png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
\r
174 if (user_png_ver[i] != png_libpng_ver[i])
\r
175 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
\r
176 } while (png_libpng_ver[i++]);
\r
180 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
\r
182 if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
\r
184 /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
\r
185 * we must recompile any applications that use any older library version.
\r
186 * For versions after libpng 1.0, we will be compatible, so we need
\r
187 * only check the first and third digits (note that when we reach version
\r
188 * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]).
\r
190 if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
\r
191 (user_png_ver[0] == '1' && (user_png_ver[2] != png_libpng_ver[2] ||
\r
192 user_png_ver[3] != png_libpng_ver[3])) ||
\r
193 (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
\r
195 #ifdef PNG_WARNINGS_SUPPORTED
\r
199 pos = png_safecat(m, (sizeof m), pos,
\r
200 "Application built with libpng-");
\r
201 pos = png_safecat(m, (sizeof m), pos, user_png_ver);
\r
202 pos = png_safecat(m, (sizeof m), pos, " but running with ");
\r
203 pos = png_safecat(m, (sizeof m), pos, png_libpng_ver);
\r
205 png_warning(png_ptr, m);
\r
208 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
\r
209 png_ptr->flags = 0;
\r
216 /* Success return. */
\r
220 /* Generic function to create a png_struct for either read or write - this
\r
221 * contains the common initialization.
\r
223 PNG_FUNCTION(png_structp /* PRIVATE */,
\r
224 png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
\r
225 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
\r
226 png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
\r
228 png_struct create_struct;
\r
229 # ifdef PNG_SETJMP_SUPPORTED
\r
230 jmp_buf create_jmp_buf;
\r
233 /* This temporary stack-allocated structure is used to provide a place to
\r
234 * build enough context to allow the user provided memory allocator (if any)
\r
237 memset(&create_struct, 0, (sizeof create_struct));
\r
239 /* Added at libpng-1.2.6 */
\r
240 # ifdef PNG_USER_LIMITS_SUPPORTED
\r
241 create_struct.user_width_max = PNG_USER_WIDTH_MAX;
\r
242 create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
\r
244 # ifdef PNG_USER_CHUNK_CACHE_MAX
\r
245 /* Added at libpng-1.2.43 and 1.4.0 */
\r
246 create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
\r
249 # ifdef PNG_USER_CHUNK_MALLOC_MAX
\r
250 /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
\r
251 * in png_struct regardless.
\r
253 create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
\r
257 /* The following two API calls simply set fields in png_struct, so it is safe
\r
258 * to do them now even though error handling is not yet set up.
\r
260 # ifdef PNG_USER_MEM_SUPPORTED
\r
261 png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
\r
264 /* (*error_fn) can return control to the caller after the error_ptr is set,
\r
265 * this will result in a memory leak unless the error_fn does something
\r
266 * extremely sophisticated. The design lacks merit but is implicit in the
\r
269 png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
\r
271 # ifdef PNG_SETJMP_SUPPORTED
\r
272 if (!setjmp(create_jmp_buf))
\r
274 /* Temporarily fake out the longjmp information until we have
\r
275 * successfully completed this function. This only works if we have
\r
276 * setjmp() support compiled in, but it is safe - this stuff should
\r
279 create_struct.jmp_buf_ptr = &create_jmp_buf;
\r
280 create_struct.jmp_buf_size = 0; /*stack allocation*/
\r
281 create_struct.longjmp_fn = longjmp;
\r
285 /* Call the general version checker (shared with read and write code):
\r
287 if (png_user_version_check(&create_struct, user_png_ver))
\r
289 png_structrp png_ptr = png_voidcast(png_structrp,
\r
290 png_malloc_warn(&create_struct, (sizeof *png_ptr)));
\r
292 if (png_ptr != NULL)
\r
294 /* png_ptr->zstream holds a back-pointer to the png_struct, so
\r
295 * this can only be done now:
\r
297 create_struct.zstream.zalloc = png_zalloc;
\r
298 create_struct.zstream.zfree = png_zfree;
\r
299 create_struct.zstream.opaque = png_ptr;
\r
301 # ifdef PNG_SETJMP_SUPPORTED
\r
302 /* Eliminate the local error handling: */
\r
303 create_struct.jmp_buf_ptr = NULL;
\r
304 create_struct.jmp_buf_size = 0;
\r
305 create_struct.longjmp_fn = 0;
\r
308 *png_ptr = create_struct;
\r
310 /* This is the successful return point */
\r
316 /* A longjmp because of a bug in the application storage allocator or a
\r
317 * simple failure to allocate the png_struct.
\r
322 /* Allocate the memory for an info_struct for the application. */
\r
323 PNG_FUNCTION(png_infop,PNGAPI
\r
324 png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
\r
326 png_inforp info_ptr;
\r
328 png_debug(1, "in png_create_info_struct");
\r
330 if (png_ptr == NULL)
\r
333 /* Use the internal API that does not (or at least should not) error out, so
\r
334 * that this call always returns ok. The application typically sets up the
\r
335 * error handling *after* creating the info_struct because this is the way it
\r
336 * has always been done in 'example.c'.
\r
338 info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
\r
339 (sizeof *info_ptr)));
\r
341 if (info_ptr != NULL)
\r
342 memset(info_ptr, 0, (sizeof *info_ptr));
\r
347 /* This function frees the memory associated with a single info struct.
\r
348 * Normally, one would use either png_destroy_read_struct() or
\r
349 * png_destroy_write_struct() to free an info struct, but this may be
\r
350 * useful for some applications. From libpng 1.6.0 this function is also used
\r
351 * internally to implement the png_info release part of the 'struct' destroy
\r
352 * APIs. This ensures that all possible approaches free the same data (all of
\r
356 png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
\r
358 png_inforp info_ptr = NULL;
\r
360 png_debug(1, "in png_destroy_info_struct");
\r
362 if (png_ptr == NULL)
\r
365 if (info_ptr_ptr != NULL)
\r
366 info_ptr = *info_ptr_ptr;
\r
368 if (info_ptr != NULL)
\r
370 /* Do this first in case of an error below; if the app implements its own
\r
371 * memory management this can lead to png_free calling png_error, which
\r
372 * will abort this routine and return control to the app error handler.
\r
373 * An infinite loop may result if it then tries to free the same info
\r
376 *info_ptr_ptr = NULL;
\r
378 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
\r
379 memset(info_ptr, 0, (sizeof *info_ptr));
\r
380 png_free(png_ptr, info_ptr);
\r
384 /* Initialize the info structure. This is now an internal function (0.89)
\r
385 * and applications using it are urged to use png_create_info_struct()
\r
386 * instead. Use deprecated in 1.6.0, internal use removed (used internally it
\r
387 * is just a memset).
\r
389 * NOTE: it is almost inconceivable that this API is used because it bypasses
\r
390 * the user-memory mechanism and the user error handling/warning mechanisms in
\r
391 * those cases where it does anything other than a memset.
\r
393 PNG_FUNCTION(void,PNGAPI
\r
394 png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
\r
397 png_inforp info_ptr = *ptr_ptr;
\r
399 png_debug(1, "in png_info_init_3");
\r
401 if (info_ptr == NULL)
\r
404 if ((sizeof (png_info)) > png_info_struct_size)
\r
407 /* The following line is why this API should not be used: */
\r
409 info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
\r
410 (sizeof *info_ptr)));
\r
411 *ptr_ptr = info_ptr;
\r
414 /* Set everything to 0 */
\r
415 memset(info_ptr, 0, (sizeof *info_ptr));
\r
418 /* The following API is not called internally */
\r
420 png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
\r
421 int freer, png_uint_32 mask)
\r
423 png_debug(1, "in png_data_freer");
\r
425 if (png_ptr == NULL || info_ptr == NULL)
\r
428 if (freer == PNG_DESTROY_WILL_FREE_DATA)
\r
429 info_ptr->free_me |= mask;
\r
431 else if (freer == PNG_USER_WILL_FREE_DATA)
\r
432 info_ptr->free_me &= ~mask;
\r
435 png_error(png_ptr, "Unknown freer parameter in png_data_freer");
\r
439 png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
\r
442 png_debug(1, "in png_free_data");
\r
444 if (png_ptr == NULL || info_ptr == NULL)
\r
447 #ifdef PNG_TEXT_SUPPORTED
\r
448 /* Free text item num or (if num == -1) all text items */
\r
449 if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
\r
453 if (info_ptr->text && info_ptr->text[num].key)
\r
455 png_free(png_ptr, info_ptr->text[num].key);
\r
456 info_ptr->text[num].key = NULL;
\r
463 for (i = 0; i < info_ptr->num_text; i++)
\r
464 png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
\r
465 png_free(png_ptr, info_ptr->text);
\r
466 info_ptr->text = NULL;
\r
467 info_ptr->num_text=0;
\r
472 #ifdef PNG_tRNS_SUPPORTED
\r
473 /* Free any tRNS entry */
\r
474 if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
\r
476 png_free(png_ptr, info_ptr->trans_alpha);
\r
477 info_ptr->trans_alpha = NULL;
\r
478 info_ptr->valid &= ~PNG_INFO_tRNS;
\r
482 #ifdef PNG_sCAL_SUPPORTED
\r
483 /* Free any sCAL entry */
\r
484 if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
\r
486 png_free(png_ptr, info_ptr->scal_s_width);
\r
487 png_free(png_ptr, info_ptr->scal_s_height);
\r
488 info_ptr->scal_s_width = NULL;
\r
489 info_ptr->scal_s_height = NULL;
\r
490 info_ptr->valid &= ~PNG_INFO_sCAL;
\r
494 #ifdef PNG_pCAL_SUPPORTED
\r
495 /* Free any pCAL entry */
\r
496 if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
\r
498 png_free(png_ptr, info_ptr->pcal_purpose);
\r
499 png_free(png_ptr, info_ptr->pcal_units);
\r
500 info_ptr->pcal_purpose = NULL;
\r
501 info_ptr->pcal_units = NULL;
\r
502 if (info_ptr->pcal_params != NULL)
\r
505 for (i = 0; i < info_ptr->pcal_nparams; i++)
\r
507 png_free(png_ptr, info_ptr->pcal_params[i]);
\r
508 info_ptr->pcal_params[i] = NULL;
\r
510 png_free(png_ptr, info_ptr->pcal_params);
\r
511 info_ptr->pcal_params = NULL;
\r
513 info_ptr->valid &= ~PNG_INFO_pCAL;
\r
517 #ifdef PNG_iCCP_SUPPORTED
\r
518 /* Free any profile entry */
\r
519 if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
\r
521 png_free(png_ptr, info_ptr->iccp_name);
\r
522 png_free(png_ptr, info_ptr->iccp_profile);
\r
523 info_ptr->iccp_name = NULL;
\r
524 info_ptr->iccp_profile = NULL;
\r
525 info_ptr->valid &= ~PNG_INFO_iCCP;
\r
529 #ifdef PNG_sPLT_SUPPORTED
\r
530 /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
\r
531 if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
\r
535 if (info_ptr->splt_palettes)
\r
537 png_free(png_ptr, info_ptr->splt_palettes[num].name);
\r
538 png_free(png_ptr, info_ptr->splt_palettes[num].entries);
\r
539 info_ptr->splt_palettes[num].name = NULL;
\r
540 info_ptr->splt_palettes[num].entries = NULL;
\r
546 if (info_ptr->splt_palettes_num)
\r
549 for (i = 0; i < info_ptr->splt_palettes_num; i++)
\r
550 png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)i);
\r
552 png_free(png_ptr, info_ptr->splt_palettes);
\r
553 info_ptr->splt_palettes = NULL;
\r
554 info_ptr->splt_palettes_num = 0;
\r
556 info_ptr->valid &= ~PNG_INFO_sPLT;
\r
561 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
\r
562 if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
\r
566 if (info_ptr->unknown_chunks)
\r
568 png_free(png_ptr, info_ptr->unknown_chunks[num].data);
\r
569 info_ptr->unknown_chunks[num].data = NULL;
\r
577 if (info_ptr->unknown_chunks_num)
\r
579 for (i = 0; i < info_ptr->unknown_chunks_num; i++)
\r
580 png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, (int)i);
\r
582 png_free(png_ptr, info_ptr->unknown_chunks);
\r
583 info_ptr->unknown_chunks = NULL;
\r
584 info_ptr->unknown_chunks_num = 0;
\r
590 #ifdef PNG_hIST_SUPPORTED
\r
591 /* Free any hIST entry */
\r
592 if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
\r
594 png_free(png_ptr, info_ptr->hist);
\r
595 info_ptr->hist = NULL;
\r
596 info_ptr->valid &= ~PNG_INFO_hIST;
\r
600 /* Free any PLTE entry that was internally allocated */
\r
601 if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
\r
603 png_free(png_ptr, info_ptr->palette);
\r
604 info_ptr->palette = NULL;
\r
605 info_ptr->valid &= ~PNG_INFO_PLTE;
\r
606 info_ptr->num_palette = 0;
\r
609 #ifdef PNG_INFO_IMAGE_SUPPORTED
\r
610 /* Free any image bits attached to the info structure */
\r
611 if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
\r
613 if (info_ptr->row_pointers)
\r
616 for (row = 0; row < info_ptr->height; row++)
\r
618 png_free(png_ptr, info_ptr->row_pointers[row]);
\r
619 info_ptr->row_pointers[row] = NULL;
\r
621 png_free(png_ptr, info_ptr->row_pointers);
\r
622 info_ptr->row_pointers = NULL;
\r
624 info_ptr->valid &= ~PNG_INFO_IDAT;
\r
629 mask &= ~PNG_FREE_MUL;
\r
631 info_ptr->free_me &= ~mask;
\r
633 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
\r
635 /* This function returns a pointer to the io_ptr associated with the user
\r
636 * functions. The application should free any memory associated with this
\r
637 * pointer before png_write_destroy() or png_read_destroy() are called.
\r
640 png_get_io_ptr(png_const_structrp png_ptr)
\r
642 if (png_ptr == NULL)
\r
645 return (png_ptr->io_ptr);
\r
648 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
\r
649 # ifdef PNG_STDIO_SUPPORTED
\r
650 /* Initialize the default input/output functions for the PNG file. If you
\r
651 * use your own read or write routines, you can call either png_set_read_fn()
\r
652 * or png_set_write_fn() instead of png_init_io(). If you have defined
\r
653 * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
\r
654 * function of your own because "FILE *" isn't necessarily available.
\r
657 png_init_io(png_structrp png_ptr, png_FILE_p fp)
\r
659 png_debug(1, "in png_init_io");
\r
661 if (png_ptr == NULL)
\r
664 png_ptr->io_ptr = (png_voidp)fp;
\r
668 #ifdef PNG_SAVE_INT_32_SUPPORTED
\r
669 /* The png_save_int_32 function assumes integers are stored in two's
\r
670 * complement format. If this isn't the case, then this routine needs to
\r
671 * be modified to write data in two's complement format. Note that,
\r
672 * the following works correctly even if png_int_32 has more than 32 bits
\r
673 * (compare the more complex code required on read for sign extension.)
\r
676 png_save_int_32(png_bytep buf, png_int_32 i)
\r
678 buf[0] = (png_byte)((i >> 24) & 0xff);
\r
679 buf[1] = (png_byte)((i >> 16) & 0xff);
\r
680 buf[2] = (png_byte)((i >> 8) & 0xff);
\r
681 buf[3] = (png_byte)(i & 0xff);
\r
685 # ifdef PNG_TIME_RFC1123_SUPPORTED
\r
686 /* Convert the supplied time into an RFC 1123 string suitable for use in
\r
687 * a "Creation Time" or other text-based time string.
\r
690 png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
\r
692 static PNG_CONST char short_months[12][4] =
\r
693 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
\r
694 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
\r
699 if (ptime->year > 9999 /* RFC1123 limitation */ ||
\r
700 ptime->month == 0 || ptime->month > 12 ||
\r
701 ptime->day == 0 || ptime->day > 31 ||
\r
702 ptime->hour > 23 || ptime->minute > 59 ||
\r
703 ptime->second > 60)
\r
708 char number_buf[5]; /* enough for a four-digit year */
\r
710 # define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
\r
711 # define APPEND_NUMBER(format, value)\
\r
712 APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
\r
713 # define APPEND(ch) if (pos < 28) out[pos++] = (ch)
\r
715 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
\r
717 APPEND_STRING(short_months[(ptime->month - 1)]);
\r
719 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
\r
721 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
\r
723 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
\r
725 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
\r
726 APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
\r
729 # undef APPEND_NUMBER
\r
730 # undef APPEND_STRING
\r
736 # if PNG_LIBPNG_VER < 10700
\r
737 /* To do: remove the following from libpng-1.7 */
\r
738 /* Original API that uses a private buffer in png_struct.
\r
739 * Deprecated because it causes png_struct to carry a spurious temporary
\r
740 * buffer (png_struct::time_buffer), better to have the caller pass this in.
\r
742 png_const_charp PNGAPI
\r
743 png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
\r
745 if (png_ptr != NULL)
\r
747 /* The only failure above if png_ptr != NULL is from an invalid ptime */
\r
748 if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime))
\r
749 png_warning(png_ptr, "Ignoring invalid time value");
\r
752 return png_ptr->time_buffer;
\r
758 # endif /* PNG_TIME_RFC1123_SUPPORTED */
\r
760 #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
\r
762 png_const_charp PNGAPI
\r
763 png_get_copyright(png_const_structrp png_ptr)
\r
765 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
\r
766 #ifdef PNG_STRING_COPYRIGHT
\r
767 return PNG_STRING_COPYRIGHT
\r
770 return PNG_STRING_NEWLINE \
\r
771 "libpng version 1.6.3 - July 18, 2013" PNG_STRING_NEWLINE \
\r
772 "Copyright (c) 1998-2013 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
\r
773 "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
\r
774 "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
\r
775 PNG_STRING_NEWLINE;
\r
777 return "libpng version 1.6.3 - July 18, 2013\
\r
778 Copyright (c) 1998-2013 Glenn Randers-Pehrson\
\r
779 Copyright (c) 1996-1997 Andreas Dilger\
\r
780 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
\r
785 /* The following return the library version as a short string in the
\r
786 * format 1.0.0 through 99.99.99zz. To get the version of *.h files
\r
787 * used with your application, print out PNG_LIBPNG_VER_STRING, which
\r
788 * is defined in png.h.
\r
789 * Note: now there is no difference between png_get_libpng_ver() and
\r
790 * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
\r
791 * it is guaranteed that png.c uses the correct version of png.h.
\r
793 png_const_charp PNGAPI
\r
794 png_get_libpng_ver(png_const_structrp png_ptr)
\r
796 /* Version of *.c files used when building libpng */
\r
797 return png_get_header_ver(png_ptr);
\r
800 png_const_charp PNGAPI
\r
801 png_get_header_ver(png_const_structrp png_ptr)
\r
803 /* Version of *.h files used when building libpng */
\r
804 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
\r
805 return PNG_LIBPNG_VER_STRING;
\r
808 png_const_charp PNGAPI
\r
809 png_get_header_version(png_const_structrp png_ptr)
\r
811 /* Returns longer string containing both version and date */
\r
812 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
\r
814 return PNG_HEADER_VERSION_STRING
\r
815 # ifndef PNG_READ_SUPPORTED
\r
816 " (NO READ SUPPORT)"
\r
818 PNG_STRING_NEWLINE;
\r
820 return PNG_HEADER_VERSION_STRING;
\r
824 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
\r
826 png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
\r
828 /* Check chunk_name and return "keep" value if it's on the list, else 0 */
\r
829 png_const_bytep p, p_end;
\r
831 if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
\r
832 return PNG_HANDLE_CHUNK_AS_DEFAULT;
\r
834 p_end = png_ptr->chunk_list;
\r
835 p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
\r
837 /* The code is the fifth byte after each four byte string. Historically this
\r
838 * code was always searched from the end of the list, this is no longer
\r
839 * necessary because the 'set' routine handles duplicate entries correcty.
\r
841 do /* num_chunk_list > 0, so at least one */
\r
845 if (!memcmp(chunk_name, p, 4))
\r
850 /* This means that known chunks should be processed and unknown chunks should
\r
851 * be handled according to the value of png_ptr->unknown_default; this can be
\r
852 * confusing because, as a result, there are two levels of defaulting for
\r
855 return PNG_HANDLE_CHUNK_AS_DEFAULT;
\r
858 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
\r
860 png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
\r
862 png_byte chunk_string[5];
\r
864 PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
\r
865 return png_handle_as_unknown(png_ptr, chunk_string);
\r
867 #endif /* READ_UNKNOWN_CHUNKS */
\r
868 #endif /* SET_UNKNOWN_CHUNKS */
\r
870 #ifdef PNG_READ_SUPPORTED
\r
871 /* This function, added to libpng-1.0.6g, is untested. */
\r
873 png_reset_zstream(png_structrp png_ptr)
\r
875 if (png_ptr == NULL)
\r
876 return Z_STREAM_ERROR;
\r
878 /* WARNING: this resets the window bits to the maximum! */
\r
879 return (inflateReset(&png_ptr->zstream));
\r
881 #endif /* PNG_READ_SUPPORTED */
\r
883 /* This function was added to libpng-1.0.7 */
\r
885 png_access_version_number(void)
\r
887 /* Version of *.c files used when building libpng */
\r
888 return((png_uint_32)PNG_LIBPNG_VER);
\r
893 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
\r
894 /* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
\r
895 * If it doesn't 'ret' is used to set it to something appropriate, even in cases
\r
896 * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
\r
899 png_zstream_error(png_structrp png_ptr, int ret)
\r
901 /* Translate 'ret' into an appropriate error string, priority is given to the
\r
902 * one in zstream if set. This always returns a string, even in cases like
\r
903 * Z_OK or Z_STREAM_END where the error code is a success code.
\r
905 if (png_ptr->zstream.msg == NULL) switch (ret)
\r
909 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
\r
914 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
\r
918 /* This means the deflate stream did not have a dictionary; this
\r
919 * indicates a bogus PNG.
\r
921 png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
\r
925 /* gz APIs only: should not happen */
\r
926 png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
\r
929 case Z_STREAM_ERROR:
\r
930 /* internal libpng error */
\r
931 png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
\r
935 png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
\r
939 png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
\r
943 /* End of input or output; not a problem if the caller is doing
\r
944 * incremental read or write.
\r
946 png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
\r
949 case Z_VERSION_ERROR:
\r
950 png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
\r
953 case PNG_UNEXPECTED_ZLIB_RETURN:
\r
954 /* Compile errors here mean that zlib now uses the value co-opted in
\r
955 * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
\r
956 * and change pngpriv.h. Note that this message is "... return",
\r
957 * whereas the default/Z_OK one is "... return code".
\r
959 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
\r
964 /* png_convert_size: a PNGAPI but no longer in png.h, so deleted
\r
968 /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
\r
969 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
\r
971 png_colorspace_check_gamma(png_const_structrp png_ptr,
\r
972 png_colorspacerp colorspace, png_fixed_point gAMA, int from)
\r
973 /* This is called to check a new gamma value against an existing one. The
\r
974 * routine returns false if the new gamma value should not be written.
\r
976 * 'from' says where the new gamma value comes from:
\r
978 * 0: the new gamma value is the libpng estimate for an ICC profile
\r
979 * 1: the new gamma value comes from a gAMA chunk
\r
980 * 2: the new gamma value comes from an sRGB chunk
\r
983 png_fixed_point gtest;
\r
985 if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
\r
986 (!png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) ||
\r
987 png_gamma_significant(gtest)))
\r
989 /* Either this is an sRGB image, in which case the calculated gamma
\r
990 * approximation should match, or this is an image with a profile and the
\r
991 * value libpng calculates for the gamma of the profile does not match the
\r
992 * value recorded in the file. The former, sRGB, case is an error, the
\r
993 * latter is just a warning.
\r
995 if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
\r
997 png_chunk_report(png_ptr, "gamma value does not match sRGB",
\r
999 /* Do not overwrite an sRGB value */
\r
1003 else /* sRGB tag not involved */
\r
1005 png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
\r
1006 PNG_CHUNK_WARNING);
\r
1014 void /* PRIVATE */
\r
1015 png_colorspace_set_gamma(png_const_structrp png_ptr,
\r
1016 png_colorspacerp colorspace, png_fixed_point gAMA)
\r
1018 /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
\r
1019 * occur. Since the fixed point representation is assymetrical it is
\r
1020 * possible for 1/gamma to overflow the limit of 21474 and this means the
\r
1021 * gamma value must be at least 5/100000 and hence at most 20000.0. For
\r
1022 * safety the limits here are a little narrower. The values are 0.00016 to
\r
1023 * 6250.0, which are truly ridiculous gamma values (and will produce
\r
1024 * displays that are all black or all white.)
\r
1026 * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
\r
1027 * handling code, which only required the value to be >0.
\r
1029 png_const_charp errmsg;
\r
1031 if (gAMA < 16 || gAMA > 625000000)
\r
1032 errmsg = "gamma value out of range";
\r
1034 # ifdef PNG_READ_gAMA_SUPPORTED
\r
1035 /* Allow the application to set the gamma value more than once */
\r
1036 else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
\r
1037 (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
\r
1038 errmsg = "duplicate";
\r
1041 /* Do nothing if the colorspace is already invalid */
\r
1042 else if (colorspace->flags & PNG_COLORSPACE_INVALID)
\r
1047 if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/))
\r
1049 /* Store this gamma value. */
\r
1050 colorspace->gamma = gAMA;
\r
1051 colorspace->flags |=
\r
1052 (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
\r
1055 /* At present if the check_gamma test fails the gamma of the colorspace is
\r
1056 * not updated however the colorspace is not invalidated. This
\r
1057 * corresponds to the case where the existing gamma comes from an sRGB
\r
1058 * chunk or profile. An error message has already been output.
\r
1063 /* Error exit - errmsg has been set. */
\r
1064 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1065 png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
\r
1068 void /* PRIVATE */
\r
1069 png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
\r
1071 if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
\r
1073 /* Everything is invalid */
\r
1074 info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
\r
1077 # ifdef PNG_COLORSPACE_SUPPORTED
\r
1078 /* Clean up the iCCP profile now if it won't be used. */
\r
1079 png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
\r
1081 PNG_UNUSED(png_ptr)
\r
1087 # ifdef PNG_COLORSPACE_SUPPORTED
\r
1088 /* Leave the INFO_iCCP flag set if the pngset.c code has already set
\r
1089 * it; this allows a PNG to contain a profile which matches sRGB and
\r
1090 * yet still have that profile retrievable by the application.
\r
1092 if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB)
\r
1093 info_ptr->valid |= PNG_INFO_sRGB;
\r
1096 info_ptr->valid &= ~PNG_INFO_sRGB;
\r
1098 if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)
\r
1099 info_ptr->valid |= PNG_INFO_cHRM;
\r
1102 info_ptr->valid &= ~PNG_INFO_cHRM;
\r
1105 if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA)
\r
1106 info_ptr->valid |= PNG_INFO_gAMA;
\r
1109 info_ptr->valid &= ~PNG_INFO_gAMA;
\r
1113 #ifdef PNG_READ_SUPPORTED
\r
1114 void /* PRIVATE */
\r
1115 png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
\r
1117 if (info_ptr == NULL) /* reduce code size; check here not in the caller */
\r
1120 info_ptr->colorspace = png_ptr->colorspace;
\r
1121 png_colorspace_sync_info(png_ptr, info_ptr);
\r
1126 #ifdef PNG_COLORSPACE_SUPPORTED
\r
1127 /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
\r
1128 * cHRM, as opposed to using chromaticities. These internal APIs return
\r
1129 * non-zero on a parameter error. The X, Y and Z values are required to be
\r
1130 * positive and less than 1.0.
\r
1133 png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
\r
1135 png_int_32 d, dwhite, whiteX, whiteY;
\r
1137 d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
\r
1138 if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1;
\r
1139 if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1;
\r
1141 whiteX = XYZ->red_X;
\r
1142 whiteY = XYZ->red_Y;
\r
1144 d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
\r
1145 if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1;
\r
1146 if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1;
\r
1148 whiteX += XYZ->green_X;
\r
1149 whiteY += XYZ->green_Y;
\r
1151 d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
\r
1152 if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1;
\r
1153 if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1;
\r
1155 whiteX += XYZ->blue_X;
\r
1156 whiteY += XYZ->blue_Y;
\r
1158 /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
\r
1161 if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
\r
1162 if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
\r
1168 png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
\r
1170 png_fixed_point red_inverse, green_inverse, blue_scale;
\r
1171 png_fixed_point left, right, denominator;
\r
1173 /* Check xy and, implicitly, z. Note that wide gamut color spaces typically
\r
1174 * have end points with 0 tristimulus values (these are impossible end
\r
1175 * points, but they are used to cover the possible colors.)
\r
1177 if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
\r
1178 if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
\r
1179 if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
\r
1180 if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
\r
1181 if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
\r
1182 if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
\r
1183 if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
\r
1184 if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
\r
1186 /* The reverse calculation is more difficult because the original tristimulus
\r
1187 * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
\r
1188 * derived values were recorded in the cHRM chunk;
\r
1189 * (red,green,blue,white)x(x,y). This loses one degree of freedom and
\r
1190 * therefore an arbitrary ninth value has to be introduced to undo the
\r
1191 * original transformations.
\r
1193 * Think of the original end-points as points in (X,Y,Z) space. The
\r
1194 * chromaticity values (c) have the property:
\r
1200 * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
\r
1201 * three chromaticity values (x,y,z) for each end-point obey the
\r
1206 * This describes the plane in (X,Y,Z) space that intersects each axis at the
\r
1207 * value 1.0; call this the chromaticity plane. Thus the chromaticity
\r
1208 * calculation has scaled each end-point so that it is on the x+y+z=1 plane
\r
1209 * and chromaticity is the intersection of the vector from the origin to the
\r
1210 * (X,Y,Z) value with the chromaticity plane.
\r
1212 * To fully invert the chromaticity calculation we would need the three
\r
1213 * end-point scale factors, (red-scale, green-scale, blue-scale), but these
\r
1214 * were not recorded. Instead we calculated the reference white (X,Y,Z) and
\r
1215 * recorded the chromaticity of this. The reference white (X,Y,Z) would have
\r
1216 * given all three of the scale factors since:
\r
1218 * color-C = color-c * color-scale
\r
1219 * white-C = red-C + green-C + blue-C
\r
1220 * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
\r
1222 * But cHRM records only white-x and white-y, so we have lost the white scale
\r
1225 * white-C = white-c*white-scale
\r
1227 * To handle this the inverse transformation makes an arbitrary assumption
\r
1228 * about white-scale:
\r
1230 * Assume: white-Y = 1.0
\r
1231 * Hence: white-scale = 1/white-y
\r
1232 * Or: red-Y + green-Y + blue-Y = 1.0
\r
1234 * Notice the last statement of the assumption gives an equation in three of
\r
1235 * the nine values we want to calculate. 8 more equations come from the
\r
1236 * above routine as summarised at the top above (the chromaticity
\r
1239 * Given: color-x = color-X / (color-X + color-Y + color-Z)
\r
1240 * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
\r
1242 * This is 9 simultaneous equations in the 9 variables "color-C" and can be
\r
1243 * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
\r
1244 * determinants, however this is not as bad as it seems because only 28 of
\r
1245 * the total of 90 terms in the various matrices are non-zero. Nevertheless
\r
1246 * Cramer's rule is notoriously numerically unstable because the determinant
\r
1247 * calculation involves the difference of large, but similar, numbers. It is
\r
1248 * difficult to be sure that the calculation is stable for real world values
\r
1249 * and it is certain that it becomes unstable where the end points are close
\r
1252 * So this code uses the perhaps slightly less optimal but more
\r
1253 * understandable and totally obvious approach of calculating color-scale.
\r
1255 * This algorithm depends on the precision in white-scale and that is
\r
1256 * (1/white-y), so we can immediately see that as white-y approaches 0 the
\r
1257 * accuracy inherent in the cHRM chunk drops off substantially.
\r
1259 * libpng arithmetic: a simple invertion of the above equations
\r
1260 * ------------------------------------------------------------
\r
1262 * white_scale = 1/white-y
\r
1263 * white-X = white-x * white-scale
\r
1265 * white-Z = (1 - white-x - white-y) * white_scale
\r
1267 * white-C = red-C + green-C + blue-C
\r
1268 * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
\r
1270 * This gives us three equations in (red-scale,green-scale,blue-scale) where
\r
1271 * all the coefficients are now known:
\r
1273 * red-x*red-scale + green-x*green-scale + blue-x*blue-scale
\r
1274 * = white-x/white-y
\r
1275 * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
\r
1276 * red-z*red-scale + green-z*green-scale + blue-z*blue-scale
\r
1277 * = (1 - white-x - white-y)/white-y
\r
1279 * In the last equation color-z is (1 - color-x - color-y) so we can add all
\r
1280 * three equations together to get an alternative third:
\r
1282 * red-scale + green-scale + blue-scale = 1/white-y = white-scale
\r
1284 * So now we have a Cramer's rule solution where the determinants are just
\r
1285 * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
\r
1286 * multiplication of three coefficients so we can't guarantee to avoid
\r
1287 * overflow in the libpng fixed point representation. Using Cramer's rule in
\r
1288 * floating point is probably a good choice here, but it's not an option for
\r
1289 * fixed point. Instead proceed to simplify the first two equations by
\r
1290 * eliminating what is likely to be the largest value, blue-scale:
\r
1292 * blue-scale = white-scale - red-scale - green-scale
\r
1296 * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
\r
1297 * (white-x - blue-x)*white-scale
\r
1299 * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
\r
1300 * 1 - blue-y*white-scale
\r
1302 * And now we can trivially solve for (red-scale,green-scale):
\r
1305 * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
\r
1306 * -----------------------------------------------------------
\r
1307 * green-x - blue-x
\r
1310 * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
\r
1311 * ---------------------------------------------------------
\r
1317 * ( (green-x - blue-x) * (white-y - blue-y) -
\r
1318 * (green-y - blue-y) * (white-x - blue-x) ) / white-y
\r
1319 * -------------------------------------------------------------------------
\r
1320 * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
\r
1323 * ( (red-y - blue-y) * (white-x - blue-x) -
\r
1324 * (red-x - blue-x) * (white-y - blue-y) ) / white-y
\r
1325 * -------------------------------------------------------------------------
\r
1326 * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
\r
1329 * The input values have 5 decimal digits of accuracy. The values are all in
\r
1330 * the range 0 < value < 1, so simple products are in the same range but may
\r
1331 * need up to 10 decimal digits to preserve the original precision and avoid
\r
1332 * underflow. Because we are using a 32-bit signed representation we cannot
\r
1333 * match this; the best is a little over 9 decimal digits, less than 10.
\r
1335 * The approach used here is to preserve the maximum precision within the
\r
1336 * signed representation. Because the red-scale calculation above uses the
\r
1337 * difference between two products of values that must be in the range -1..+1
\r
1338 * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
\r
1339 * factor is irrelevant in the calculation because it is applied to both
\r
1340 * numerator and denominator.
\r
1342 * Note that the values of the differences of the products of the
\r
1343 * chromaticities in the above equations tend to be small, for example for
\r
1344 * the sRGB chromaticities they are:
\r
1346 * red numerator: -0.04751
\r
1347 * green numerator: -0.08788
\r
1348 * denominator: -0.2241 (without white-y multiplication)
\r
1350 * The resultant Y coefficients from the chromaticities of some widely used
\r
1351 * color space definitions are (to 15 decimal places):
\r
1354 * 0.212639005871510 0.715168678767756 0.072192315360734
\r
1356 * 0.288071128229293 0.711843217810102 0.000085653960605
\r
1358 * 0.297344975250536 0.627363566255466 0.075291458493998
\r
1359 * Adobe Wide Gamut RGB
\r
1360 * 0.258728243040113 0.724682314948566 0.016589442011321
\r
1362 /* By the argument, above overflow should be impossible here. The return
\r
1363 * value of 2 indicates an internal error to the caller.
\r
1365 if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7))
\r
1367 if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7))
\r
1369 denominator = left - right;
\r
1371 /* Now find the red numerator. */
\r
1372 if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7))
\r
1374 if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7))
\r
1377 /* Overflow is possible here and it indicates an extreme set of PNG cHRM
\r
1378 * chunk values. This calculation actually returns the reciprocal of the
\r
1379 * scale value because this allows us to delay the multiplication of white-y
\r
1380 * into the denominator, which tends to produce a small number.
\r
1382 if (!png_muldiv(&red_inverse, xy->whitey, denominator, left-right) ||
\r
1383 red_inverse <= xy->whitey /* r+g+b scales = white scale */)
\r
1386 /* Similarly for green_inverse: */
\r
1387 if (!png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7))
\r
1389 if (!png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7))
\r
1391 if (!png_muldiv(&green_inverse, xy->whitey, denominator, left-right) ||
\r
1392 green_inverse <= xy->whitey)
\r
1395 /* And the blue scale, the checks above guarantee this can't overflow but it
\r
1396 * can still produce 0 for extreme cHRM values.
\r
1398 blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
\r
1399 png_reciprocal(green_inverse);
\r
1400 if (blue_scale <= 0) return 1;
\r
1403 /* And fill in the png_XYZ: */
\r
1404 if (!png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1;
\r
1405 if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1;
\r
1406 if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
\r
1410 if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse))
\r
1412 if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse))
\r
1414 if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
\r
1418 if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1;
\r
1419 if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1;
\r
1420 if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
\r
1424 return 0; /*success*/
\r
1428 png_XYZ_normalize(png_XYZ *XYZ)
\r
1432 if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
\r
1433 XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
\r
1434 XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
\r
1437 /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
\r
1438 * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
\r
1439 * relying on addition of two positive values producing a negative one is not
\r
1443 if (0x7fffffff - Y < XYZ->green_X) return 1;
\r
1444 Y += XYZ->green_Y;
\r
1445 if (0x7fffffff - Y < XYZ->blue_X) return 1;
\r
1448 if (Y != PNG_FP_1)
\r
1450 if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1;
\r
1451 if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1;
\r
1452 if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1;
\r
1454 if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1;
\r
1455 if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1;
\r
1456 if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1;
\r
1458 if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1;
\r
1459 if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1;
\r
1460 if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1;
\r
1467 png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
\r
1469 /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
\r
1470 return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
\r
1471 PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
\r
1472 PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
\r
1473 PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
\r
1474 PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
\r
1475 PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
\r
1476 PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
\r
1477 PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta));
\r
1480 /* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
\r
1481 * chunk chromaticities. Earlier checks used to simply look for the overflow
\r
1482 * condition (where the determinant of the matrix to solve for XYZ ends up zero
\r
1483 * because the chromaticity values are not all distinct.) Despite this it is
\r
1484 * theoretically possible to produce chromaticities that are apparently valid
\r
1485 * but that rapidly degrade to invalid, potentially crashing, sets because of
\r
1486 * arithmetic inaccuracies when calculations are performed on them. The new
\r
1487 * check is to round-trip xy -> XYZ -> xy and then check that the result is
\r
1488 * within a small percentage of the original.
\r
1491 png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
\r
1496 /* As a side-effect this routine also returns the XYZ endpoints. */
\r
1497 result = png_XYZ_from_xy(XYZ, xy);
\r
1498 if (result) return result;
\r
1500 result = png_xy_from_XYZ(&xy_test, XYZ);
\r
1501 if (result) return result;
\r
1503 if (png_colorspace_endpoints_match(xy, &xy_test,
\r
1504 5/*actually, the math is pretty accurate*/))
\r
1507 /* Too much slip */
\r
1511 /* This is the check going the other way. The XYZ is modified to normalize it
\r
1512 * (another side-effect) and the xy chromaticities are returned.
\r
1515 png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
\r
1520 result = png_XYZ_normalize(XYZ);
\r
1521 if (result) return result;
\r
1523 result = png_xy_from_XYZ(xy, XYZ);
\r
1524 if (result) return result;
\r
1527 return png_colorspace_check_xy(&XYZtemp, xy);
\r
1530 /* Used to check for an endpoint match against sRGB */
\r
1531 static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
\r
1534 /* red */ 64000, 33000,
\r
1535 /* green */ 30000, 60000,
\r
1536 /* blue */ 15000, 6000,
\r
1537 /* white */ 31270, 32900
\r
1541 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
\r
1542 png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
\r
1545 if (colorspace->flags & PNG_COLORSPACE_INVALID)
\r
1548 /* The consistency check is performed on the chromaticities; this factors out
\r
1549 * variations because of the normalization (or not) of the end point Y
\r
1552 if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
\r
1554 /* The end points must be reasonably close to any we already have. The
\r
1555 * following allows an error of up to +/-.001
\r
1557 if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100))
\r
1559 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1560 png_benign_error(png_ptr, "inconsistent chromaticities");
\r
1561 return 0; /* failed */
\r
1564 /* Only overwrite with preferred values */
\r
1566 return 1; /* ok, but no change */
\r
1569 colorspace->end_points_xy = *xy;
\r
1570 colorspace->end_points_XYZ = *XYZ;
\r
1571 colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
\r
1573 /* The end points are normally quoted to two decimal digits, so allow +/-0.01
\r
1576 if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000))
\r
1577 colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
\r
1580 colorspace->flags &= PNG_COLORSPACE_CANCEL(
\r
1581 PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
\r
1583 return 2; /* ok and changed */
\r
1587 png_colorspace_set_chromaticities(png_const_structrp png_ptr,
\r
1588 png_colorspacerp colorspace, const png_xy *xy, int preferred)
\r
1590 /* We must check the end points to ensure they are reasonable - in the past
\r
1591 * color management systems have crashed as a result of getting bogus
\r
1592 * colorant values, while this isn't the fault of libpng it is the
\r
1593 * responsibility of libpng because PNG carries the bomb and libpng is in a
\r
1594 * position to protect against it.
\r
1598 switch (png_colorspace_check_xy(&XYZ, xy))
\r
1600 case 0: /* success */
\r
1601 return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
\r
1605 /* We can't invert the chromaticities so we can't produce value XYZ
\r
1606 * values. Likely as not a color management system will fail too.
\r
1608 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1609 png_benign_error(png_ptr, "invalid chromaticities");
\r
1613 /* libpng is broken; this should be a warning but if it happens we
\r
1614 * want error reports so for the moment it is an error.
\r
1616 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1617 png_error(png_ptr, "internal error checking chromaticities");
\r
1621 return 0; /* failed */
\r
1625 png_colorspace_set_endpoints(png_const_structrp png_ptr,
\r
1626 png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
\r
1628 png_XYZ XYZ = *XYZ_in;
\r
1631 switch (png_colorspace_check_XYZ(&xy, &XYZ))
\r
1634 return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
\r
1638 /* End points are invalid. */
\r
1639 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1640 png_benign_error(png_ptr, "invalid end points");
\r
1644 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1645 png_error(png_ptr, "internal error checking chromaticities");
\r
1649 return 0; /* failed */
\r
1652 #if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
\r
1653 /* Error message generation */
\r
1655 png_icc_tag_char(png_uint_32 byte)
\r
1658 if (byte >= 32 && byte <= 126)
\r
1659 return (char)byte;
\r
1665 png_icc_tag_name(char *name, png_uint_32 tag)
\r
1668 name[1] = png_icc_tag_char(tag >> 24);
\r
1669 name[2] = png_icc_tag_char(tag >> 16);
\r
1670 name[3] = png_icc_tag_char(tag >> 8);
\r
1671 name[4] = png_icc_tag_char(tag );
\r
1676 is_ICC_signature_char(png_alloc_size_t it)
\r
1678 return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
\r
1679 (it >= 97 && it <= 122);
\r
1682 static int is_ICC_signature(png_alloc_size_t it)
\r
1684 return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
\r
1685 is_ICC_signature_char((it >> 16) & 0xff) &&
\r
1686 is_ICC_signature_char((it >> 8) & 0xff) &&
\r
1687 is_ICC_signature_char(it & 0xff);
\r
1691 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
1692 png_const_charp name, png_alloc_size_t value, png_const_charp reason)
\r
1695 char message[196]; /* see below for calculation */
\r
1697 if (colorspace != NULL)
\r
1698 colorspace->flags |= PNG_COLORSPACE_INVALID;
\r
1700 pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
\r
1701 pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
\r
1702 pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
\r
1703 if (is_ICC_signature(value))
\r
1705 /* So 'value' is at most 4 bytes and the following cast is safe */
\r
1706 png_icc_tag_name(message+pos, (png_uint_32)value);
\r
1707 pos += 6; /* total +8; less than the else clause */
\r
1708 message[pos++] = ':';
\r
1709 message[pos++] = ' ';
\r
1711 # ifdef PNG_WARNINGS_SUPPORTED
\r
1714 char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
\r
1716 pos = png_safecat(message, (sizeof message), pos,
\r
1717 png_format_number(number, number+(sizeof number),
\r
1718 PNG_NUMBER_FORMAT_x, value));
\r
1719 pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
\r
1722 /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
\r
1723 pos = png_safecat(message, (sizeof message), pos, reason);
\r
1725 /* This is recoverable, but make it unconditionally an app_error on write to
\r
1726 * avoid writing invalid ICC profiles into PNG files. (I.e. we handle them
\r
1727 * on read, with a warning, but on write unless the app turns off
\r
1728 * application errors the PNG won't be written.)
\r
1730 png_chunk_report(png_ptr, message,
\r
1731 (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
\r
1735 #endif /* sRGB || iCCP */
\r
1737 #ifdef PNG_sRGB_SUPPORTED
\r
1739 png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
1742 /* sRGB sets known gamma, end points and (from the chunk) intent. */
\r
1743 /* IMPORTANT: these are not necessarily the values found in an ICC profile
\r
1744 * because ICC profiles store values adapted to a D50 environment; it is
\r
1745 * expected that the ICC profile mediaWhitePointTag will be D50, see the
\r
1746 * checks and code elsewhere to understand this better.
\r
1748 * These XYZ values, which are accurate to 5dp, produce rgb to gray
\r
1749 * coefficients of (6968,23435,2366), which are reduced (because they add up
\r
1750 * to 32769 not 32768) to (6968,23434,2366). These are the values that
\r
1751 * libpng has traditionally used (and are the best values given the 15bit
\r
1752 * algorithm used by the rgb to gray code.)
\r
1754 static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
\r
1757 /* red */ 41239, 21264, 1933,
\r
1758 /* green */ 35758, 71517, 11919,
\r
1759 /* blue */ 18048, 7219, 95053
\r
1762 /* Do nothing if the colorspace is already invalidated. */
\r
1763 if (colorspace->flags & PNG_COLORSPACE_INVALID)
\r
1766 /* Check the intent, then check for existing settings. It is valid for the
\r
1767 * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
\r
1768 * be consistent with the correct values. If, however, this function is
\r
1769 * called below because an iCCP chunk matches sRGB then it is quite
\r
1770 * conceivable that an older app recorded incorrect gAMA and cHRM because of
\r
1771 * an incorrect calculation based on the values in the profile - this does
\r
1772 * *not* invalidate the profile (though it still produces an error, which can
\r
1775 if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
\r
1776 return png_icc_profile_error(png_ptr, colorspace, "sRGB",
\r
1777 (unsigned)intent, "invalid sRGB rendering intent");
\r
1779 if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
\r
1780 colorspace->rendering_intent != intent)
\r
1781 return png_icc_profile_error(png_ptr, colorspace, "sRGB",
\r
1782 (unsigned)intent, "inconsistent rendering intents");
\r
1784 if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
\r
1786 png_benign_error(png_ptr, "duplicate sRGB information ignored");
\r
1790 /* If the standard sRGB cHRM chunk does not match the one from the PNG file
\r
1791 * warn but overwrite the value with the correct one.
\r
1793 if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
\r
1794 !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
\r
1796 png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
\r
1799 /* This check is just done for the error reporting - the routine always
\r
1800 * returns true when the 'from' argument corresponds to sRGB (2).
\r
1802 (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
\r
1805 /* intent: bugs in GCC force 'int' to be used as the parameter type. */
\r
1806 colorspace->rendering_intent = (png_uint_16)intent;
\r
1807 colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
\r
1810 colorspace->end_points_xy = sRGB_xy;
\r
1811 colorspace->end_points_XYZ = sRGB_XYZ;
\r
1812 colorspace->flags |=
\r
1813 (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
\r
1816 colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
\r
1817 colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
\r
1819 /* Finally record that we have an sRGB profile */
\r
1820 colorspace->flags |=
\r
1821 (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
\r
1823 return 1; /* set */
\r
1827 #ifdef PNG_iCCP_SUPPORTED
\r
1828 /* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
\r
1829 * is XYZ(0.9642,1.0,0.8249), which scales to:
\r
1831 * (63189.8112, 65536, 54060.6464)
\r
1833 static const png_byte D50_nCIEXYZ[12] =
\r
1834 { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
\r
1837 png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
1838 png_const_charp name, png_uint_32 profile_length)
\r
1840 if (profile_length < 132)
\r
1841 return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
\r
1844 if (profile_length & 3)
\r
1845 return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
\r
1846 "invalid length");
\r
1852 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
1853 png_const_charp name, png_uint_32 profile_length,
\r
1854 png_const_bytep profile/* first 132 bytes only */, int color_type)
\r
1858 /* Length check; this cannot be ignored in this code because profile_length
\r
1859 * is used later to check the tag table, so even if the profile seems over
\r
1860 * long profile_length from the caller must be correct. The caller can fix
\r
1861 * this up on read or write by just passing in the profile header length.
\r
1863 temp = png_get_uint_32(profile);
\r
1864 if (temp != profile_length)
\r
1865 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1866 "length does not match profile");
\r
1868 temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
\r
1869 if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
\r
1870 profile_length < 132+12*temp) /* truncated tag table */
\r
1871 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1872 "tag count too large");
\r
1874 /* The 'intent' must be valid or we can't store it, ICC limits the intent to
\r
1877 temp = png_get_uint_32(profile+64);
\r
1878 if (temp >= 0xffff) /* The ICC limit */
\r
1879 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1880 "invalid rendering intent");
\r
1882 /* This is just a warning because the profile may be valid in future
\r
1885 if (temp >= PNG_sRGB_INTENT_LAST)
\r
1886 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
\r
1887 "intent outside defined range");
\r
1889 /* At this point the tag table can't be checked because it hasn't necessarily
\r
1890 * been loaded; however, various header fields can be checked. These checks
\r
1891 * are for values permitted by the PNG spec in an ICC profile; the PNG spec
\r
1892 * restricts the profiles that can be passed in an iCCP chunk (they must be
\r
1893 * appropriate to processing PNG data!)
\r
1896 /* Data checks (could be skipped). These checks must be independent of the
\r
1897 * version number; however, the version number doesn't accomodate changes in
\r
1898 * the header fields (just the known tags and the interpretation of the
\r
1901 temp = png_get_uint_32(profile+36); /* signature 'ascp' */
\r
1902 if (temp != 0x61637370)
\r
1903 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1904 "invalid signature");
\r
1906 /* Currently the PCS illuminant/adopted white point (the computational
\r
1907 * white point) are required to be D50,
\r
1908 * however the profile contains a record of the illuminant so perhaps ICC
\r
1909 * expects to be able to change this in the future (despite the rationale in
\r
1910 * the introduction for using a fixed PCS adopted white.) Consequently the
\r
1911 * following is just a warning.
\r
1913 if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
\r
1914 (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
\r
1915 "PCS illuminant is not D50");
\r
1917 /* The PNG spec requires this:
\r
1918 * "If the iCCP chunk is present, the image samples conform to the colour
\r
1919 * space represented by the embedded ICC profile as defined by the
\r
1920 * International Color Consortium [ICC]. The colour space of the ICC profile
\r
1921 * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
\r
1922 * 6), or a greyscale colour space for greyscale images (PNG colour types 0
\r
1925 * This checking code ensures the embedded profile (on either read or write)
\r
1926 * conforms to the specification requirements. Notice that an ICC 'gray'
\r
1927 * color-space profile contains the information to transform the monochrome
\r
1928 * data to XYZ or L*a*b (according to which PCS the profile uses) and this
\r
1929 * should be used in preference to the standard libpng K channel replication
\r
1930 * into R, G and B channels.
\r
1932 * Previously it was suggested that an RGB profile on grayscale data could be
\r
1933 * handled. However it it is clear that using an RGB profile in this context
\r
1934 * must be an error - there is no specification of what it means. Thus it is
\r
1935 * almost certainly more correct to ignore the profile.
\r
1937 temp = png_get_uint_32(profile+16); /* data colour space field */
\r
1940 case 0x52474220: /* 'RGB ' */
\r
1941 if (!(color_type & PNG_COLOR_MASK_COLOR))
\r
1942 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1943 "RGB color space not permitted on grayscale PNG");
\r
1946 case 0x47524159: /* 'GRAY' */
\r
1947 if (color_type & PNG_COLOR_MASK_COLOR)
\r
1948 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1949 "Gray color space not permitted on RGB PNG");
\r
1953 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1954 "invalid ICC profile color space");
\r
1957 /* It is up to the application to check that the profile class matches the
\r
1958 * application requirements; the spec provides no guidance, but it's pretty
\r
1959 * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
\r
1960 * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these
\r
1961 * cases. Issue an error for device link or abstract profiles - these don't
\r
1962 * contain the records necessary to transform the color-space to anything
\r
1963 * other than the target device (and not even that for an abstract profile).
\r
1964 * Profiles of these classes may not be embedded in images.
\r
1966 temp = png_get_uint_32(profile+12); /* profile/device class */
\r
1969 case 0x73636E72: /* 'scnr' */
\r
1970 case 0x6D6E7472: /* 'mntr' */
\r
1971 case 0x70727472: /* 'prtr' */
\r
1972 case 0x73706163: /* 'spac' */
\r
1973 /* All supported */
\r
1976 case 0x61627374: /* 'abst' */
\r
1977 /* May not be embedded in an image */
\r
1978 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1979 "invalid embedded Abstract ICC profile");
\r
1981 case 0x6C696E6B: /* 'link' */
\r
1982 /* DeviceLink profiles cannnot be interpreted in a non-device specific
\r
1983 * fashion, if an app uses the AToB0Tag in the profile the results are
\r
1984 * undefined unless the result is sent to the intended device,
\r
1985 * therefore a DeviceLink profile should not be found embedded in a
\r
1988 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
1989 "unexpected DeviceLink ICC profile class");
\r
1991 case 0x6E6D636C: /* 'nmcl' */
\r
1992 /* A NamedColor profile is also device specific, however it doesn't
\r
1993 * contain an AToB0 tag that is open to misintrepretation. Almost
\r
1994 * certainly it will fail the tests below.
\r
1996 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
\r
1997 "unexpected NamedColor ICC profile class");
\r
2001 /* To allow for future enhancements to the profile accept unrecognized
\r
2002 * profile classes with a warning, these then hit the test below on the
\r
2003 * tag content to ensure they are backward compatible with one of the
\r
2004 * understood profiles.
\r
2006 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
\r
2007 "unrecognized ICC profile class");
\r
2011 /* For any profile other than a device link one the PCS must be encoded
\r
2012 * either in XYZ or Lab.
\r
2014 temp = png_get_uint_32(profile+20);
\r
2017 case 0x58595A20: /* 'XYZ ' */
\r
2018 case 0x4C616220: /* 'Lab ' */
\r
2022 return png_icc_profile_error(png_ptr, colorspace, name, temp,
\r
2023 "unexpected ICC PCS encoding");
\r
2030 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
2031 png_const_charp name, png_uint_32 profile_length,
\r
2032 png_const_bytep profile /* header plus whole tag table */)
\r
2034 png_uint_32 tag_count = png_get_uint_32(profile+128);
\r
2036 png_const_bytep tag = profile+132; /* The first tag */
\r
2038 /* First scan all the tags in the table and add bits to the icc_info value
\r
2039 * (temporarily in 'tags').
\r
2041 for (itag=0; itag < tag_count; ++itag, tag += 12)
\r
2043 png_uint_32 tag_id = png_get_uint_32(tag+0);
\r
2044 png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
\r
2045 png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
\r
2047 /* The ICC specification does not exclude zero length tags, therefore the
\r
2048 * start might actually be anywhere if there is no data, but this would be
\r
2049 * a clear abuse of the intent of the standard so the start is checked for
\r
2050 * being in range. All defined tag types have an 8 byte header - a 4 byte
\r
2051 * type signature then 0.
\r
2053 if ((tag_start & 3) != 0)
\r
2055 /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
\r
2056 * only a warning here because libpng does not care about the
\r
2059 (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
\r
2060 "ICC profile tag start not a multiple of 4");
\r
2063 /* This is a hard error; potentially it can cause read outside the
\r
2066 if (tag_start > profile_length || tag_length > profile_length - tag_start)
\r
2067 return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
\r
2068 "ICC profile tag outside profile");
\r
2071 return 1; /* success, maybe with warnings */
\r
2074 #ifdef PNG_sRGB_SUPPORTED
\r
2075 /* Information about the known ICC sRGB profiles */
\r
2076 static const struct
\r
2078 png_uint_32 adler, crc, length;
\r
2079 png_uint_32 md5[4];
\r
2080 png_byte have_md5;
\r
2081 png_byte is_broken;
\r
2082 png_uint_16 intent;
\r
2084 # define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
\r
2085 # define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
\r
2086 { adler, crc, length, md5, broke, intent },
\r
2088 } png_sRGB_checks[] =
\r
2090 /* This data comes from contrib/tools/checksum-icc run on downloads of
\r
2091 * all four ICC sRGB profiles from www.color.org.
\r
2093 /* adler32, crc32, MD5[4], intent, date, length, file-name */
\r
2094 PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
\r
2095 PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
\r
2096 "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
\r
2098 /* ICC sRGB v2 perceptual no black-compensation: */
\r
2099 PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
\r
2100 PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
\r
2101 "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
\r
2103 PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
\r
2104 PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
\r
2105 "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
\r
2107 /* ICC sRGB v4 perceptual */
\r
2108 PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
\r
2109 PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
\r
2110 "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
\r
2112 /* The following profiles have no known MD5 checksum. If there is a match
\r
2113 * on the (empty) MD5 the other fields are used to attempt a match and
\r
2114 * a warning is produced. The first two of these profiles have a 'cprt' tag
\r
2115 * which suggests that they were also made by Hewlett Packard.
\r
2117 PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
\r
2118 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
\r
2119 "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
\r
2121 /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
\r
2122 * match the D50 PCS illuminant in the header (it is in fact the D65 values,
\r
2123 * so the white point is recorded as the un-adapted value.) The profiles
\r
2124 * below only differ in one byte - the intent - and are basically the same as
\r
2125 * the previous profile except for the mediaWhitePointTag error and a missing
\r
2126 * chromaticAdaptationTag.
\r
2128 PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
\r
2129 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
\r
2130 "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
\r
2132 PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
\r
2133 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
\r
2134 "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
\r
2138 png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
\r
2139 png_const_bytep profile, uLong adler)
\r
2141 /* The quick check is to verify just the MD5 signature and trust the
\r
2142 * rest of the data. Because the profile has already been verified for
\r
2143 * correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
\r
2144 * field too, so if the profile has been edited with an intent not defined
\r
2145 * by sRGB (but maybe defined by a later ICC specification) the read of
\r
2146 * the profile will fail at that point.
\r
2148 png_uint_32 length = 0;
\r
2149 png_uint_32 intent = 0x10000; /* invalid */
\r
2150 #if PNG_sRGB_PROFILE_CHECKS > 1
\r
2151 uLong crc = 0; /* the value for 0 length data */
\r
2155 for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
\r
2157 if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
\r
2158 png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
\r
2159 png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
\r
2160 png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
\r
2162 /* This may be one of the old HP profiles without an MD5, in that
\r
2163 * case we can only use the length and Adler32 (note that these
\r
2164 * are not used by default if there is an MD5!)
\r
2166 # if PNG_sRGB_PROFILE_CHECKS == 0
\r
2167 if (png_sRGB_checks[i].have_md5)
\r
2168 return 1+png_sRGB_checks[i].is_broken;
\r
2171 /* Profile is unsigned or more checks have been configured in. */
\r
2174 length = png_get_uint_32(profile);
\r
2175 intent = png_get_uint_32(profile+64);
\r
2178 /* Length *and* intent must match */
\r
2179 if (length == png_sRGB_checks[i].length &&
\r
2180 intent == png_sRGB_checks[i].intent)
\r
2182 /* Now calculate the adler32 if not done already. */
\r
2185 adler = adler32(0, NULL, 0);
\r
2186 adler = adler32(adler, profile, length);
\r
2189 if (adler == png_sRGB_checks[i].adler)
\r
2191 /* These basic checks suggest that the data has not been
\r
2192 * modified, but if the check level is more than 1 perform
\r
2193 * our own crc32 checksum on the data.
\r
2195 # if PNG_sRGB_PROFILE_CHECKS > 1
\r
2198 crc = crc32(0, NULL, 0);
\r
2199 crc = crc32(crc, profile, length);
\r
2202 /* So this check must pass for the 'return' below to happen.
\r
2204 if (crc == png_sRGB_checks[i].crc)
\r
2207 if (png_sRGB_checks[i].is_broken)
\r
2209 /* These profiles are known to have bad data that may cause
\r
2210 * problems if they are used, therefore attempt to
\r
2211 * discourage their use, skip the 'have_md5' warning below,
\r
2212 * which is made irrelevant by this error.
\r
2214 png_chunk_report(png_ptr, "known incorrect sRGB profile",
\r
2218 /* Warn that this being done; this isn't even an error since
\r
2219 * the profile is perfectly valid, but it would be nice if
\r
2220 * people used the up-to-date ones.
\r
2222 else if (!png_sRGB_checks[i].have_md5)
\r
2224 png_chunk_report(png_ptr,
\r
2225 "out-of-date sRGB profile with no signature",
\r
2226 PNG_CHUNK_WARNING);
\r
2229 return 1+png_sRGB_checks[i].is_broken;
\r
2234 # if PNG_sRGB_PROFILE_CHECKS > 0
\r
2235 /* The signature matched, but the profile had been changed in some
\r
2236 * way. This is an apparent violation of the ICC terms of use and,
\r
2237 * anyway, probably indicates a data error or uninformed hacking.
\r
2239 if (png_sRGB_checks[i].have_md5)
\r
2240 png_benign_error(png_ptr,
\r
2241 "copyright violation: edited ICC profile ignored");
\r
2246 return 0; /* no match */
\r
2250 #ifdef PNG_sRGB_SUPPORTED
\r
2251 void /* PRIVATE */
\r
2252 png_icc_set_sRGB(png_const_structrp png_ptr,
\r
2253 png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
\r
2255 /* Is this profile one of the known ICC sRGB profiles? If it is, just set
\r
2256 * the sRGB information.
\r
2258 if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
\r
2259 (void)png_colorspace_set_sRGB(png_ptr, colorspace,
\r
2260 (int)/*already checked*/png_get_uint_32(profile+64));
\r
2262 #endif /* PNG_READ_sRGB_SUPPORTED */
\r
2265 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
\r
2266 png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
\r
2269 if (colorspace->flags & PNG_COLORSPACE_INVALID)
\r
2272 if (png_icc_check_length(png_ptr, colorspace, name, profile_length) &&
\r
2273 png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
\r
2275 png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
\r
2278 # ifdef PNG_sRGB_SUPPORTED
\r
2279 /* If no sRGB support, don't try storing sRGB information */
\r
2280 png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
\r
2285 /* Failure case */
\r
2290 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
\r
2291 void /* PRIVATE */
\r
2292 png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
\r
2294 /* Set the rgb_to_gray coefficients from the colorspace. */
\r
2295 if (!png_ptr->rgb_to_gray_coefficients_set &&
\r
2296 (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
\r
2298 /* png_set_background has not been called, get the coefficients from the Y
\r
2299 * values of the colorspace colorants.
\r
2301 png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
\r
2302 png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
\r
2303 png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
\r
2304 png_fixed_point total = r+g+b;
\r
2307 r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
\r
2308 g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
\r
2309 b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
\r
2312 /* We allow 0 coefficients here. r+g+b may be 32769 if two or
\r
2313 * all of the coefficients were rounded up. Handle this by
\r
2314 * reducing the *largest* coefficient by 1; this matches the
\r
2315 * approach used for the default coefficients in pngrtran.c
\r
2319 if (r+g+b > 32768)
\r
2321 else if (r+g+b < 32768)
\r
2326 if (g >= r && g >= b)
\r
2328 else if (r >= g && r >= b)
\r
2334 /* Check for an internal error. */
\r
2335 if (r+g+b != 32768)
\r
2336 png_error(png_ptr,
\r
2337 "internal error handling cHRM coefficients");
\r
2341 png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
\r
2342 png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
\r
2346 /* This is a png_error at present even though it could be ignored -
\r
2347 * it should never happen, but it is important that if it does, the
\r
2351 png_error(png_ptr, "internal error handling cHRM->XYZ");
\r
2356 #endif /* COLORSPACE */
\r
2358 void /* PRIVATE */
\r
2359 png_check_IHDR(png_const_structrp png_ptr,
\r
2360 png_uint_32 width, png_uint_32 height, int bit_depth,
\r
2361 int color_type, int interlace_type, int compression_type,
\r
2366 /* Check for width and height valid values */
\r
2369 png_warning(png_ptr, "Image width is zero in IHDR");
\r
2375 png_warning(png_ptr, "Image height is zero in IHDR");
\r
2379 # ifdef PNG_SET_USER_LIMITS_SUPPORTED
\r
2380 if (width > png_ptr->user_width_max)
\r
2383 if (width > PNG_USER_WIDTH_MAX)
\r
2386 png_warning(png_ptr, "Image width exceeds user limit in IHDR");
\r
2390 # ifdef PNG_SET_USER_LIMITS_SUPPORTED
\r
2391 if (height > png_ptr->user_height_max)
\r
2393 if (height > PNG_USER_HEIGHT_MAX)
\r
2396 png_warning(png_ptr, "Image height exceeds user limit in IHDR");
\r
2400 if (width > PNG_UINT_31_MAX)
\r
2402 png_warning(png_ptr, "Invalid image width in IHDR");
\r
2406 if (height > PNG_UINT_31_MAX)
\r
2408 png_warning(png_ptr, "Invalid image height in IHDR");
\r
2412 if (width > (PNG_UINT_32_MAX
\r
2413 >> 3) /* 8-byte RGBA pixels */
\r
2414 - 48 /* bigrowbuf hack */
\r
2415 - 1 /* filter byte */
\r
2416 - 7*8 /* rounding of width to multiple of 8 pixels */
\r
2417 - 8) /* extra max_pixel_depth pad */
\r
2418 png_warning(png_ptr, "Width is too large for libpng to process pixels");
\r
2420 /* Check other values */
\r
2421 if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
\r
2422 bit_depth != 8 && bit_depth != 16)
\r
2424 png_warning(png_ptr, "Invalid bit depth in IHDR");
\r
2428 if (color_type < 0 || color_type == 1 ||
\r
2429 color_type == 5 || color_type > 6)
\r
2431 png_warning(png_ptr, "Invalid color type in IHDR");
\r
2435 if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
\r
2436 ((color_type == PNG_COLOR_TYPE_RGB ||
\r
2437 color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
\r
2438 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
\r
2440 png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
\r
2444 if (interlace_type >= PNG_INTERLACE_LAST)
\r
2446 png_warning(png_ptr, "Unknown interlace method in IHDR");
\r
2450 if (compression_type != PNG_COMPRESSION_TYPE_BASE)
\r
2452 png_warning(png_ptr, "Unknown compression method in IHDR");
\r
2456 # ifdef PNG_MNG_FEATURES_SUPPORTED
\r
2457 /* Accept filter_method 64 (intrapixel differencing) only if
\r
2458 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
\r
2459 * 2. Libpng did not read a PNG signature (this filter_method is only
\r
2460 * used in PNG datastreams that are embedded in MNG datastreams) and
\r
2461 * 3. The application called png_permit_mng_features with a mask that
\r
2462 * included PNG_FLAG_MNG_FILTER_64 and
\r
2463 * 4. The filter_method is 64 and
\r
2464 * 5. The color_type is RGB or RGBA
\r
2466 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
\r
2467 png_ptr->mng_features_permitted)
\r
2468 png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
\r
2470 if (filter_type != PNG_FILTER_TYPE_BASE)
\r
2472 if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
\r
2473 (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
\r
2474 ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
\r
2475 (color_type == PNG_COLOR_TYPE_RGB ||
\r
2476 color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
\r
2478 png_warning(png_ptr, "Unknown filter method in IHDR");
\r
2482 if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
\r
2484 png_warning(png_ptr, "Invalid filter method in IHDR");
\r
2490 if (filter_type != PNG_FILTER_TYPE_BASE)
\r
2492 png_warning(png_ptr, "Unknown filter method in IHDR");
\r
2498 png_error(png_ptr, "Invalid IHDR data");
\r
2501 #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
\r
2502 /* ASCII to fp functions */
\r
2503 /* Check an ASCII formated floating point value, see the more detailed
\r
2504 * comments in pngpriv.h
\r
2506 /* The following is used internally to preserve the sticky flags */
\r
2507 #define png_fp_add(state, flags) ((state) |= (flags))
\r
2508 #define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
\r
2511 png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
\r
2512 png_size_tp whereami)
\r
2514 int state = *statep;
\r
2515 png_size_t i = *whereami;
\r
2520 /* First find the type of the next character */
\r
2521 switch (string[i])
\r
2523 case 43: type = PNG_FP_SAW_SIGN; break;
\r
2524 case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
\r
2525 case 46: type = PNG_FP_SAW_DOT; break;
\r
2526 case 48: type = PNG_FP_SAW_DIGIT; break;
\r
2527 case 49: case 50: case 51: case 52:
\r
2528 case 53: case 54: case 55: case 56:
\r
2529 case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
\r
2531 case 101: type = PNG_FP_SAW_E; break;
\r
2532 default: goto PNG_FP_End;
\r
2535 /* Now deal with this type according to the current
\r
2536 * state, the type is arranged to not overlap the
\r
2537 * bits of the PNG_FP_STATE.
\r
2539 switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
\r
2541 case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
\r
2542 if (state & PNG_FP_SAW_ANY)
\r
2543 goto PNG_FP_End; /* not a part of the number */
\r
2545 png_fp_add(state, type);
\r
2548 case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
\r
2549 /* Ok as trailer, ok as lead of fraction. */
\r
2550 if (state & PNG_FP_SAW_DOT) /* two dots */
\r
2553 else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */
\r
2554 png_fp_add(state, type);
\r
2557 png_fp_set(state, PNG_FP_FRACTION | type);
\r
2561 case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
\r
2562 if (state & PNG_FP_SAW_DOT) /* delayed fraction */
\r
2563 png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
\r
2565 png_fp_add(state, type | PNG_FP_WAS_VALID);
\r
2569 case PNG_FP_INTEGER + PNG_FP_SAW_E:
\r
2570 if ((state & PNG_FP_SAW_DIGIT) == 0)
\r
2573 png_fp_set(state, PNG_FP_EXPONENT);
\r
2577 /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
\r
2578 goto PNG_FP_End; ** no sign in fraction */
\r
2580 /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
\r
2581 goto PNG_FP_End; ** Because SAW_DOT is always set */
\r
2583 case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
\r
2584 png_fp_add(state, type | PNG_FP_WAS_VALID);
\r
2587 case PNG_FP_FRACTION + PNG_FP_SAW_E:
\r
2588 /* This is correct because the trailing '.' on an
\r
2589 * integer is handled above - so we can only get here
\r
2590 * with the sequence ".E" (with no preceding digits).
\r
2592 if ((state & PNG_FP_SAW_DIGIT) == 0)
\r
2595 png_fp_set(state, PNG_FP_EXPONENT);
\r
2599 case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
\r
2600 if (state & PNG_FP_SAW_ANY)
\r
2601 goto PNG_FP_End; /* not a part of the number */
\r
2603 png_fp_add(state, PNG_FP_SAW_SIGN);
\r
2607 /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
\r
2608 goto PNG_FP_End; */
\r
2610 case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
\r
2611 png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
\r
2615 /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
\r
2616 goto PNG_FP_End; */
\r
2618 default: goto PNG_FP_End; /* I.e. break 2 */
\r
2621 /* The character seems ok, continue. */
\r
2626 /* Here at the end, update the state and return the correct
\r
2632 return (state & PNG_FP_SAW_DIGIT) != 0;
\r
2636 /* The same but for a complete string. */
\r
2638 png_check_fp_string(png_const_charp string, png_size_t size)
\r
2641 png_size_t char_index=0;
\r
2643 if (png_check_fp_number(string, size, &state, &char_index) &&
\r
2644 (char_index == size || string[char_index] == 0))
\r
2645 return state /* must be non-zero - see above */;
\r
2647 return 0; /* i.e. fail */
\r
2649 #endif /* pCAL or sCAL */
\r
2651 #ifdef PNG_sCAL_SUPPORTED
\r
2652 # ifdef PNG_FLOATING_POINT_SUPPORTED
\r
2653 /* Utility used below - a simple accurate power of ten from an integral
\r
2657 png_pow10(int power)
\r
2662 /* Handle negative exponent with a reciprocal at the end because
\r
2663 * 10 is exact whereas .1 is inexact in base 2
\r
2667 if (power < DBL_MIN_10_EXP) return 0;
\r
2668 recip = 1, power = -power;
\r
2673 /* Decompose power bitwise. */
\r
2677 if (power & 1) d *= mult;
\r
2681 while (power > 0);
\r
2683 if (recip) d = 1/d;
\r
2685 /* else power is 0 and d is 1 */
\r
2690 /* Function to format a floating point value in ASCII with a given
\r
2693 void /* PRIVATE */
\r
2694 png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
\r
2695 double fp, unsigned int precision)
\r
2697 /* We use standard functions from math.h, but not printf because
\r
2698 * that would require stdio. The caller must supply a buffer of
\r
2699 * sufficient size or we will png_error. The tests on size and
\r
2700 * the space in ascii[] consumed are indicated below.
\r
2702 if (precision < 1)
\r
2703 precision = DBL_DIG;
\r
2705 /* Enforce the limit of the implementation precision too. */
\r
2706 if (precision > DBL_DIG+1)
\r
2707 precision = DBL_DIG+1;
\r
2709 /* Basic sanity checks */
\r
2710 if (size >= precision+5) /* See the requirements below. */
\r
2715 *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */
\r
2719 if (fp >= DBL_MIN && fp <= DBL_MAX)
\r
2721 int exp_b10; /* A base 10 exponent */
\r
2722 double base; /* 10^exp_b10 */
\r
2724 /* First extract a base 10 exponent of the number,
\r
2725 * the calculation below rounds down when converting
\r
2726 * from base 2 to base 10 (multiply by log10(2) -
\r
2727 * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
\r
2728 * be increased. Note that the arithmetic shift
\r
2729 * performs a floor() unlike C arithmetic - using a
\r
2730 * C multiply would break the following for negative
\r
2733 (void)frexp(fp, &exp_b10); /* exponent to base 2 */
\r
2735 exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
\r
2737 /* Avoid underflow here. */
\r
2738 base = png_pow10(exp_b10); /* May underflow */
\r
2740 while (base < DBL_MIN || base < fp)
\r
2742 /* And this may overflow. */
\r
2743 double test = png_pow10(exp_b10+1);
\r
2745 if (test <= DBL_MAX)
\r
2746 ++exp_b10, base = test;
\r
2752 /* Normalize fp and correct exp_b10, after this fp is in the
\r
2753 * range [.1,1) and exp_b10 is both the exponent and the digit
\r
2754 * *before* which the decimal point should be inserted
\r
2755 * (starting with 0 for the first digit). Note that this
\r
2756 * works even if 10^exp_b10 is out of range because of the
\r
2757 * test on DBL_MAX above.
\r
2760 while (fp >= 1) fp /= 10, ++exp_b10;
\r
2762 /* Because of the code above fp may, at this point, be
\r
2763 * less than .1, this is ok because the code below can
\r
2764 * handle the leading zeros this generates, so no attempt
\r
2765 * is made to correct that here.
\r
2769 int czero, clead, cdigits;
\r
2770 char exponent[10];
\r
2772 /* Allow up to two leading zeros - this will not lengthen
\r
2773 * the number compared to using E-n.
\r
2775 if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
\r
2777 czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
\r
2778 exp_b10 = 0; /* Dot added below before first output. */
\r
2781 czero = 0; /* No zeros to add */
\r
2783 /* Generate the digit list, stripping trailing zeros and
\r
2784 * inserting a '.' before a digit if the exponent is 0.
\r
2786 clead = czero; /* Count of leading zeros */
\r
2787 cdigits = 0; /* Count of digits in list. */
\r
2794 /* Use modf here, not floor and subtract, so that
\r
2795 * the separation is done in one step. At the end
\r
2796 * of the loop don't break the number into parts so
\r
2797 * that the final digit is rounded.
\r
2799 if (cdigits+czero-clead+1 < (int)precision)
\r
2800 fp = modf(fp, &d);
\r
2804 d = floor(fp + .5);
\r
2808 /* Rounding up to 10, handle that here. */
\r
2812 if (cdigits == 0) --clead;
\r
2816 while (cdigits > 0 && d > 9)
\r
2818 int ch = *--ascii;
\r
2820 if (exp_b10 != (-1))
\r
2823 else if (ch == 46)
\r
2825 ch = *--ascii, ++size;
\r
2826 /* Advance exp_b10 to '1', so that the
\r
2827 * decimal point happens after the
\r
2834 d = ch - 47; /* I.e. 1+(ch-48) */
\r
2837 /* Did we reach the beginning? If so adjust the
\r
2838 * exponent but take into account the leading
\r
2841 if (d > 9) /* cdigits == 0 */
\r
2843 if (exp_b10 == (-1))
\r
2845 /* Leading decimal point (plus zeros?), if
\r
2846 * we lose the decimal point here it must
\r
2847 * be reentered below.
\r
2849 int ch = *--ascii;
\r
2852 ++size, exp_b10 = 1;
\r
2854 /* Else lost a leading zero, so 'exp_b10' is
\r
2855 * still ok at (-1)
\r
2861 /* In all cases we output a '1' */
\r
2866 fp = 0; /* Guarantees termination below. */
\r
2872 if (cdigits == 0) ++clead;
\r
2876 /* Included embedded zeros in the digit count. */
\r
2877 cdigits += czero - clead;
\r
2882 /* exp_b10 == (-1) means we just output the decimal
\r
2883 * place - after the DP don't adjust 'exp_b10' any
\r
2886 if (exp_b10 != (-1))
\r
2888 if (exp_b10 == 0) *ascii++ = 46, --size;
\r
2889 /* PLUS 1: TOTAL 4 */
\r
2892 *ascii++ = 48, --czero;
\r
2895 if (exp_b10 != (-1))
\r
2897 if (exp_b10 == 0) *ascii++ = 46, --size; /* counted
\r
2901 *ascii++ = (char)(48 + (int)d), ++cdigits;
\r
2904 while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
\r
2906 /* The total output count (max) is now 4+precision */
\r
2908 /* Check for an exponent, if we don't need one we are
\r
2909 * done and just need to terminate the string. At
\r
2910 * this point exp_b10==(-1) is effectively if flag - it got
\r
2911 * to '-1' because of the decrement after outputing
\r
2912 * the decimal point above (the exponent required is
\r
2915 if (exp_b10 >= (-1) && exp_b10 <= 2)
\r
2917 /* The following only happens if we didn't output the
\r
2918 * leading zeros above for negative exponent, so this
\r
2919 * doest add to the digit requirement. Note that the
\r
2920 * two zeros here can only be output if the two leading
\r
2921 * zeros were *not* output, so this doesn't increase
\r
2922 * the output count.
\r
2924 while (--exp_b10 >= 0) *ascii++ = 48;
\r
2928 /* Total buffer requirement (including the '\0') is
\r
2929 * 5+precision - see check at the start.
\r
2934 /* Here if an exponent is required, adjust size for
\r
2935 * the digits we output but did not count. The total
\r
2936 * digit output here so far is at most 1+precision - no
\r
2937 * decimal point and no leading or trailing zeros have
\r
2942 *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
\r
2944 /* The following use of an unsigned temporary avoids ambiguities in
\r
2945 * the signed arithmetic on exp_b10 and permits GCC at least to do
\r
2946 * better optimization.
\r
2949 unsigned int uexp_b10;
\r
2953 *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
\r
2954 uexp_b10 = -exp_b10;
\r
2958 uexp_b10 = exp_b10;
\r
2962 while (uexp_b10 > 0)
\r
2964 exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
\r
2969 /* Need another size check here for the exponent digits, so
\r
2970 * this need not be considered above.
\r
2972 if ((int)size > cdigits)
\r
2974 while (cdigits > 0) *ascii++ = exponent[--cdigits];
\r
2982 else if (!(fp >= DBL_MIN))
\r
2984 *ascii++ = 48; /* '0' */
\r
2990 *ascii++ = 105; /* 'i' */
\r
2991 *ascii++ = 110; /* 'n' */
\r
2992 *ascii++ = 102; /* 'f' */
\r
2998 /* Here on buffer too small. */
\r
2999 png_error(png_ptr, "ASCII conversion buffer too small");
\r
3002 # endif /* FLOATING_POINT */
\r
3004 # ifdef PNG_FIXED_POINT_SUPPORTED
\r
3005 /* Function to format a fixed point value in ASCII.
\r
3007 void /* PRIVATE */
\r
3008 png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
\r
3009 png_size_t size, png_fixed_point fp)
\r
3011 /* Require space for 10 decimal digits, a decimal point, a minus sign and a
\r
3012 * trailing \0, 13 characters:
\r
3018 /* Avoid overflow here on the minimum integer. */
\r
3020 *ascii++ = 45, --size, num = -fp;
\r
3024 if (num <= 0x80000000) /* else overflowed */
\r
3026 unsigned int ndigits = 0, first = 16 /* flag value */;
\r
3031 /* Split the low digit off num: */
\r
3032 unsigned int tmp = num/10;
\r
3034 digits[ndigits++] = (char)(48 + num);
\r
3035 /* Record the first non-zero digit, note that this is a number
\r
3036 * starting at 1, it's not actually the array index.
\r
3038 if (first == 16 && num > 0)
\r
3045 while (ndigits > 5) *ascii++ = digits[--ndigits];
\r
3046 /* The remaining digits are fractional digits, ndigits is '5' or
\r
3047 * smaller at this point. It is certainly not zero. Check for a
\r
3048 * non-zero fractional digit:
\r
3053 *ascii++ = 46; /* decimal point */
\r
3054 /* ndigits may be <5 for small numbers, output leading zeros
\r
3055 * then ndigits digits to first:
\r
3058 while (ndigits < i) *ascii++ = 48, --i;
\r
3059 while (ndigits >= first) *ascii++ = digits[--ndigits];
\r