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