[LIBPNG] Update to v1.6.21. CORE-11128
[reactos.git] / reactos / dll / 3rdparty / libpng / png.c
1
2 /* png.c - location for general purpose libpng functions
3 *
4 * Last changed in libpng 1.6.19 [November 12, 2015]
5 * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
12 */
13
14 #include "pngpriv.h"
15
16 /* Generate a compiler error if there is an old png.h in the search path. */
17 typedef png_libpng_version_1_6_21 Your_png_h_is_not_version_1_6_21;
18
19 /* Tells libpng that we have already handled the first "num_bytes" bytes
20 * of the PNG file signature. If the PNG data is embedded into another
21 * stream we can set num_bytes = 8 so that libpng will not attempt to read
22 * or write any of the magic bytes before it starts on the IHDR.
23 */
24
25 #ifdef PNG_READ_SUPPORTED
26 void PNGAPI
27 png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
28 {
29 unsigned int nb = (unsigned int)num_bytes;
30
31 png_debug(1, "in png_set_sig_bytes");
32
33 if (png_ptr == NULL)
34 return;
35
36 if (num_bytes < 0)
37 nb = 0;
38
39 if (nb > 8)
40 png_error(png_ptr, "Too many bytes for PNG signature");
41
42 png_ptr->sig_bytes = (png_byte)nb;
43 }
44
45 /* Checks whether the supplied bytes match the PNG signature. We allow
46 * checking less than the full 8-byte signature so that those apps that
47 * already read the first few bytes of a file to determine the file type
48 * can simply check the remaining bytes for extra assurance. Returns
49 * an integer less than, equal to, or greater than zero if sig is found,
50 * respectively, to be less than, to match, or be greater than the correct
51 * PNG signature (this is the same behavior as strcmp, memcmp, etc).
52 */
53 int PNGAPI
54 png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
55 {
56 png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
57
58 if (num_to_check > 8)
59 num_to_check = 8;
60
61 else if (num_to_check < 1)
62 return (-1);
63
64 if (start > 7)
65 return (-1);
66
67 if (start + num_to_check > 8)
68 num_to_check = 8 - start;
69
70 return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
71 }
72
73 #endif /* READ */
74
75 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
76 /* Function to allocate memory for zlib */
77 PNG_FUNCTION(voidpf /* PRIVATE */,
78 png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
79 {
80 png_alloc_size_t num_bytes = size;
81
82 if (png_ptr == NULL)
83 return NULL;
84
85 if (items >= (~(png_alloc_size_t)0)/size)
86 {
87 png_warning (png_voidcast(png_structrp, png_ptr),
88 "Potential overflow in png_zalloc()");
89 return NULL;
90 }
91
92 num_bytes *= items;
93 return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
94 }
95
96 /* Function to free memory for zlib */
97 void /* PRIVATE */
98 png_zfree(voidpf png_ptr, voidpf ptr)
99 {
100 png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
101 }
102
103 /* Reset the CRC variable to 32 bits of 1's. Care must be taken
104 * in case CRC is > 32 bits to leave the top bits 0.
105 */
106 void /* PRIVATE */
107 png_reset_crc(png_structrp png_ptr)
108 {
109 /* The cast is safe because the crc is a 32-bit value. */
110 png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
111 }
112
113 /* Calculate the CRC over a section of data. We can only pass as
114 * much data to this routine as the largest single buffer size. We
115 * also check that this data will actually be used before going to the
116 * trouble of calculating it.
117 */
118 void /* PRIVATE */
119 png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
120 {
121 int need_crc = 1;
122
123 if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
124 {
125 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
126 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
127 need_crc = 0;
128 }
129
130 else /* critical */
131 {
132 if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
133 need_crc = 0;
134 }
135
136 /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
137 * systems it is a 64-bit value. crc32, however, returns 32 bits so the
138 * following cast is safe. 'uInt' may be no more than 16 bits, so it is
139 * necessary to perform a loop here.
140 */
141 if (need_crc != 0 && length > 0)
142 {
143 uLong crc = png_ptr->crc; /* Should never issue a warning */
144
145 do
146 {
147 uInt safe_length = (uInt)length;
148 #ifndef __COVERITY__
149 if (safe_length == 0)
150 safe_length = (uInt)-1; /* evil, but safe */
151 #endif
152
153 crc = crc32(crc, ptr, safe_length);
154
155 /* The following should never issue compiler warnings; if they do the
156 * target system has characteristics that will probably violate other
157 * assumptions within the libpng code.
158 */
159 ptr += safe_length;
160 length -= safe_length;
161 }
162 while (length > 0);
163
164 /* And the following is always safe because the crc is only 32 bits. */
165 png_ptr->crc = (png_uint_32)crc;
166 }
167 }
168
169 /* Check a user supplied version number, called from both read and write
170 * functions that create a png_struct.
171 */
172 int
173 png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
174 {
175 /* Libpng versions 1.0.0 and later are binary compatible if the version
176 * string matches through the second '.'; we must recompile any
177 * applications that use any older library version.
178 */
179
180 if (user_png_ver != NULL)
181 {
182 int i = -1;
183 int found_dots = 0;
184
185 do
186 {
187 i++;
188 if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
189 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
190 if (user_png_ver[i] == '.')
191 found_dots++;
192 } while (found_dots < 2 && user_png_ver[i] != 0 &&
193 PNG_LIBPNG_VER_STRING[i] != 0);
194 }
195
196 else
197 png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
198
199 if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
200 {
201 #ifdef PNG_WARNINGS_SUPPORTED
202 size_t pos = 0;
203 char m[128];
204
205 pos = png_safecat(m, (sizeof m), pos,
206 "Application built with libpng-");
207 pos = png_safecat(m, (sizeof m), pos, user_png_ver);
208 pos = png_safecat(m, (sizeof m), pos, " but running with ");
209 pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
210 PNG_UNUSED(pos)
211
212 png_warning(png_ptr, m);
213 #endif
214
215 #ifdef PNG_ERROR_NUMBERS_SUPPORTED
216 png_ptr->flags = 0;
217 #endif
218
219 return 0;
220 }
221
222 /* Success return. */
223 return 1;
224 }
225
226 /* Generic function to create a png_struct for either read or write - this
227 * contains the common initialization.
228 */
229 PNG_FUNCTION(png_structp /* PRIVATE */,
230 png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
231 png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
232 png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
233 {
234 png_struct create_struct;
235 # ifdef PNG_SETJMP_SUPPORTED
236 jmp_buf create_jmp_buf;
237 # endif
238
239 /* This temporary stack-allocated structure is used to provide a place to
240 * build enough context to allow the user provided memory allocator (if any)
241 * to be called.
242 */
243 memset(&create_struct, 0, (sizeof create_struct));
244
245 /* Added at libpng-1.2.6 */
246 # ifdef PNG_USER_LIMITS_SUPPORTED
247 create_struct.user_width_max = PNG_USER_WIDTH_MAX;
248 create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
249
250 # ifdef PNG_USER_CHUNK_CACHE_MAX
251 /* Added at libpng-1.2.43 and 1.4.0 */
252 create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
253 # endif
254
255 # ifdef PNG_USER_CHUNK_MALLOC_MAX
256 /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
257 * in png_struct regardless.
258 */
259 create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
260 # endif
261 # endif
262
263 /* The following two API calls simply set fields in png_struct, so it is safe
264 * to do them now even though error handling is not yet set up.
265 */
266 # ifdef PNG_USER_MEM_SUPPORTED
267 png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
268 # else
269 PNG_UNUSED(mem_ptr)
270 PNG_UNUSED(malloc_fn)
271 PNG_UNUSED(free_fn)
272 # endif
273
274 /* (*error_fn) can return control to the caller after the error_ptr is set,
275 * this will result in a memory leak unless the error_fn does something
276 * extremely sophisticated. The design lacks merit but is implicit in the
277 * API.
278 */
279 png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
280
281 # ifdef PNG_SETJMP_SUPPORTED
282 if (!setjmp(create_jmp_buf))
283 # endif
284 {
285 # ifdef PNG_SETJMP_SUPPORTED
286 /* Temporarily fake out the longjmp information until we have
287 * successfully completed this function. This only works if we have
288 * setjmp() support compiled in, but it is safe - this stuff should
289 * never happen.
290 */
291 create_struct.jmp_buf_ptr = &create_jmp_buf;
292 create_struct.jmp_buf_size = 0; /*stack allocation*/
293 create_struct.longjmp_fn = longjmp;
294 # endif
295 /* Call the general version checker (shared with read and write code):
296 */
297 if (png_user_version_check(&create_struct, user_png_ver) != 0)
298 {
299 png_structrp png_ptr = png_voidcast(png_structrp,
300 png_malloc_warn(&create_struct, (sizeof *png_ptr)));
301
302 if (png_ptr != NULL)
303 {
304 /* png_ptr->zstream holds a back-pointer to the png_struct, so
305 * this can only be done now:
306 */
307 create_struct.zstream.zalloc = png_zalloc;
308 create_struct.zstream.zfree = png_zfree;
309 create_struct.zstream.opaque = png_ptr;
310
311 # ifdef PNG_SETJMP_SUPPORTED
312 /* Eliminate the local error handling: */
313 create_struct.jmp_buf_ptr = NULL;
314 create_struct.jmp_buf_size = 0;
315 create_struct.longjmp_fn = 0;
316 # endif
317
318 *png_ptr = create_struct;
319
320 /* This is the successful return point */
321 return png_ptr;
322 }
323 }
324 }
325
326 /* A longjmp because of a bug in the application storage allocator or a
327 * simple failure to allocate the png_struct.
328 */
329 return NULL;
330 }
331
332 /* Allocate the memory for an info_struct for the application. */
333 PNG_FUNCTION(png_infop,PNGAPI
334 png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
335 {
336 png_inforp info_ptr;
337
338 png_debug(1, "in png_create_info_struct");
339
340 if (png_ptr == NULL)
341 return NULL;
342
343 /* Use the internal API that does not (or at least should not) error out, so
344 * that this call always returns ok. The application typically sets up the
345 * error handling *after* creating the info_struct because this is the way it
346 * has always been done in 'example.c'.
347 */
348 info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
349 (sizeof *info_ptr)));
350
351 if (info_ptr != NULL)
352 memset(info_ptr, 0, (sizeof *info_ptr));
353
354 return info_ptr;
355 }
356
357 /* This function frees the memory associated with a single info struct.
358 * Normally, one would use either png_destroy_read_struct() or
359 * png_destroy_write_struct() to free an info struct, but this may be
360 * useful for some applications. From libpng 1.6.0 this function is also used
361 * internally to implement the png_info release part of the 'struct' destroy
362 * APIs. This ensures that all possible approaches free the same data (all of
363 * it).
364 */
365 void PNGAPI
366 png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
367 {
368 png_inforp info_ptr = NULL;
369
370 png_debug(1, "in png_destroy_info_struct");
371
372 if (png_ptr == NULL)
373 return;
374
375 if (info_ptr_ptr != NULL)
376 info_ptr = *info_ptr_ptr;
377
378 if (info_ptr != NULL)
379 {
380 /* Do this first in case of an error below; if the app implements its own
381 * memory management this can lead to png_free calling png_error, which
382 * will abort this routine and return control to the app error handler.
383 * An infinite loop may result if it then tries to free the same info
384 * ptr.
385 */
386 *info_ptr_ptr = NULL;
387
388 png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
389 memset(info_ptr, 0, (sizeof *info_ptr));
390 png_free(png_ptr, info_ptr);
391 }
392 }
393
394 /* Initialize the info structure. This is now an internal function (0.89)
395 * and applications using it are urged to use png_create_info_struct()
396 * instead. Use deprecated in 1.6.0, internal use removed (used internally it
397 * is just a memset).
398 *
399 * NOTE: it is almost inconceivable that this API is used because it bypasses
400 * the user-memory mechanism and the user error handling/warning mechanisms in
401 * those cases where it does anything other than a memset.
402 */
403 PNG_FUNCTION(void,PNGAPI
404 png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
405 PNG_DEPRECATED)
406 {
407 png_inforp info_ptr = *ptr_ptr;
408
409 png_debug(1, "in png_info_init_3");
410
411 if (info_ptr == NULL)
412 return;
413
414 if ((sizeof (png_info)) > png_info_struct_size)
415 {
416 *ptr_ptr = NULL;
417 /* The following line is why this API should not be used: */
418 free(info_ptr);
419 info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
420 (sizeof *info_ptr)));
421 if (info_ptr == NULL)
422 return;
423 *ptr_ptr = info_ptr;
424 }
425
426 /* Set everything to 0 */
427 memset(info_ptr, 0, (sizeof *info_ptr));
428 }
429
430 /* The following API is not called internally */
431 void PNGAPI
432 png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
433 int freer, png_uint_32 mask)
434 {
435 png_debug(1, "in png_data_freer");
436
437 if (png_ptr == NULL || info_ptr == NULL)
438 return;
439
440 if (freer == PNG_DESTROY_WILL_FREE_DATA)
441 info_ptr->free_me |= mask;
442
443 else if (freer == PNG_USER_WILL_FREE_DATA)
444 info_ptr->free_me &= ~mask;
445
446 else
447 png_error(png_ptr, "Unknown freer parameter in png_data_freer");
448 }
449
450 void PNGAPI
451 png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
452 int num)
453 {
454 png_debug(1, "in png_free_data");
455
456 if (png_ptr == NULL || info_ptr == NULL)
457 return;
458
459 #ifdef PNG_TEXT_SUPPORTED
460 /* Free text item num or (if num == -1) all text items */
461 if (info_ptr->text != 0 &&
462 ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
463 {
464 if (num != -1)
465 {
466 png_free(png_ptr, info_ptr->text[num].key);
467 info_ptr->text[num].key = NULL;
468 }
469
470 else
471 {
472 int i;
473
474 for (i = 0; i < info_ptr->num_text; i++)
475 png_free(png_ptr, info_ptr->text[i].key);
476
477 png_free(png_ptr, info_ptr->text);
478 info_ptr->text = NULL;
479 info_ptr->num_text = 0;
480 }
481 }
482 #endif
483
484 #ifdef PNG_tRNS_SUPPORTED
485 /* Free any tRNS entry */
486 if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
487 {
488 info_ptr->valid &= ~PNG_INFO_tRNS;
489 png_free(png_ptr, info_ptr->trans_alpha);
490 info_ptr->trans_alpha = NULL;
491 info_ptr->num_trans = 0;
492 }
493 #endif
494
495 #ifdef PNG_sCAL_SUPPORTED
496 /* Free any sCAL entry */
497 if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
498 {
499 png_free(png_ptr, info_ptr->scal_s_width);
500 png_free(png_ptr, info_ptr->scal_s_height);
501 info_ptr->scal_s_width = NULL;
502 info_ptr->scal_s_height = NULL;
503 info_ptr->valid &= ~PNG_INFO_sCAL;
504 }
505 #endif
506
507 #ifdef PNG_pCAL_SUPPORTED
508 /* Free any pCAL entry */
509 if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
510 {
511 png_free(png_ptr, info_ptr->pcal_purpose);
512 png_free(png_ptr, info_ptr->pcal_units);
513 info_ptr->pcal_purpose = NULL;
514 info_ptr->pcal_units = NULL;
515
516 if (info_ptr->pcal_params != NULL)
517 {
518 int i;
519
520 for (i = 0; i < info_ptr->pcal_nparams; i++)
521 png_free(png_ptr, info_ptr->pcal_params[i]);
522
523 png_free(png_ptr, info_ptr->pcal_params);
524 info_ptr->pcal_params = NULL;
525 }
526 info_ptr->valid &= ~PNG_INFO_pCAL;
527 }
528 #endif
529
530 #ifdef PNG_iCCP_SUPPORTED
531 /* Free any profile entry */
532 if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
533 {
534 png_free(png_ptr, info_ptr->iccp_name);
535 png_free(png_ptr, info_ptr->iccp_profile);
536 info_ptr->iccp_name = NULL;
537 info_ptr->iccp_profile = NULL;
538 info_ptr->valid &= ~PNG_INFO_iCCP;
539 }
540 #endif
541
542 #ifdef PNG_sPLT_SUPPORTED
543 /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
544 if (info_ptr->splt_palettes != 0 &&
545 ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
546 {
547 if (num != -1)
548 {
549 png_free(png_ptr, info_ptr->splt_palettes[num].name);
550 png_free(png_ptr, info_ptr->splt_palettes[num].entries);
551 info_ptr->splt_palettes[num].name = NULL;
552 info_ptr->splt_palettes[num].entries = NULL;
553 }
554
555 else
556 {
557 int i;
558
559 for (i = 0; i < info_ptr->splt_palettes_num; i++)
560 {
561 png_free(png_ptr, info_ptr->splt_palettes[i].name);
562 png_free(png_ptr, info_ptr->splt_palettes[i].entries);
563 }
564
565 png_free(png_ptr, info_ptr->splt_palettes);
566 info_ptr->splt_palettes = NULL;
567 info_ptr->splt_palettes_num = 0;
568 info_ptr->valid &= ~PNG_INFO_sPLT;
569 }
570 }
571 #endif
572
573 #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
574 if (info_ptr->unknown_chunks != 0 &&
575 ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
576 {
577 if (num != -1)
578 {
579 png_free(png_ptr, info_ptr->unknown_chunks[num].data);
580 info_ptr->unknown_chunks[num].data = NULL;
581 }
582
583 else
584 {
585 int i;
586
587 for (i = 0; i < info_ptr->unknown_chunks_num; i++)
588 png_free(png_ptr, info_ptr->unknown_chunks[i].data);
589
590 png_free(png_ptr, info_ptr->unknown_chunks);
591 info_ptr->unknown_chunks = NULL;
592 info_ptr->unknown_chunks_num = 0;
593 }
594 }
595 #endif
596
597 #ifdef PNG_hIST_SUPPORTED
598 /* Free any hIST entry */
599 if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
600 {
601 png_free(png_ptr, info_ptr->hist);
602 info_ptr->hist = NULL;
603 info_ptr->valid &= ~PNG_INFO_hIST;
604 }
605 #endif
606
607 /* Free any PLTE entry that was internally allocated */
608 if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
609 {
610 png_free(png_ptr, info_ptr->palette);
611 info_ptr->palette = NULL;
612 info_ptr->valid &= ~PNG_INFO_PLTE;
613 info_ptr->num_palette = 0;
614 }
615
616 #ifdef PNG_INFO_IMAGE_SUPPORTED
617 /* Free any image bits attached to the info structure */
618 if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
619 {
620 if (info_ptr->row_pointers != 0)
621 {
622 png_uint_32 row;
623 for (row = 0; row < info_ptr->height; row++)
624 png_free(png_ptr, info_ptr->row_pointers[row]);
625
626 png_free(png_ptr, info_ptr->row_pointers);
627 info_ptr->row_pointers = NULL;
628 }
629 info_ptr->valid &= ~PNG_INFO_IDAT;
630 }
631 #endif
632
633 if (num != -1)
634 mask &= ~PNG_FREE_MUL;
635
636 info_ptr->free_me &= ~mask;
637 }
638 #endif /* READ || WRITE */
639
640 /* This function returns a pointer to the io_ptr associated with the user
641 * functions. The application should free any memory associated with this
642 * pointer before png_write_destroy() or png_read_destroy() are called.
643 */
644 png_voidp PNGAPI
645 png_get_io_ptr(png_const_structrp png_ptr)
646 {
647 if (png_ptr == NULL)
648 return (NULL);
649
650 return (png_ptr->io_ptr);
651 }
652
653 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
654 # ifdef PNG_STDIO_SUPPORTED
655 /* Initialize the default input/output functions for the PNG file. If you
656 * use your own read or write routines, you can call either png_set_read_fn()
657 * or png_set_write_fn() instead of png_init_io(). If you have defined
658 * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
659 * function of your own because "FILE *" isn't necessarily available.
660 */
661 void PNGAPI
662 png_init_io(png_structrp png_ptr, png_FILE_p fp)
663 {
664 png_debug(1, "in png_init_io");
665
666 if (png_ptr == NULL)
667 return;
668
669 png_ptr->io_ptr = (png_voidp)fp;
670 }
671 # endif
672
673 # ifdef PNG_SAVE_INT_32_SUPPORTED
674 /* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90
675 * defines a cast of a signed integer to an unsigned integer either to preserve
676 * the value, if it is positive, or to calculate:
677 *
678 * (UNSIGNED_MAX+1) + integer
679 *
680 * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
681 * negative integral value is added the result will be an unsigned value
682 * correspnding to the 2's complement representation.
683 */
684 void PNGAPI
685 png_save_int_32(png_bytep buf, png_int_32 i)
686 {
687 png_save_uint_32(buf, i);
688 }
689 # endif
690
691 # ifdef PNG_TIME_RFC1123_SUPPORTED
692 /* Convert the supplied time into an RFC 1123 string suitable for use in
693 * a "Creation Time" or other text-based time string.
694 */
695 int PNGAPI
696 png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
697 {
698 static PNG_CONST char short_months[12][4] =
699 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
700 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
701
702 if (out == NULL)
703 return 0;
704
705 if (ptime->year > 9999 /* RFC1123 limitation */ ||
706 ptime->month == 0 || ptime->month > 12 ||
707 ptime->day == 0 || ptime->day > 31 ||
708 ptime->hour > 23 || ptime->minute > 59 ||
709 ptime->second > 60)
710 return 0;
711
712 {
713 size_t pos = 0;
714 char number_buf[5]; /* enough for a four-digit year */
715
716 # define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
717 # define APPEND_NUMBER(format, value)\
718 APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
719 # define APPEND(ch) if (pos < 28) out[pos++] = (ch)
720
721 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
722 APPEND(' ');
723 APPEND_STRING(short_months[(ptime->month - 1)]);
724 APPEND(' ');
725 APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
726 APPEND(' ');
727 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
728 APPEND(':');
729 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
730 APPEND(':');
731 APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
732 APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
733 PNG_UNUSED (pos)
734
735 # undef APPEND
736 # undef APPEND_NUMBER
737 # undef APPEND_STRING
738 }
739
740 return 1;
741 }
742
743 # if PNG_LIBPNG_VER < 10700
744 /* To do: remove the following from libpng-1.7 */
745 /* Original API that uses a private buffer in png_struct.
746 * Deprecated because it causes png_struct to carry a spurious temporary
747 * buffer (png_struct::time_buffer), better to have the caller pass this in.
748 */
749 png_const_charp PNGAPI
750 png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
751 {
752 if (png_ptr != NULL)
753 {
754 /* The only failure above if png_ptr != NULL is from an invalid ptime */
755 if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
756 png_warning(png_ptr, "Ignoring invalid time value");
757
758 else
759 return png_ptr->time_buffer;
760 }
761
762 return NULL;
763 }
764 # endif /* LIBPNG_VER < 10700 */
765 # endif /* TIME_RFC1123 */
766
767 #endif /* READ || WRITE */
768
769 png_const_charp PNGAPI
770 png_get_copyright(png_const_structrp png_ptr)
771 {
772 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
773 #ifdef PNG_STRING_COPYRIGHT
774 return PNG_STRING_COPYRIGHT
775 #else
776 # ifdef __STDC__
777 return PNG_STRING_NEWLINE \
778 "libpng version 1.6.21 - January 15, 2016" PNG_STRING_NEWLINE \
779 "Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson" \
780 PNG_STRING_NEWLINE \
781 "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
782 "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
783 PNG_STRING_NEWLINE;
784 # else
785 return "libpng version 1.6.21 - January 15, 2016\
786 Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson\
787 Copyright (c) 1996-1997 Andreas Dilger\
788 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
789 # endif
790 #endif
791 }
792
793 /* The following return the library version as a short string in the
794 * format 1.0.0 through 99.99.99zz. To get the version of *.h files
795 * used with your application, print out PNG_LIBPNG_VER_STRING, which
796 * is defined in png.h.
797 * Note: now there is no difference between png_get_libpng_ver() and
798 * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
799 * it is guaranteed that png.c uses the correct version of png.h.
800 */
801 png_const_charp PNGAPI
802 png_get_libpng_ver(png_const_structrp png_ptr)
803 {
804 /* Version of *.c files used when building libpng */
805 return png_get_header_ver(png_ptr);
806 }
807
808 png_const_charp PNGAPI
809 png_get_header_ver(png_const_structrp png_ptr)
810 {
811 /* Version of *.h files used when building libpng */
812 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
813 return PNG_LIBPNG_VER_STRING;
814 }
815
816 png_const_charp PNGAPI
817 png_get_header_version(png_const_structrp png_ptr)
818 {
819 /* Returns longer string containing both version and date */
820 PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
821 #ifdef __STDC__
822 return PNG_HEADER_VERSION_STRING
823 # ifndef PNG_READ_SUPPORTED
824 " (NO READ SUPPORT)"
825 # endif
826 PNG_STRING_NEWLINE;
827 #else
828 return PNG_HEADER_VERSION_STRING;
829 #endif
830 }
831
832 #ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
833 /* NOTE: this routine is not used internally! */
834 /* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
835 * large of png_color. This lets grayscale images be treated as
836 * paletted. Most useful for gamma correction and simplification
837 * of code. This API is not used internally.
838 */
839 void PNGAPI
840 png_build_grayscale_palette(int bit_depth, png_colorp palette)
841 {
842 int num_palette;
843 int color_inc;
844 int i;
845 int v;
846
847 png_debug(1, "in png_do_build_grayscale_palette");
848
849 if (palette == NULL)
850 return;
851
852 switch (bit_depth)
853 {
854 case 1:
855 num_palette = 2;
856 color_inc = 0xff;
857 break;
858
859 case 2:
860 num_palette = 4;
861 color_inc = 0x55;
862 break;
863
864 case 4:
865 num_palette = 16;
866 color_inc = 0x11;
867 break;
868
869 case 8:
870 num_palette = 256;
871 color_inc = 1;
872 break;
873
874 default:
875 num_palette = 0;
876 color_inc = 0;
877 break;
878 }
879
880 for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
881 {
882 palette[i].red = (png_byte)(v & 0xff);
883 palette[i].green = (png_byte)(v & 0xff);
884 palette[i].blue = (png_byte)(v & 0xff);
885 }
886 }
887 #endif
888
889 #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
890 int PNGAPI
891 png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
892 {
893 /* Check chunk_name and return "keep" value if it's on the list, else 0 */
894 png_const_bytep p, p_end;
895
896 if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
897 return PNG_HANDLE_CHUNK_AS_DEFAULT;
898
899 p_end = png_ptr->chunk_list;
900 p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
901
902 /* The code is the fifth byte after each four byte string. Historically this
903 * code was always searched from the end of the list, this is no longer
904 * necessary because the 'set' routine handles duplicate entries correcty.
905 */
906 do /* num_chunk_list > 0, so at least one */
907 {
908 p -= 5;
909
910 if (memcmp(chunk_name, p, 4) == 0)
911 return p[4];
912 }
913 while (p > p_end);
914
915 /* This means that known chunks should be processed and unknown chunks should
916 * be handled according to the value of png_ptr->unknown_default; this can be
917 * confusing because, as a result, there are two levels of defaulting for
918 * unknown chunks.
919 */
920 return PNG_HANDLE_CHUNK_AS_DEFAULT;
921 }
922
923 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
924 defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
925 int /* PRIVATE */
926 png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
927 {
928 png_byte chunk_string[5];
929
930 PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
931 return png_handle_as_unknown(png_ptr, chunk_string);
932 }
933 #endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
934 #endif /* SET_UNKNOWN_CHUNKS */
935
936 #ifdef PNG_READ_SUPPORTED
937 /* This function, added to libpng-1.0.6g, is untested. */
938 int PNGAPI
939 png_reset_zstream(png_structrp png_ptr)
940 {
941 if (png_ptr == NULL)
942 return Z_STREAM_ERROR;
943
944 /* WARNING: this resets the window bits to the maximum! */
945 return (inflateReset(&png_ptr->zstream));
946 }
947 #endif /* READ */
948
949 /* This function was added to libpng-1.0.7 */
950 png_uint_32 PNGAPI
951 png_access_version_number(void)
952 {
953 /* Version of *.c files used when building libpng */
954 return((png_uint_32)PNG_LIBPNG_VER);
955 }
956
957 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
958 /* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
959 * If it doesn't 'ret' is used to set it to something appropriate, even in cases
960 * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
961 */
962 void /* PRIVATE */
963 png_zstream_error(png_structrp png_ptr, int ret)
964 {
965 /* Translate 'ret' into an appropriate error string, priority is given to the
966 * one in zstream if set. This always returns a string, even in cases like
967 * Z_OK or Z_STREAM_END where the error code is a success code.
968 */
969 if (png_ptr->zstream.msg == NULL) switch (ret)
970 {
971 default:
972 case Z_OK:
973 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
974 break;
975
976 case Z_STREAM_END:
977 /* Normal exit */
978 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
979 break;
980
981 case Z_NEED_DICT:
982 /* This means the deflate stream did not have a dictionary; this
983 * indicates a bogus PNG.
984 */
985 png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
986 break;
987
988 case Z_ERRNO:
989 /* gz APIs only: should not happen */
990 png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
991 break;
992
993 case Z_STREAM_ERROR:
994 /* internal libpng error */
995 png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
996 break;
997
998 case Z_DATA_ERROR:
999 png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
1000 break;
1001
1002 case Z_MEM_ERROR:
1003 png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
1004 break;
1005
1006 case Z_BUF_ERROR:
1007 /* End of input or output; not a problem if the caller is doing
1008 * incremental read or write.
1009 */
1010 png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
1011 break;
1012
1013 case Z_VERSION_ERROR:
1014 png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
1015 break;
1016
1017 case PNG_UNEXPECTED_ZLIB_RETURN:
1018 /* Compile errors here mean that zlib now uses the value co-opted in
1019 * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
1020 * and change pngpriv.h. Note that this message is "... return",
1021 * whereas the default/Z_OK one is "... return code".
1022 */
1023 png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
1024 break;
1025 }
1026 }
1027
1028 /* png_convert_size: a PNGAPI but no longer in png.h, so deleted
1029 * at libpng 1.5.5!
1030 */
1031
1032 /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
1033 #ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
1034 static int
1035 png_colorspace_check_gamma(png_const_structrp png_ptr,
1036 png_colorspacerp colorspace, png_fixed_point gAMA, int from)
1037 /* This is called to check a new gamma value against an existing one. The
1038 * routine returns false if the new gamma value should not be written.
1039 *
1040 * 'from' says where the new gamma value comes from:
1041 *
1042 * 0: the new gamma value is the libpng estimate for an ICC profile
1043 * 1: the new gamma value comes from a gAMA chunk
1044 * 2: the new gamma value comes from an sRGB chunk
1045 */
1046 {
1047 png_fixed_point gtest;
1048
1049 if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
1050 (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0 ||
1051 png_gamma_significant(gtest) != 0))
1052 {
1053 /* Either this is an sRGB image, in which case the calculated gamma
1054 * approximation should match, or this is an image with a profile and the
1055 * value libpng calculates for the gamma of the profile does not match the
1056 * value recorded in the file. The former, sRGB, case is an error, the
1057 * latter is just a warning.
1058 */
1059 if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
1060 {
1061 png_chunk_report(png_ptr, "gamma value does not match sRGB",
1062 PNG_CHUNK_ERROR);
1063 /* Do not overwrite an sRGB value */
1064 return from == 2;
1065 }
1066
1067 else /* sRGB tag not involved */
1068 {
1069 png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
1070 PNG_CHUNK_WARNING);
1071 return from == 1;
1072 }
1073 }
1074
1075 return 1;
1076 }
1077
1078 void /* PRIVATE */
1079 png_colorspace_set_gamma(png_const_structrp png_ptr,
1080 png_colorspacerp colorspace, png_fixed_point gAMA)
1081 {
1082 /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
1083 * occur. Since the fixed point representation is asymetrical it is
1084 * possible for 1/gamma to overflow the limit of 21474 and this means the
1085 * gamma value must be at least 5/100000 and hence at most 20000.0. For
1086 * safety the limits here are a little narrower. The values are 0.00016 to
1087 * 6250.0, which are truly ridiculous gamma values (and will produce
1088 * displays that are all black or all white.)
1089 *
1090 * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
1091 * handling code, which only required the value to be >0.
1092 */
1093 png_const_charp errmsg;
1094
1095 if (gAMA < 16 || gAMA > 625000000)
1096 errmsg = "gamma value out of range";
1097
1098 # ifdef PNG_READ_gAMA_SUPPORTED
1099 /* Allow the application to set the gamma value more than once */
1100 else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
1101 (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
1102 errmsg = "duplicate";
1103 # endif
1104
1105 /* Do nothing if the colorspace is already invalid */
1106 else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1107 return;
1108
1109 else
1110 {
1111 if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
1112 1/*from gAMA*/) != 0)
1113 {
1114 /* Store this gamma value. */
1115 colorspace->gamma = gAMA;
1116 colorspace->flags |=
1117 (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
1118 }
1119
1120 /* At present if the check_gamma test fails the gamma of the colorspace is
1121 * not updated however the colorspace is not invalidated. This
1122 * corresponds to the case where the existing gamma comes from an sRGB
1123 * chunk or profile. An error message has already been output.
1124 */
1125 return;
1126 }
1127
1128 /* Error exit - errmsg has been set. */
1129 colorspace->flags |= PNG_COLORSPACE_INVALID;
1130 png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
1131 }
1132
1133 void /* PRIVATE */
1134 png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
1135 {
1136 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
1137 {
1138 /* Everything is invalid */
1139 info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
1140 PNG_INFO_iCCP);
1141
1142 # ifdef PNG_COLORSPACE_SUPPORTED
1143 /* Clean up the iCCP profile now if it won't be used. */
1144 png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
1145 # else
1146 PNG_UNUSED(png_ptr)
1147 # endif
1148 }
1149
1150 else
1151 {
1152 # ifdef PNG_COLORSPACE_SUPPORTED
1153 /* Leave the INFO_iCCP flag set if the pngset.c code has already set
1154 * it; this allows a PNG to contain a profile which matches sRGB and
1155 * yet still have that profile retrievable by the application.
1156 */
1157 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
1158 info_ptr->valid |= PNG_INFO_sRGB;
1159
1160 else
1161 info_ptr->valid &= ~PNG_INFO_sRGB;
1162
1163 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
1164 info_ptr->valid |= PNG_INFO_cHRM;
1165
1166 else
1167 info_ptr->valid &= ~PNG_INFO_cHRM;
1168 # endif
1169
1170 if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
1171 info_ptr->valid |= PNG_INFO_gAMA;
1172
1173 else
1174 info_ptr->valid &= ~PNG_INFO_gAMA;
1175 }
1176 }
1177
1178 #ifdef PNG_READ_SUPPORTED
1179 void /* PRIVATE */
1180 png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
1181 {
1182 if (info_ptr == NULL) /* reduce code size; check here not in the caller */
1183 return;
1184
1185 info_ptr->colorspace = png_ptr->colorspace;
1186 png_colorspace_sync_info(png_ptr, info_ptr);
1187 }
1188 #endif
1189 #endif /* GAMMA */
1190
1191 #ifdef PNG_COLORSPACE_SUPPORTED
1192 /* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
1193 * cHRM, as opposed to using chromaticities. These internal APIs return
1194 * non-zero on a parameter error. The X, Y and Z values are required to be
1195 * positive and less than 1.0.
1196 */
1197 static int
1198 png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
1199 {
1200 png_int_32 d, dwhite, whiteX, whiteY;
1201
1202 d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
1203 if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
1204 return 1;
1205 if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
1206 return 1;
1207 dwhite = d;
1208 whiteX = XYZ->red_X;
1209 whiteY = XYZ->red_Y;
1210
1211 d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
1212 if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
1213 return 1;
1214 if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
1215 return 1;
1216 dwhite += d;
1217 whiteX += XYZ->green_X;
1218 whiteY += XYZ->green_Y;
1219
1220 d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
1221 if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
1222 return 1;
1223 if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
1224 return 1;
1225 dwhite += d;
1226 whiteX += XYZ->blue_X;
1227 whiteY += XYZ->blue_Y;
1228
1229 /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
1230 * thus:
1231 */
1232 if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
1233 return 1;
1234 if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
1235 return 1;
1236
1237 return 0;
1238 }
1239
1240 static int
1241 png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
1242 {
1243 png_fixed_point red_inverse, green_inverse, blue_scale;
1244 png_fixed_point left, right, denominator;
1245
1246 /* Check xy and, implicitly, z. Note that wide gamut color spaces typically
1247 * have end points with 0 tristimulus values (these are impossible end
1248 * points, but they are used to cover the possible colors). We check
1249 * xy->whitey against 5, not 0, to avoid a possible integer overflow.
1250 */
1251 if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
1252 if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
1253 if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
1254 if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
1255 if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
1256 if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
1257 if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
1258 if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
1259
1260 /* The reverse calculation is more difficult because the original tristimulus
1261 * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
1262 * derived values were recorded in the cHRM chunk;
1263 * (red,green,blue,white)x(x,y). This loses one degree of freedom and
1264 * therefore an arbitrary ninth value has to be introduced to undo the
1265 * original transformations.
1266 *
1267 * Think of the original end-points as points in (X,Y,Z) space. The
1268 * chromaticity values (c) have the property:
1269 *
1270 * C
1271 * c = ---------
1272 * X + Y + Z
1273 *
1274 * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
1275 * three chromaticity values (x,y,z) for each end-point obey the
1276 * relationship:
1277 *
1278 * x + y + z = 1
1279 *
1280 * This describes the plane in (X,Y,Z) space that intersects each axis at the
1281 * value 1.0; call this the chromaticity plane. Thus the chromaticity
1282 * calculation has scaled each end-point so that it is on the x+y+z=1 plane
1283 * and chromaticity is the intersection of the vector from the origin to the
1284 * (X,Y,Z) value with the chromaticity plane.
1285 *
1286 * To fully invert the chromaticity calculation we would need the three
1287 * end-point scale factors, (red-scale, green-scale, blue-scale), but these
1288 * were not recorded. Instead we calculated the reference white (X,Y,Z) and
1289 * recorded the chromaticity of this. The reference white (X,Y,Z) would have
1290 * given all three of the scale factors since:
1291 *
1292 * color-C = color-c * color-scale
1293 * white-C = red-C + green-C + blue-C
1294 * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1295 *
1296 * But cHRM records only white-x and white-y, so we have lost the white scale
1297 * factor:
1298 *
1299 * white-C = white-c*white-scale
1300 *
1301 * To handle this the inverse transformation makes an arbitrary assumption
1302 * about white-scale:
1303 *
1304 * Assume: white-Y = 1.0
1305 * Hence: white-scale = 1/white-y
1306 * Or: red-Y + green-Y + blue-Y = 1.0
1307 *
1308 * Notice the last statement of the assumption gives an equation in three of
1309 * the nine values we want to calculate. 8 more equations come from the
1310 * above routine as summarised at the top above (the chromaticity
1311 * calculation):
1312 *
1313 * Given: color-x = color-X / (color-X + color-Y + color-Z)
1314 * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
1315 *
1316 * This is 9 simultaneous equations in the 9 variables "color-C" and can be
1317 * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
1318 * determinants, however this is not as bad as it seems because only 28 of
1319 * the total of 90 terms in the various matrices are non-zero. Nevertheless
1320 * Cramer's rule is notoriously numerically unstable because the determinant
1321 * calculation involves the difference of large, but similar, numbers. It is
1322 * difficult to be sure that the calculation is stable for real world values
1323 * and it is certain that it becomes unstable where the end points are close
1324 * together.
1325 *
1326 * So this code uses the perhaps slightly less optimal but more
1327 * understandable and totally obvious approach of calculating color-scale.
1328 *
1329 * This algorithm depends on the precision in white-scale and that is
1330 * (1/white-y), so we can immediately see that as white-y approaches 0 the
1331 * accuracy inherent in the cHRM chunk drops off substantially.
1332 *
1333 * libpng arithmetic: a simple inversion of the above equations
1334 * ------------------------------------------------------------
1335 *
1336 * white_scale = 1/white-y
1337 * white-X = white-x * white-scale
1338 * white-Y = 1.0
1339 * white-Z = (1 - white-x - white-y) * white_scale
1340 *
1341 * white-C = red-C + green-C + blue-C
1342 * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1343 *
1344 * This gives us three equations in (red-scale,green-scale,blue-scale) where
1345 * all the coefficients are now known:
1346 *
1347 * red-x*red-scale + green-x*green-scale + blue-x*blue-scale
1348 * = white-x/white-y
1349 * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
1350 * red-z*red-scale + green-z*green-scale + blue-z*blue-scale
1351 * = (1 - white-x - white-y)/white-y
1352 *
1353 * In the last equation color-z is (1 - color-x - color-y) so we can add all
1354 * three equations together to get an alternative third:
1355 *
1356 * red-scale + green-scale + blue-scale = 1/white-y = white-scale
1357 *
1358 * So now we have a Cramer's rule solution where the determinants are just
1359 * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
1360 * multiplication of three coefficients so we can't guarantee to avoid
1361 * overflow in the libpng fixed point representation. Using Cramer's rule in
1362 * floating point is probably a good choice here, but it's not an option for
1363 * fixed point. Instead proceed to simplify the first two equations by
1364 * eliminating what is likely to be the largest value, blue-scale:
1365 *
1366 * blue-scale = white-scale - red-scale - green-scale
1367 *
1368 * Hence:
1369 *
1370 * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
1371 * (white-x - blue-x)*white-scale
1372 *
1373 * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
1374 * 1 - blue-y*white-scale
1375 *
1376 * And now we can trivially solve for (red-scale,green-scale):
1377 *
1378 * green-scale =
1379 * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
1380 * -----------------------------------------------------------
1381 * green-x - blue-x
1382 *
1383 * red-scale =
1384 * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
1385 * ---------------------------------------------------------
1386 * red-y - blue-y
1387 *
1388 * Hence:
1389 *
1390 * red-scale =
1391 * ( (green-x - blue-x) * (white-y - blue-y) -
1392 * (green-y - blue-y) * (white-x - blue-x) ) / white-y
1393 * -------------------------------------------------------------------------
1394 * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1395 *
1396 * green-scale =
1397 * ( (red-y - blue-y) * (white-x - blue-x) -
1398 * (red-x - blue-x) * (white-y - blue-y) ) / white-y
1399 * -------------------------------------------------------------------------
1400 * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1401 *
1402 * Accuracy:
1403 * The input values have 5 decimal digits of accuracy. The values are all in
1404 * the range 0 < value < 1, so simple products are in the same range but may
1405 * need up to 10 decimal digits to preserve the original precision and avoid
1406 * underflow. Because we are using a 32-bit signed representation we cannot
1407 * match this; the best is a little over 9 decimal digits, less than 10.
1408 *
1409 * The approach used here is to preserve the maximum precision within the
1410 * signed representation. Because the red-scale calculation above uses the
1411 * difference between two products of values that must be in the range -1..+1
1412 * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
1413 * factor is irrelevant in the calculation because it is applied to both
1414 * numerator and denominator.
1415 *
1416 * Note that the values of the differences of the products of the
1417 * chromaticities in the above equations tend to be small, for example for
1418 * the sRGB chromaticities they are:
1419 *
1420 * red numerator: -0.04751
1421 * green numerator: -0.08788
1422 * denominator: -0.2241 (without white-y multiplication)
1423 *
1424 * The resultant Y coefficients from the chromaticities of some widely used
1425 * color space definitions are (to 15 decimal places):
1426 *
1427 * sRGB
1428 * 0.212639005871510 0.715168678767756 0.072192315360734
1429 * Kodak ProPhoto
1430 * 0.288071128229293 0.711843217810102 0.000085653960605
1431 * Adobe RGB
1432 * 0.297344975250536 0.627363566255466 0.075291458493998
1433 * Adobe Wide Gamut RGB
1434 * 0.258728243040113 0.724682314948566 0.016589442011321
1435 */
1436 /* By the argument, above overflow should be impossible here. The return
1437 * value of 2 indicates an internal error to the caller.
1438 */
1439 if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
1440 return 2;
1441 if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
1442 return 2;
1443 denominator = left - right;
1444
1445 /* Now find the red numerator. */
1446 if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
1447 return 2;
1448 if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
1449 return 2;
1450
1451 /* Overflow is possible here and it indicates an extreme set of PNG cHRM
1452 * chunk values. This calculation actually returns the reciprocal of the
1453 * scale value because this allows us to delay the multiplication of white-y
1454 * into the denominator, which tends to produce a small number.
1455 */
1456 if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
1457 red_inverse <= xy->whitey /* r+g+b scales = white scale */)
1458 return 1;
1459
1460 /* Similarly for green_inverse: */
1461 if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
1462 return 2;
1463 if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
1464 return 2;
1465 if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
1466 green_inverse <= xy->whitey)
1467 return 1;
1468
1469 /* And the blue scale, the checks above guarantee this can't overflow but it
1470 * can still produce 0 for extreme cHRM values.
1471 */
1472 blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
1473 png_reciprocal(green_inverse);
1474 if (blue_scale <= 0)
1475 return 1;
1476
1477
1478 /* And fill in the png_XYZ: */
1479 if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
1480 return 1;
1481 if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
1482 return 1;
1483 if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
1484 red_inverse) == 0)
1485 return 1;
1486
1487 if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
1488 return 1;
1489 if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
1490 return 1;
1491 if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
1492 green_inverse) == 0)
1493 return 1;
1494
1495 if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
1496 return 1;
1497 if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
1498 return 1;
1499 if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
1500 PNG_FP_1) == 0)
1501 return 1;
1502
1503 return 0; /*success*/
1504 }
1505
1506 static int
1507 png_XYZ_normalize(png_XYZ *XYZ)
1508 {
1509 png_int_32 Y;
1510
1511 if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
1512 XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
1513 XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
1514 return 1;
1515
1516 /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
1517 * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
1518 * relying on addition of two positive values producing a negative one is not
1519 * safe.
1520 */
1521 Y = XYZ->red_Y;
1522 if (0x7fffffff - Y < XYZ->green_X)
1523 return 1;
1524 Y += XYZ->green_Y;
1525 if (0x7fffffff - Y < XYZ->blue_X)
1526 return 1;
1527 Y += XYZ->blue_Y;
1528
1529 if (Y != PNG_FP_1)
1530 {
1531 if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
1532 return 1;
1533 if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
1534 return 1;
1535 if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
1536 return 1;
1537
1538 if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
1539 return 1;
1540 if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
1541 return 1;
1542 if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
1543 return 1;
1544
1545 if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
1546 return 1;
1547 if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
1548 return 1;
1549 if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
1550 return 1;
1551 }
1552
1553 return 0;
1554 }
1555
1556 static int
1557 png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
1558 {
1559 /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
1560 if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
1561 PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
1562 PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
1563 PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
1564 PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
1565 PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
1566 PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
1567 PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta))
1568 return 0;
1569 return 1;
1570 }
1571
1572 /* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
1573 * chunk chromaticities. Earlier checks used to simply look for the overflow
1574 * condition (where the determinant of the matrix to solve for XYZ ends up zero
1575 * because the chromaticity values are not all distinct.) Despite this it is
1576 * theoretically possible to produce chromaticities that are apparently valid
1577 * but that rapidly degrade to invalid, potentially crashing, sets because of
1578 * arithmetic inaccuracies when calculations are performed on them. The new
1579 * check is to round-trip xy -> XYZ -> xy and then check that the result is
1580 * within a small percentage of the original.
1581 */
1582 static int
1583 png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
1584 {
1585 int result;
1586 png_xy xy_test;
1587
1588 /* As a side-effect this routine also returns the XYZ endpoints. */
1589 result = png_XYZ_from_xy(XYZ, xy);
1590 if (result != 0)
1591 return result;
1592
1593 result = png_xy_from_XYZ(&xy_test, XYZ);
1594 if (result != 0)
1595 return result;
1596
1597 if (png_colorspace_endpoints_match(xy, &xy_test,
1598 5/*actually, the math is pretty accurate*/) != 0)
1599 return 0;
1600
1601 /* Too much slip */
1602 return 1;
1603 }
1604
1605 /* This is the check going the other way. The XYZ is modified to normalize it
1606 * (another side-effect) and the xy chromaticities are returned.
1607 */
1608 static int
1609 png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
1610 {
1611 int result;
1612 png_XYZ XYZtemp;
1613
1614 result = png_XYZ_normalize(XYZ);
1615 if (result != 0)
1616 return result;
1617
1618 result = png_xy_from_XYZ(xy, XYZ);
1619 if (result != 0)
1620 return result;
1621
1622 XYZtemp = *XYZ;
1623 return png_colorspace_check_xy(&XYZtemp, xy);
1624 }
1625
1626 /* Used to check for an endpoint match against sRGB */
1627 static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
1628 {
1629 /* color x y */
1630 /* red */ 64000, 33000,
1631 /* green */ 30000, 60000,
1632 /* blue */ 15000, 6000,
1633 /* white */ 31270, 32900
1634 };
1635
1636 static int
1637 png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
1638 png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
1639 int preferred)
1640 {
1641 if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1642 return 0;
1643
1644 /* The consistency check is performed on the chromaticities; this factors out
1645 * variations because of the normalization (or not) of the end point Y
1646 * values.
1647 */
1648 if (preferred < 2 &&
1649 (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
1650 {
1651 /* The end points must be reasonably close to any we already have. The
1652 * following allows an error of up to +/-.001
1653 */
1654 if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
1655 100) == 0)
1656 {
1657 colorspace->flags |= PNG_COLORSPACE_INVALID;
1658 png_benign_error(png_ptr, "inconsistent chromaticities");
1659 return 0; /* failed */
1660 }
1661
1662 /* Only overwrite with preferred values */
1663 if (preferred == 0)
1664 return 1; /* ok, but no change */
1665 }
1666
1667 colorspace->end_points_xy = *xy;
1668 colorspace->end_points_XYZ = *XYZ;
1669 colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
1670
1671 /* The end points are normally quoted to two decimal digits, so allow +/-0.01
1672 * on this test.
1673 */
1674 if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
1675 colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
1676
1677 else
1678 colorspace->flags &= PNG_COLORSPACE_CANCEL(
1679 PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
1680
1681 return 2; /* ok and changed */
1682 }
1683
1684 int /* PRIVATE */
1685 png_colorspace_set_chromaticities(png_const_structrp png_ptr,
1686 png_colorspacerp colorspace, const png_xy *xy, int preferred)
1687 {
1688 /* We must check the end points to ensure they are reasonable - in the past
1689 * color management systems have crashed as a result of getting bogus
1690 * colorant values, while this isn't the fault of libpng it is the
1691 * responsibility of libpng because PNG carries the bomb and libpng is in a
1692 * position to protect against it.
1693 */
1694 png_XYZ XYZ;
1695
1696 switch (png_colorspace_check_xy(&XYZ, xy))
1697 {
1698 case 0: /* success */
1699 return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
1700 preferred);
1701
1702 case 1:
1703 /* We can't invert the chromaticities so we can't produce value XYZ
1704 * values. Likely as not a color management system will fail too.
1705 */
1706 colorspace->flags |= PNG_COLORSPACE_INVALID;
1707 png_benign_error(png_ptr, "invalid chromaticities");
1708 break;
1709
1710 default:
1711 /* libpng is broken; this should be a warning but if it happens we
1712 * want error reports so for the moment it is an error.
1713 */
1714 colorspace->flags |= PNG_COLORSPACE_INVALID;
1715 png_error(png_ptr, "internal error checking chromaticities");
1716 }
1717
1718 return 0; /* failed */
1719 }
1720
1721 int /* PRIVATE */
1722 png_colorspace_set_endpoints(png_const_structrp png_ptr,
1723 png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
1724 {
1725 png_XYZ XYZ = *XYZ_in;
1726 png_xy xy;
1727
1728 switch (png_colorspace_check_XYZ(&xy, &XYZ))
1729 {
1730 case 0:
1731 return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
1732 preferred);
1733
1734 case 1:
1735 /* End points are invalid. */
1736 colorspace->flags |= PNG_COLORSPACE_INVALID;
1737 png_benign_error(png_ptr, "invalid end points");
1738 break;
1739
1740 default:
1741 colorspace->flags |= PNG_COLORSPACE_INVALID;
1742 png_error(png_ptr, "internal error checking chromaticities");
1743 }
1744
1745 return 0; /* failed */
1746 }
1747
1748 #if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
1749 /* Error message generation */
1750 static char
1751 png_icc_tag_char(png_uint_32 byte)
1752 {
1753 byte &= 0xff;
1754 if (byte >= 32 && byte <= 126)
1755 return (char)byte;
1756 else
1757 return '?';
1758 }
1759
1760 static void
1761 png_icc_tag_name(char *name, png_uint_32 tag)
1762 {
1763 name[0] = '\'';
1764 name[1] = png_icc_tag_char(tag >> 24);
1765 name[2] = png_icc_tag_char(tag >> 16);
1766 name[3] = png_icc_tag_char(tag >> 8);
1767 name[4] = png_icc_tag_char(tag );
1768 name[5] = '\'';
1769 }
1770
1771 static int
1772 is_ICC_signature_char(png_alloc_size_t it)
1773 {
1774 return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
1775 (it >= 97 && it <= 122);
1776 }
1777
1778 static int
1779 is_ICC_signature(png_alloc_size_t it)
1780 {
1781 return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
1782 is_ICC_signature_char((it >> 16) & 0xff) &&
1783 is_ICC_signature_char((it >> 8) & 0xff) &&
1784 is_ICC_signature_char(it & 0xff);
1785 }
1786
1787 static int
1788 png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
1789 png_const_charp name, png_alloc_size_t value, png_const_charp reason)
1790 {
1791 size_t pos;
1792 char message[196]; /* see below for calculation */
1793
1794 if (colorspace != NULL)
1795 colorspace->flags |= PNG_COLORSPACE_INVALID;
1796
1797 pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
1798 pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
1799 pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
1800 if (is_ICC_signature(value) != 0)
1801 {
1802 /* So 'value' is at most 4 bytes and the following cast is safe */
1803 png_icc_tag_name(message+pos, (png_uint_32)value);
1804 pos += 6; /* total +8; less than the else clause */
1805 message[pos++] = ':';
1806 message[pos++] = ' ';
1807 }
1808 # ifdef PNG_WARNINGS_SUPPORTED
1809 else
1810 {
1811 char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
1812
1813 pos = png_safecat(message, (sizeof message), pos,
1814 png_format_number(number, number+(sizeof number),
1815 PNG_NUMBER_FORMAT_x, value));
1816 pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
1817 }
1818 # endif
1819 /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
1820 pos = png_safecat(message, (sizeof message), pos, reason);
1821 PNG_UNUSED(pos)
1822
1823 /* This is recoverable, but make it unconditionally an app_error on write to
1824 * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
1825 * on read, with a warning, but on write unless the app turns off
1826 * application errors the PNG won't be written.)
1827 */
1828 png_chunk_report(png_ptr, message,
1829 (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
1830
1831 return 0;
1832 }
1833 #endif /* sRGB || iCCP */
1834
1835 #ifdef PNG_sRGB_SUPPORTED
1836 int /* PRIVATE */
1837 png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
1838 int intent)
1839 {
1840 /* sRGB sets known gamma, end points and (from the chunk) intent. */
1841 /* IMPORTANT: these are not necessarily the values found in an ICC profile
1842 * because ICC profiles store values adapted to a D50 environment; it is
1843 * expected that the ICC profile mediaWhitePointTag will be D50; see the
1844 * checks and code elsewhere to understand this better.
1845 *
1846 * These XYZ values, which are accurate to 5dp, produce rgb to gray
1847 * coefficients of (6968,23435,2366), which are reduced (because they add up
1848 * to 32769 not 32768) to (6968,23434,2366). These are the values that
1849 * libpng has traditionally used (and are the best values given the 15bit
1850 * algorithm used by the rgb to gray code.)
1851 */
1852 static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
1853 {
1854 /* color X Y Z */
1855 /* red */ 41239, 21264, 1933,
1856 /* green */ 35758, 71517, 11919,
1857 /* blue */ 18048, 7219, 95053
1858 };
1859
1860 /* Do nothing if the colorspace is already invalidated. */
1861 if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1862 return 0;
1863
1864 /* Check the intent, then check for existing settings. It is valid for the
1865 * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
1866 * be consistent with the correct values. If, however, this function is
1867 * called below because an iCCP chunk matches sRGB then it is quite
1868 * conceivable that an older app recorded incorrect gAMA and cHRM because of
1869 * an incorrect calculation based on the values in the profile - this does
1870 * *not* invalidate the profile (though it still produces an error, which can
1871 * be ignored.)
1872 */
1873 if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
1874 return png_icc_profile_error(png_ptr, colorspace, "sRGB",
1875 (unsigned)intent, "invalid sRGB rendering intent");
1876
1877 if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
1878 colorspace->rendering_intent != intent)
1879 return png_icc_profile_error(png_ptr, colorspace, "sRGB",
1880 (unsigned)intent, "inconsistent rendering intents");
1881
1882 if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
1883 {
1884 png_benign_error(png_ptr, "duplicate sRGB information ignored");
1885 return 0;
1886 }
1887
1888 /* If the standard sRGB cHRM chunk does not match the one from the PNG file
1889 * warn but overwrite the value with the correct one.
1890 */
1891 if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
1892 !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
1893 100))
1894 png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
1895 PNG_CHUNK_ERROR);
1896
1897 /* This check is just done for the error reporting - the routine always
1898 * returns true when the 'from' argument corresponds to sRGB (2).
1899 */
1900 (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
1901 2/*from sRGB*/);
1902
1903 /* intent: bugs in GCC force 'int' to be used as the parameter type. */
1904 colorspace->rendering_intent = (png_uint_16)intent;
1905 colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
1906
1907 /* endpoints */
1908 colorspace->end_points_xy = sRGB_xy;
1909 colorspace->end_points_XYZ = sRGB_XYZ;
1910 colorspace->flags |=
1911 (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
1912
1913 /* gamma */
1914 colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
1915 colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
1916
1917 /* Finally record that we have an sRGB profile */
1918 colorspace->flags |=
1919 (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
1920
1921 return 1; /* set */
1922 }
1923 #endif /* sRGB */
1924
1925 #ifdef PNG_iCCP_SUPPORTED
1926 /* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
1927 * is XYZ(0.9642,1.0,0.8249), which scales to:
1928 *
1929 * (63189.8112, 65536, 54060.6464)
1930 */
1931 static const png_byte D50_nCIEXYZ[12] =
1932 { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
1933
1934 int /* PRIVATE */
1935 png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
1936 png_const_charp name, png_uint_32 profile_length)
1937 {
1938 if (profile_length < 132)
1939 return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
1940 "too short");
1941
1942 return 1;
1943 }
1944
1945 int /* PRIVATE */
1946 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
1947 png_const_charp name, png_uint_32 profile_length,
1948 png_const_bytep profile/* first 132 bytes only */, int color_type)
1949 {
1950 png_uint_32 temp;
1951
1952 /* Length check; this cannot be ignored in this code because profile_length
1953 * is used later to check the tag table, so even if the profile seems over
1954 * long profile_length from the caller must be correct. The caller can fix
1955 * this up on read or write by just passing in the profile header length.
1956 */
1957 temp = png_get_uint_32(profile);
1958 if (temp != profile_length)
1959 return png_icc_profile_error(png_ptr, colorspace, name, temp,
1960 "length does not match profile");
1961
1962 temp = (png_uint_32) (*(profile+8));
1963 if (temp > 3 && (profile_length & 3))
1964 return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
1965 "invalid length");
1966
1967 temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
1968 if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
1969 profile_length < 132+12*temp) /* truncated tag table */
1970 return png_icc_profile_error(png_ptr, colorspace, name, temp,
1971 "tag count too large");
1972
1973 /* The 'intent' must be valid or we can't store it, ICC limits the intent to
1974 * 16 bits.
1975 */
1976 temp = png_get_uint_32(profile+64);
1977 if (temp >= 0xffff) /* The ICC limit */
1978 return png_icc_profile_error(png_ptr, colorspace, name, temp,
1979 "invalid rendering intent");
1980
1981 /* This is just a warning because the profile may be valid in future
1982 * versions.
1983 */
1984 if (temp >= PNG_sRGB_INTENT_LAST)
1985 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
1986 "intent outside defined range");
1987
1988 /* At this point the tag table can't be checked because it hasn't necessarily
1989 * been loaded; however, various header fields can be checked. These checks
1990 * are for values permitted by the PNG spec in an ICC profile; the PNG spec
1991 * restricts the profiles that can be passed in an iCCP chunk (they must be
1992 * appropriate to processing PNG data!)
1993 */
1994
1995 /* Data checks (could be skipped). These checks must be independent of the
1996 * version number; however, the version number doesn't accomodate changes in
1997 * the header fields (just the known tags and the interpretation of the
1998 * data.)
1999 */
2000 temp = png_get_uint_32(profile+36); /* signature 'ascp' */
2001 if (temp != 0x61637370)
2002 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2003 "invalid signature");
2004
2005 /* Currently the PCS illuminant/adopted white point (the computational
2006 * white point) are required to be D50,
2007 * however the profile contains a record of the illuminant so perhaps ICC
2008 * expects to be able to change this in the future (despite the rationale in
2009 * the introduction for using a fixed PCS adopted white.) Consequently the
2010 * following is just a warning.
2011 */
2012 if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
2013 (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
2014 "PCS illuminant is not D50");
2015
2016 /* The PNG spec requires this:
2017 * "If the iCCP chunk is present, the image samples conform to the colour
2018 * space represented by the embedded ICC profile as defined by the
2019 * International Color Consortium [ICC]. The colour space of the ICC profile
2020 * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
2021 * 6), or a greyscale colour space for greyscale images (PNG colour types 0
2022 * and 4)."
2023 *
2024 * This checking code ensures the embedded profile (on either read or write)
2025 * conforms to the specification requirements. Notice that an ICC 'gray'
2026 * color-space profile contains the information to transform the monochrome
2027 * data to XYZ or L*a*b (according to which PCS the profile uses) and this
2028 * should be used in preference to the standard libpng K channel replication
2029 * into R, G and B channels.
2030 *
2031 * Previously it was suggested that an RGB profile on grayscale data could be
2032 * handled. However it it is clear that using an RGB profile in this context
2033 * must be an error - there is no specification of what it means. Thus it is
2034 * almost certainly more correct to ignore the profile.
2035 */
2036 temp = png_get_uint_32(profile+16); /* data colour space field */
2037 switch (temp)
2038 {
2039 case 0x52474220: /* 'RGB ' */
2040 if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
2041 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2042 "RGB color space not permitted on grayscale PNG");
2043 break;
2044
2045 case 0x47524159: /* 'GRAY' */
2046 if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
2047 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2048 "Gray color space not permitted on RGB PNG");
2049 break;
2050
2051 default:
2052 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2053 "invalid ICC profile color space");
2054 }
2055
2056 /* It is up to the application to check that the profile class matches the
2057 * application requirements; the spec provides no guidance, but it's pretty
2058 * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
2059 * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these
2060 * cases. Issue an error for device link or abstract profiles - these don't
2061 * contain the records necessary to transform the color-space to anything
2062 * other than the target device (and not even that for an abstract profile).
2063 * Profiles of these classes may not be embedded in images.
2064 */
2065 temp = png_get_uint_32(profile+12); /* profile/device class */
2066 switch (temp)
2067 {
2068 case 0x73636e72: /* 'scnr' */
2069 case 0x6d6e7472: /* 'mntr' */
2070 case 0x70727472: /* 'prtr' */
2071 case 0x73706163: /* 'spac' */
2072 /* All supported */
2073 break;
2074
2075 case 0x61627374: /* 'abst' */
2076 /* May not be embedded in an image */
2077 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2078 "invalid embedded Abstract ICC profile");
2079
2080 case 0x6c696e6b: /* 'link' */
2081 /* DeviceLink profiles cannot be interpreted in a non-device specific
2082 * fashion, if an app uses the AToB0Tag in the profile the results are
2083 * undefined unless the result is sent to the intended device,
2084 * therefore a DeviceLink profile should not be found embedded in a
2085 * PNG.
2086 */
2087 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2088 "unexpected DeviceLink ICC profile class");
2089
2090 case 0x6e6d636c: /* 'nmcl' */
2091 /* A NamedColor profile is also device specific, however it doesn't
2092 * contain an AToB0 tag that is open to misinterpretation. Almost
2093 * certainly it will fail the tests below.
2094 */
2095 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
2096 "unexpected NamedColor ICC profile class");
2097 break;
2098
2099 default:
2100 /* To allow for future enhancements to the profile accept unrecognized
2101 * profile classes with a warning, these then hit the test below on the
2102 * tag content to ensure they are backward compatible with one of the
2103 * understood profiles.
2104 */
2105 (void)png_icc_profile_error(png_ptr, NULL, name, temp,
2106 "unrecognized ICC profile class");
2107 break;
2108 }
2109
2110 /* For any profile other than a device link one the PCS must be encoded
2111 * either in XYZ or Lab.
2112 */
2113 temp = png_get_uint_32(profile+20);
2114 switch (temp)
2115 {
2116 case 0x58595a20: /* 'XYZ ' */
2117 case 0x4c616220: /* 'Lab ' */
2118 break;
2119
2120 default:
2121 return png_icc_profile_error(png_ptr, colorspace, name, temp,
2122 "unexpected ICC PCS encoding");
2123 }
2124
2125 return 1;
2126 }
2127
2128 int /* PRIVATE */
2129 png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
2130 png_const_charp name, png_uint_32 profile_length,
2131 png_const_bytep profile /* header plus whole tag table */)
2132 {
2133 png_uint_32 tag_count = png_get_uint_32(profile+128);
2134 png_uint_32 itag;
2135 png_const_bytep tag = profile+132; /* The first tag */
2136
2137 /* First scan all the tags in the table and add bits to the icc_info value
2138 * (temporarily in 'tags').
2139 */
2140 for (itag=0; itag < tag_count; ++itag, tag += 12)
2141 {
2142 png_uint_32 tag_id = png_get_uint_32(tag+0);
2143 png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
2144 png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
2145
2146 /* The ICC specification does not exclude zero length tags, therefore the
2147 * start might actually be anywhere if there is no data, but this would be
2148 * a clear abuse of the intent of the standard so the start is checked for
2149 * being in range. All defined tag types have an 8 byte header - a 4 byte
2150 * type signature then 0.
2151 */
2152 if ((tag_start & 3) != 0)
2153 {
2154 /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
2155 * only a warning here because libpng does not care about the
2156 * alignment.
2157 */
2158 (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
2159 "ICC profile tag start not a multiple of 4");
2160 }
2161
2162 /* This is a hard error; potentially it can cause read outside the
2163 * profile.
2164 */
2165 if (tag_start > profile_length || tag_length > profile_length - tag_start)
2166 return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
2167 "ICC profile tag outside profile");
2168 }
2169
2170 return 1; /* success, maybe with warnings */
2171 }
2172
2173 #ifdef PNG_sRGB_SUPPORTED
2174 #if PNG_sRGB_PROFILE_CHECKS >= 0
2175 /* Information about the known ICC sRGB profiles */
2176 static const struct
2177 {
2178 png_uint_32 adler, crc, length;
2179 png_uint_32 md5[4];
2180 png_byte have_md5;
2181 png_byte is_broken;
2182 png_uint_16 intent;
2183
2184 # define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
2185 # define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
2186 { adler, crc, length, md5, broke, intent },
2187
2188 } png_sRGB_checks[] =
2189 {
2190 /* This data comes from contrib/tools/checksum-icc run on downloads of
2191 * all four ICC sRGB profiles from www.color.org.
2192 */
2193 /* adler32, crc32, MD5[4], intent, date, length, file-name */
2194 PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
2195 PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
2196 "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
2197
2198 /* ICC sRGB v2 perceptual no black-compensation: */
2199 PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
2200 PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
2201 "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
2202
2203 PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
2204 PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
2205 "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
2206
2207 /* ICC sRGB v4 perceptual */
2208 PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
2209 PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
2210 "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
2211
2212 /* The following profiles have no known MD5 checksum. If there is a match
2213 * on the (empty) MD5 the other fields are used to attempt a match and
2214 * a warning is produced. The first two of these profiles have a 'cprt' tag
2215 * which suggests that they were also made by Hewlett Packard.
2216 */
2217 PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
2218 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
2219 "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
2220
2221 /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
2222 * match the D50 PCS illuminant in the header (it is in fact the D65 values,
2223 * so the white point is recorded as the un-adapted value.) The profiles
2224 * below only differ in one byte - the intent - and are basically the same as
2225 * the previous profile except for the mediaWhitePointTag error and a missing
2226 * chromaticAdaptationTag.
2227 */
2228 PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
2229 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
2230 "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
2231
2232 PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
2233 PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
2234 "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
2235 };
2236
2237 static int
2238 png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
2239 png_const_bytep profile, uLong adler)
2240 {
2241 /* The quick check is to verify just the MD5 signature and trust the
2242 * rest of the data. Because the profile has already been verified for
2243 * correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
2244 * field too, so if the profile has been edited with an intent not defined
2245 * by sRGB (but maybe defined by a later ICC specification) the read of
2246 * the profile will fail at that point.
2247 */
2248
2249 png_uint_32 length = 0;
2250 png_uint_32 intent = 0x10000; /* invalid */
2251 #if PNG_sRGB_PROFILE_CHECKS > 1
2252 uLong crc = 0; /* the value for 0 length data */
2253 #endif
2254 unsigned int i;
2255
2256 #ifdef PNG_SET_OPTION_SUPPORTED
2257 /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
2258 if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
2259 PNG_OPTION_ON)
2260 return 0;
2261 #endif
2262
2263 for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
2264 {
2265 if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
2266 png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
2267 png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
2268 png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
2269 {
2270 /* This may be one of the old HP profiles without an MD5, in that
2271 * case we can only use the length and Adler32 (note that these
2272 * are not used by default if there is an MD5!)
2273 */
2274 # if PNG_sRGB_PROFILE_CHECKS == 0
2275 if (png_sRGB_checks[i].have_md5 != 0)
2276 return 1+png_sRGB_checks[i].is_broken;
2277 # endif
2278
2279 /* Profile is unsigned or more checks have been configured in. */
2280 if (length == 0)
2281 {
2282 length = png_get_uint_32(profile);
2283 intent = png_get_uint_32(profile+64);
2284 }
2285
2286 /* Length *and* intent must match */
2287 if (length == (png_uint_32) png_sRGB_checks[i].length &&
2288 intent == (png_uint_32) png_sRGB_checks[i].intent)
2289 {
2290 /* Now calculate the adler32 if not done already. */
2291 if (adler == 0)
2292 {
2293 adler = adler32(0, NULL, 0);
2294 adler = adler32(adler, profile, length);
2295 }
2296
2297 if (adler == png_sRGB_checks[i].adler)
2298 {
2299 /* These basic checks suggest that the data has not been
2300 * modified, but if the check level is more than 1 perform
2301 * our own crc32 checksum on the data.
2302 */
2303 # if PNG_sRGB_PROFILE_CHECKS > 1
2304 if (crc == 0)
2305 {
2306 crc = crc32(0, NULL, 0);
2307 crc = crc32(crc, profile, length);
2308 }
2309
2310 /* So this check must pass for the 'return' below to happen.
2311 */
2312 if (crc == png_sRGB_checks[i].crc)
2313 # endif
2314 {
2315 if (png_sRGB_checks[i].is_broken != 0)
2316 {
2317 /* These profiles are known to have bad data that may cause
2318 * problems if they are used, therefore attempt to
2319 * discourage their use, skip the 'have_md5' warning below,
2320 * which is made irrelevant by this error.
2321 */
2322 png_chunk_report(png_ptr, "known incorrect sRGB profile",
2323 PNG_CHUNK_ERROR);
2324 }
2325
2326 /* Warn that this being done; this isn't even an error since
2327 * the profile is perfectly valid, but it would be nice if
2328 * people used the up-to-date ones.
2329 */
2330 else if (png_sRGB_checks[i].have_md5 == 0)
2331 {
2332 png_chunk_report(png_ptr,
2333 "out-of-date sRGB profile with no signature",
2334 PNG_CHUNK_WARNING);
2335 }
2336
2337 return 1+png_sRGB_checks[i].is_broken;
2338 }
2339 }
2340
2341 # if PNG_sRGB_PROFILE_CHECKS > 0
2342 /* The signature matched, but the profile had been changed in some
2343 * way. This probably indicates a data error or uninformed hacking.
2344 * Fall through to "no match".
2345 */
2346 png_chunk_report(png_ptr,
2347 "Not recognizing known sRGB profile that has been edited",
2348 PNG_CHUNK_WARNING);
2349 break;
2350 # endif
2351 }
2352 }
2353 }
2354
2355 return 0; /* no match */
2356 }
2357 #endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
2358
2359 void /* PRIVATE */
2360 png_icc_set_sRGB(png_const_structrp png_ptr,
2361 png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
2362 {
2363 /* Is this profile one of the known ICC sRGB profiles? If it is, just set
2364 * the sRGB information.
2365 */
2366 #if PNG_sRGB_PROFILE_CHECKS >= 0
2367 if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
2368 #endif
2369 (void)png_colorspace_set_sRGB(png_ptr, colorspace,
2370 (int)/*already checked*/png_get_uint_32(profile+64));
2371 }
2372 #endif /* sRGB */
2373
2374 int /* PRIVATE */
2375 png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
2376 png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
2377 int color_type)
2378 {
2379 if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
2380 return 0;
2381
2382 if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
2383 png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
2384 color_type) != 0 &&
2385 png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
2386 profile) != 0)
2387 {
2388 # ifdef PNG_sRGB_SUPPORTED
2389 /* If no sRGB support, don't try storing sRGB information */
2390 png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
2391 # endif
2392 return 1;
2393 }
2394
2395 /* Failure case */
2396 return 0;
2397 }
2398 #endif /* iCCP */
2399
2400 #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
2401 void /* PRIVATE */
2402 png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
2403 {
2404 /* Set the rgb_to_gray coefficients from the colorspace. */
2405 if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
2406 (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
2407 {
2408 /* png_set_background has not been called, get the coefficients from the Y
2409 * values of the colorspace colorants.
2410 */
2411 png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
2412 png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
2413 png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
2414 png_fixed_point total = r+g+b;
2415
2416 if (total > 0 &&
2417 r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
2418 g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
2419 b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
2420 r+g+b <= 32769)
2421 {
2422 /* We allow 0 coefficients here. r+g+b may be 32769 if two or
2423 * all of the coefficients were rounded up. Handle this by
2424 * reducing the *largest* coefficient by 1; this matches the
2425 * approach used for the default coefficients in pngrtran.c
2426 */
2427 int add = 0;
2428
2429 if (r+g+b > 32768)
2430 add = -1;
2431 else if (r+g+b < 32768)
2432 add = 1;
2433
2434 if (add != 0)
2435 {
2436 if (g >= r && g >= b)
2437 g += add;
2438 else if (r >= g && r >= b)
2439 r += add;
2440 else
2441 b += add;
2442 }
2443
2444 /* Check for an internal error. */
2445 if (r+g+b != 32768)
2446 png_error(png_ptr,
2447 "internal error handling cHRM coefficients");
2448
2449 else
2450 {
2451 png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
2452 png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
2453 }
2454 }
2455
2456 /* This is a png_error at present even though it could be ignored -
2457 * it should never happen, but it is important that if it does, the
2458 * bug is fixed.
2459 */
2460 else
2461 png_error(png_ptr, "internal error handling cHRM->XYZ");
2462 }
2463 }
2464 #endif /* READ_RGB_TO_GRAY */
2465
2466 #endif /* COLORSPACE */
2467
2468 #ifdef __GNUC__
2469 /* This exists solely to work round a warning from GNU C. */
2470 static int /* PRIVATE */
2471 png_gt(size_t a, size_t b)
2472 {
2473 return a > b;
2474 }
2475 #else
2476 # define png_gt(a,b) ((a) > (b))
2477 #endif
2478
2479 void /* PRIVATE */
2480 png_check_IHDR(png_const_structrp png_ptr,
2481 png_uint_32 width, png_uint_32 height, int bit_depth,
2482 int color_type, int interlace_type, int compression_type,
2483 int filter_type)
2484 {
2485 int error = 0;
2486
2487 /* Check for width and height valid values */
2488 if (width == 0)
2489 {
2490 png_warning(png_ptr, "Image width is zero in IHDR");
2491 error = 1;
2492 }
2493
2494 if (width > PNG_UINT_31_MAX)
2495 {
2496 png_warning(png_ptr, "Invalid image width in IHDR");
2497 error = 1;
2498 }
2499
2500 if (png_gt(((width + 7) & (~7)),
2501 ((PNG_SIZE_MAX
2502 - 48 /* big_row_buf hack */
2503 - 1) /* filter byte */
2504 / 8) /* 8-byte RGBA pixels */
2505 - 1)) /* extra max_pixel_depth pad */
2506 {
2507 /* The size of the row must be within the limits of this architecture.
2508 * Because the read code can perform arbitrary transformations the
2509 * maximum size is checked here. Because the code in png_read_start_row
2510 * adds extra space "for safety's sake" in several places a conservative
2511 * limit is used here.
2512 *
2513 * NOTE: it would be far better to check the size that is actually used,
2514 * but the effect in the real world is minor and the changes are more
2515 * extensive, therefore much more dangerous and much more difficult to
2516 * write in a way that avoids compiler warnings.
2517 */
2518 png_warning(png_ptr, "Image width is too large for this architecture");
2519 error = 1;
2520 }
2521
2522 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
2523 if (width > png_ptr->user_width_max)
2524 #else
2525 if (width > PNG_USER_WIDTH_MAX)
2526 #endif
2527 {
2528 png_warning(png_ptr, "Image width exceeds user limit in IHDR");
2529 error = 1;
2530 }
2531
2532 if (height == 0)
2533 {
2534 png_warning(png_ptr, "Image height is zero in IHDR");
2535 error = 1;
2536 }
2537
2538 if (height > PNG_UINT_31_MAX)
2539 {
2540 png_warning(png_ptr, "Invalid image height in IHDR");
2541 error = 1;
2542 }
2543
2544 #ifdef PNG_SET_USER_LIMITS_SUPPORTED
2545 if (height > png_ptr->user_height_max)
2546 #else
2547 if (height > PNG_USER_HEIGHT_MAX)
2548 #endif
2549 {
2550 png_warning(png_ptr, "Image height exceeds user limit in IHDR");
2551 error = 1;
2552 }
2553
2554 /* Check other values */
2555 if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
2556 bit_depth != 8 && bit_depth != 16)
2557 {
2558 png_warning(png_ptr, "Invalid bit depth in IHDR");
2559 error = 1;
2560 }
2561
2562 if (color_type < 0 || color_type == 1 ||
2563 color_type == 5 || color_type > 6)
2564 {
2565 png_warning(png_ptr, "Invalid color type in IHDR");
2566 error = 1;
2567 }
2568
2569 if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
2570 ((color_type == PNG_COLOR_TYPE_RGB ||
2571 color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
2572 color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
2573 {
2574 png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
2575 error = 1;
2576 }
2577
2578 if (interlace_type >= PNG_INTERLACE_LAST)
2579 {
2580 png_warning(png_ptr, "Unknown interlace method in IHDR");
2581 error = 1;
2582 }
2583
2584 if (compression_type != PNG_COMPRESSION_TYPE_BASE)
2585 {
2586 png_warning(png_ptr, "Unknown compression method in IHDR");
2587 error = 1;
2588 }
2589
2590 #ifdef PNG_MNG_FEATURES_SUPPORTED
2591 /* Accept filter_method 64 (intrapixel differencing) only if
2592 * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
2593 * 2. Libpng did not read a PNG signature (this filter_method is only
2594 * used in PNG datastreams that are embedded in MNG datastreams) and
2595 * 3. The application called png_permit_mng_features with a mask that
2596 * included PNG_FLAG_MNG_FILTER_64 and
2597 * 4. The filter_method is 64 and
2598 * 5. The color_type is RGB or RGBA
2599 */
2600 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
2601 png_ptr->mng_features_permitted != 0)
2602 png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
2603
2604 if (filter_type != PNG_FILTER_TYPE_BASE)
2605 {
2606 if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
2607 (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
2608 ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
2609 (color_type == PNG_COLOR_TYPE_RGB ||
2610 color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
2611 {
2612 png_warning(png_ptr, "Unknown filter method in IHDR");
2613 error = 1;
2614 }
2615
2616 if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
2617 {
2618 png_warning(png_ptr, "Invalid filter method in IHDR");
2619 error = 1;
2620 }
2621 }
2622
2623 #else
2624 if (filter_type != PNG_FILTER_TYPE_BASE)
2625 {
2626 png_warning(png_ptr, "Unknown filter method in IHDR");
2627 error = 1;
2628 }
2629 #endif
2630
2631 if (error == 1)
2632 png_error(png_ptr, "Invalid IHDR data");
2633 }
2634
2635 #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
2636 /* ASCII to fp functions */
2637 /* Check an ASCII formated floating point value, see the more detailed
2638 * comments in pngpriv.h
2639 */
2640 /* The following is used internally to preserve the sticky flags */
2641 #define png_fp_add(state, flags) ((state) |= (flags))
2642 #define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
2643
2644 int /* PRIVATE */
2645 png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
2646 png_size_tp whereami)
2647 {
2648 int state = *statep;
2649 png_size_t i = *whereami;
2650
2651 while (i < size)
2652 {
2653 int type;
2654 /* First find the type of the next character */
2655 switch (string[i])
2656 {
2657 case 43: type = PNG_FP_SAW_SIGN; break;
2658 case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
2659 case 46: type = PNG_FP_SAW_DOT; break;
2660 case 48: type = PNG_FP_SAW_DIGIT; break;
2661 case 49: case 50: case 51: case 52:
2662 case 53: case 54: case 55: case 56:
2663 case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
2664 case 69:
2665 case 101: type = PNG_FP_SAW_E; break;
2666 default: goto PNG_FP_End;
2667 }
2668
2669 /* Now deal with this type according to the current
2670 * state, the type is arranged to not overlap the
2671 * bits of the PNG_FP_STATE.
2672 */
2673 switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
2674 {
2675 case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
2676 if ((state & PNG_FP_SAW_ANY) != 0)
2677 goto PNG_FP_End; /* not a part of the number */
2678
2679 png_fp_add(state, type);
2680 break;
2681
2682 case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
2683 /* Ok as trailer, ok as lead of fraction. */
2684 if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
2685 goto PNG_FP_End;
2686
2687 else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
2688 png_fp_add(state, type);
2689
2690 else
2691 png_fp_set(state, PNG_FP_FRACTION | type);
2692
2693 break;
2694
2695 case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
2696 if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
2697 png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
2698
2699 png_fp_add(state, type | PNG_FP_WAS_VALID);
2700
2701 break;
2702
2703 case PNG_FP_INTEGER + PNG_FP_SAW_E:
2704 if ((state & PNG_FP_SAW_DIGIT) == 0)
2705 goto PNG_FP_End;
2706
2707 png_fp_set(state, PNG_FP_EXPONENT);
2708
2709 break;
2710
2711 /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
2712 goto PNG_FP_End; ** no sign in fraction */
2713
2714 /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
2715 goto PNG_FP_End; ** Because SAW_DOT is always set */
2716
2717 case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
2718 png_fp_add(state, type | PNG_FP_WAS_VALID);
2719 break;
2720
2721 case PNG_FP_FRACTION + PNG_FP_SAW_E:
2722 /* This is correct because the trailing '.' on an
2723 * integer is handled above - so we can only get here
2724 * with the sequence ".E" (with no preceding digits).
2725 */
2726 if ((state & PNG_FP_SAW_DIGIT) == 0)
2727 goto PNG_FP_End;
2728
2729 png_fp_set(state, PNG_FP_EXPONENT);
2730
2731 break;
2732
2733 case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
2734 if ((state & PNG_FP_SAW_ANY) != 0)
2735 goto PNG_FP_End; /* not a part of the number */
2736
2737 png_fp_add(state, PNG_FP_SAW_SIGN);
2738
2739 break;
2740
2741 /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
2742 goto PNG_FP_End; */
2743
2744 case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
2745 png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
2746
2747 break;
2748
2749 /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
2750 goto PNG_FP_End; */
2751
2752 default: goto PNG_FP_End; /* I.e. break 2 */
2753 }
2754
2755 /* The character seems ok, continue. */
2756 ++i;
2757 }
2758
2759 PNG_FP_End:
2760 /* Here at the end, update the state and return the correct
2761 * return code.
2762 */
2763 *statep = state;
2764 *whereami = i;
2765
2766 return (state & PNG_FP_SAW_DIGIT) != 0;
2767 }
2768
2769
2770 /* The same but for a complete string. */
2771 int
2772 png_check_fp_string(png_const_charp string, png_size_t size)
2773 {
2774 int state=0;
2775 png_size_t char_index=0;
2776
2777 if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
2778 (char_index == size || string[char_index] == 0))
2779 return state /* must be non-zero - see above */;
2780
2781 return 0; /* i.e. fail */
2782 }
2783 #endif /* pCAL || sCAL */
2784
2785 #ifdef PNG_sCAL_SUPPORTED
2786 # ifdef PNG_FLOATING_POINT_SUPPORTED
2787 /* Utility used below - a simple accurate power of ten from an integral
2788 * exponent.
2789 */
2790 static double
2791 png_pow10(int power)
2792 {
2793 int recip = 0;
2794 double d = 1;
2795
2796 /* Handle negative exponent with a reciprocal at the end because
2797 * 10 is exact whereas .1 is inexact in base 2
2798 */
2799 if (power < 0)
2800 {
2801 if (power < DBL_MIN_10_EXP) return 0;
2802 recip = 1, power = -power;
2803 }
2804
2805 if (power > 0)
2806 {
2807 /* Decompose power bitwise. */
2808 double mult = 10;
2809 do
2810 {
2811 if (power & 1) d *= mult;
2812 mult *= mult;
2813 power >>= 1;
2814 }
2815 while (power > 0);
2816
2817 if (recip != 0) d = 1/d;
2818 }
2819 /* else power is 0 and d is 1 */
2820
2821 return d;
2822 }
2823
2824 /* Function to format a floating point value in ASCII with a given
2825 * precision.
2826 */
2827 void /* PRIVATE */
2828 png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
2829 double fp, unsigned int precision)
2830 {
2831 /* We use standard functions from math.h, but not printf because
2832 * that would require stdio. The caller must supply a buffer of
2833 * sufficient size or we will png_error. The tests on size and
2834 * the space in ascii[] consumed are indicated below.
2835 */
2836 if (precision < 1)
2837 precision = DBL_DIG;
2838
2839 /* Enforce the limit of the implementation precision too. */
2840 if (precision > DBL_DIG+1)
2841 precision = DBL_DIG+1;
2842
2843 /* Basic sanity checks */
2844 if (size >= precision+5) /* See the requirements below. */
2845 {
2846 if (fp < 0)
2847 {
2848 fp = -fp;
2849 *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */
2850 --size;
2851 }
2852
2853 if (fp >= DBL_MIN && fp <= DBL_MAX)
2854 {
2855 int exp_b10; /* A base 10 exponent */
2856 double base; /* 10^exp_b10 */
2857
2858 /* First extract a base 10 exponent of the number,
2859 * the calculation below rounds down when converting
2860 * from base 2 to base 10 (multiply by log10(2) -
2861 * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
2862 * be increased. Note that the arithmetic shift
2863 * performs a floor() unlike C arithmetic - using a
2864 * C multiply would break the following for negative
2865 * exponents.
2866 */
2867 (void)frexp(fp, &exp_b10); /* exponent to base 2 */
2868
2869 exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
2870
2871 /* Avoid underflow here. */
2872 base = png_pow10(exp_b10); /* May underflow */
2873
2874 while (base < DBL_MIN || base < fp)
2875 {
2876 /* And this may overflow. */
2877 double test = png_pow10(exp_b10+1);
2878
2879 if (test <= DBL_MAX)
2880 ++exp_b10, base = test;
2881
2882 else
2883 break;
2884 }
2885
2886 /* Normalize fp and correct exp_b10, after this fp is in the
2887 * range [.1,1) and exp_b10 is both the exponent and the digit
2888 * *before* which the decimal point should be inserted
2889 * (starting with 0 for the first digit). Note that this
2890 * works even if 10^exp_b10 is out of range because of the
2891 * test on DBL_MAX above.
2892 */
2893 fp /= base;
2894 while (fp >= 1) fp /= 10, ++exp_b10;
2895
2896 /* Because of the code above fp may, at this point, be
2897 * less than .1, this is ok because the code below can
2898 * handle the leading zeros this generates, so no attempt
2899 * is made to correct that here.
2900 */
2901
2902 {
2903 unsigned int czero, clead, cdigits;
2904 char exponent[10];
2905
2906 /* Allow up to two leading zeros - this will not lengthen
2907 * the number compared to using E-n.
2908 */
2909 if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
2910 {
2911 czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
2912 exp_b10 = 0; /* Dot added below before first output. */
2913 }
2914 else
2915 czero = 0; /* No zeros to add */
2916
2917 /* Generate the digit list, stripping trailing zeros and
2918 * inserting a '.' before a digit if the exponent is 0.
2919 */
2920 clead = czero; /* Count of leading zeros */
2921 cdigits = 0; /* Count of digits in list. */
2922
2923 do
2924 {
2925 double d;
2926
2927 fp *= 10;
2928 /* Use modf here, not floor and subtract, so that
2929 * the separation is done in one step. At the end
2930 * of the loop don't break the number into parts so
2931 * that the final digit is rounded.
2932 */
2933 if (cdigits+czero+1 < precision+clead)
2934 fp = modf(fp, &d);
2935
2936 else
2937 {
2938 d = floor(fp + .5);
2939
2940 if (d > 9)
2941 {
2942 /* Rounding up to 10, handle that here. */
2943 if (czero > 0)
2944 {
2945 --czero, d = 1;
2946 if (cdigits == 0) --clead;
2947 }
2948 else
2949 {
2950 while (cdigits > 0 && d > 9)
2951 {
2952 int ch = *--ascii;
2953
2954 if (exp_b10 != (-1))
2955 ++exp_b10;
2956
2957 else if (ch == 46)
2958 {
2959 ch = *--ascii, ++size;
2960 /* Advance exp_b10 to '1', so that the
2961 * decimal point happens after the
2962 * previous digit.
2963 */
2964 exp_b10 = 1;
2965 }
2966
2967 --cdigits;
2968 d = ch - 47; /* I.e. 1+(ch-48) */
2969 }
2970
2971 /* Did we reach the beginning? If so adjust the
2972 * exponent but take into account the leading
2973 * decimal point.
2974 */
2975 if (d > 9) /* cdigits == 0 */
2976 {
2977 if (exp_b10 == (-1))
2978 {
2979 /* Leading decimal point (plus zeros?), if
2980 * we lose the decimal point here it must
2981 * be reentered below.
2982 */
2983 int ch = *--ascii;
2984
2985 if (ch == 46)
2986 ++size, exp_b10 = 1;
2987
2988 /* Else lost a leading zero, so 'exp_b10' is
2989 * still ok at (-1)
2990 */
2991 }
2992 else
2993 ++exp_b10;
2994
2995 /* In all cases we output a '1' */
2996 d = 1;
2997 }
2998 }
2999 }
3000 fp = 0; /* Guarantees termination below. */
3001 }
3002
3003 if (d == 0)
3004 {
3005 ++czero;
3006 if (cdigits == 0) ++clead;
3007 }
3008 else
3009 {
3010 /* Included embedded zeros in the digit count. */
3011 cdigits += czero - clead;
3012 clead = 0;
3013
3014 while (czero > 0)
3015 {
3016 /* exp_b10 == (-1) means we just output the decimal
3017 * place - after the DP don't adjust 'exp_b10' any
3018 * more!
3019 */
3020 if (exp_b10 != (-1))
3021 {
3022 if (exp_b10 == 0) *ascii++ = 46, --size;
3023 /* PLUS 1: TOTAL 4 */
3024 --exp_b10;
3025 }
3026 *ascii++ = 48, --czero;
3027 }
3028
3029 if (exp_b10 != (-1))
3030 {
3031 if (exp_b10 == 0)
3032 *ascii++ = 46, --size; /* counted above */
3033
3034 --exp_b10;
3035 }
3036 *ascii++ = (char)(48 + (int)d), ++cdigits;
3037 }
3038 }
3039 while (cdigits+czero < precision+clead && fp > DBL_MIN);
3040
3041 /* The total output count (max) is now 4+precision */
3042
3043 /* Check for an exponent, if we don't need one we are
3044 * done and just need to terminate the string. At
3045 * this point exp_b10==(-1) is effectively if flag - it got
3046 * to '-1' because of the decrement after outputting
3047 * the decimal point above (the exponent required is
3048 * *not* -1!)
3049 */
3050 if (exp_b10 >= (-1) && exp_b10 <= 2)
3051 {
3052 /* The following only happens if we didn't output the
3053 * leading zeros above for negative exponent, so this
3054 * doesn't add to the digit requirement. Note that the
3055 * two zeros here can only be output if the two leading
3056 * zeros were *not* output, so this doesn't increase
3057 * the output count.
3058 */
3059 while (--exp_b10 >= 0) *ascii++ = 48;
3060
3061 *ascii = 0;
3062
3063 /* Total buffer requirement (including the '\0') is
3064 * 5+precision - see check at the start.
3065 */
3066 return;
3067 }
3068
3069 /* Here if an exponent is required, adjust size for
3070 * the digits we output but did not count. The total
3071 * digit output here so far is at most 1+precision - no
3072 * decimal point and no leading or trailing zeros have
3073 * been output.
3074 */
3075 size -= cdigits;
3076
3077 *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
3078
3079 /* The following use of an unsigned temporary avoids ambiguities in
3080 * the signed arithmetic on exp_b10 and permits GCC at least to do
3081 * better optimization.
3082 */
3083 {
3084 unsigned int uexp_b10;
3085
3086 if (exp_b10 < 0)
3087 {
3088 *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
3089 uexp_b10 = -exp_b10;
3090 }
3091
3092 else
3093 uexp_b10 = exp_b10;
3094
3095 cdigits = 0;
3096
3097 while (uexp_b10 > 0)
3098 {
3099 exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
3100 uexp_b10 /= 10;
3101 }
3102 }
3103
3104 /* Need another size check here for the exponent digits, so
3105 * this need not be considered above.
3106 */
3107 if (size > cdigits)
3108 {
3109 while (cdigits > 0) *ascii++ = exponent[--cdigits];
3110
3111 *ascii = 0;
3112
3113 return;
3114 }
3115 }
3116 }
3117 else if (!(fp >= DBL_MIN))
3118 {
3119 *ascii++ = 48; /* '0' */
3120 *ascii = 0;
3121 return;
3122 }
3123 else
3124 {
3125 *ascii++ = 105; /* 'i' */
3126 *ascii++ = 110; /* 'n' */
3127 *ascii++ = 102; /* 'f' */
3128 *ascii = 0;
3129 return;
3130 }
3131 }
3132
3133 /* Here on buffer too small. */
3134 png_error(png_ptr, "ASCII conversion buffer too small");
3135 }
3136
3137 # endif /* FLOATING_POINT */
3138
3139 # ifdef PNG_FIXED_POINT_SUPPORTED
3140 /* Function to format a fixed point value in ASCII.
3141 */
3142 void /* PRIVATE */
3143 png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
3144 png_size_t size, png_fixed_point fp)
3145 {
3146 /* Require space for 10 decimal digits, a decimal point, a minus sign and a
3147 * trailing \0, 13 characters:
3148 */
3149 if (size > 12)
3150 {
3151 png_uint_32 num;
3152
3153 /* Avoid overflow here on the minimum integer. */
3154 if (fp < 0)
3155 *ascii++ = 45, num = -fp;
3156 else
3157 num = fp;
3158
3159 if (num <= 0x80000000) /* else overflowed */
3160 {
3161 unsigned int ndigits = 0, first = 16 /* flag value */;
3162 char digits[10];
3163
3164 while (num)
3165 {
3166 /* Split the low digit off num: */
3167 unsigned int tmp = num/10;
3168 num -= tmp*10;
3169 digits[ndigits++] = (char)(48 + num);
3170 /* Record the first non-zero digit, note that this is a number
3171 * starting at 1, it's not actually the array index.
3172 */
3173 if (first == 16 && num > 0)
3174 first = ndigits;
3175 num = tmp;
3176 }
3177
3178 if (ndigits > 0)
3179 {
3180 while (ndigits > 5) *ascii++ = digits[--ndigits];
3181 /* The remaining digits are fractional digits, ndigits is '5' or
3182 * smaller at this point. It is certainly not zero. Check for a
3183 * non-zero fractional digit:
3184 */
3185 if (first <= 5)
3186 {
3187 unsigned int i;
3188 *ascii++ = 46; /* decimal point */
3189 /* ndigits may be <5 for small numbers, output leading zeros
3190 * then ndigits digits to first:
3191 */
3192 i = 5;
3193 while (ndigits < i) *ascii++ = 48, --i;
3194 while (ndigits >= first) *ascii++ = digits[--ndigits];
3195 /* Don't output the trailing zeros! */
3196 }
3197 }
3198 else
3199 *ascii++ = 48;
3200
3201 /* And null terminate the string: */
3202 *ascii = 0;
3203 return;
3204 }
3205 }
3206
3207 /* Here on buffer too small. */
3208 png_error(png_ptr, "ASCII conversion buffer too small");
3209 }
3210 # endif /* FIXED_POINT */
3211 #endif /* SCAL */
3212
3213 #if defined(PNG_FLOATING_POINT_SUPPORTED) && \
3214 !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
3215 (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
3216 defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3217 defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
3218 (defined(PNG_sCAL_SUPPORTED) && \
3219 defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
3220 png_fixed_point
3221 png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
3222 {
3223 double r = floor(100000 * fp + .5);
3224
3225 if (r > 2147483647. || r < -2147483648.)
3226 png_fixed_error(png_ptr, text);
3227
3228 # ifndef PNG_ERROR_TEXT_SUPPORTED
3229 PNG_UNUSED(text)
3230 # endif
3231
3232 return (png_fixed_point)r;
3233 }
3234 #endif
3235
3236 #if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
3237 defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
3238 /* muldiv functions */
3239 /* This API takes signed arguments and rounds the result to the nearest
3240 * integer (or, for a fixed point number - the standard argument - to
3241 * the nearest .00001). Overflow and divide by zero are signalled in
3242 * the result, a boolean - true on success, false on overflow.
3243 */
3244 int
3245 png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
3246 png_int_32 divisor)
3247 {
3248 /* Return a * times / divisor, rounded. */
3249