CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libpng17/png.c
Views: 1401
1
2
/* png.c - location for general purpose libpng functions
3
*
4
* Last changed in libpng 1.7.0 [(PENDING RELEASE)]
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
#define PNG_SRC_FILE PNG_SRC_FILE_png
16
17
/* Generate a compiler error if there is an old png.h in the search path. */
18
typedef png_libpng_version_1_7_0beta90 Your_png_h_is_not_version_1_7_0beta90;
19
20
/* Tells libpng that we have already handled the first "num_bytes" bytes
21
* of the PNG file signature. If the PNG data is embedded into another
22
* stream we can set num_bytes = 8 so that libpng will not attempt to read
23
* or write any of the magic bytes before it starts on the IHDR.
24
*/
25
26
#ifdef PNG_READ_SUPPORTED
27
void PNGAPI
28
png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
29
{
30
png_debug(1, "in png_set_sig_bytes");
31
32
if (png_ptr == NULL)
33
return;
34
35
if (num_bytes > 8)
36
png_error(png_ptr, "Too many bytes for PNG signature");
37
38
png_ptr->sig_bytes = png_check_byte(png_ptr, num_bytes < 0 ? 0 : num_bytes);
39
}
40
41
/* Checks whether the supplied bytes match the PNG signature. We allow
42
* checking less than the full 8-byte signature so that those apps that
43
* already read the first few bytes of a file to determine the file type
44
* can simply check the remaining bytes for extra assurance. Returns
45
* an integer less than, equal to, or greater than zero if sig is found,
46
* respectively, to be less than, to match, or be greater than the correct
47
* PNG signature (this is the same behavior as strcmp, memcmp, etc).
48
*/
49
int PNGAPI
50
png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
51
{
52
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
53
54
if (num_to_check > 8)
55
num_to_check = 8;
56
57
else if (num_to_check < 1)
58
return (-1);
59
60
if (start > 7)
61
return (-1);
62
63
if (start + num_to_check > 8)
64
num_to_check = 8 - start;
65
66
return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
67
}
68
69
#endif /* READ */
70
71
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
72
/* Function to allocate memory for zlib */
73
PNG_FUNCTION(voidpf /* PRIVATE */,
74
png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
75
{
76
png_alloc_size_t num_bytes = size;
77
78
if (png_ptr == NULL)
79
return NULL;
80
81
if (items >= (~(png_alloc_size_t)0)/size)
82
{
83
png_warning(png_voidcast(png_structrp, png_ptr),
84
"Potential overflow in png_zalloc()");
85
return NULL;
86
}
87
88
num_bytes *= items;
89
return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
90
}
91
92
/* Function to free memory for zlib */
93
void /* PRIVATE */
94
png_zfree(voidpf png_ptr, voidpf ptr)
95
{
96
png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
97
}
98
99
/* Reset the CRC variable to 32 bits of 1's. Care must be taken
100
* in case CRC is > 32 bits to leave the top bits 0.
101
*/
102
void /* PRIVATE */
103
png_reset_crc(png_structrp png_ptr, png_const_bytep chunk_tag)
104
{
105
# ifdef PNG_READ_SUPPORTED
106
if (png_ptr->read_struct)
107
{
108
/* Set png_struct::current_crc appropriately. */
109
if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
110
png_ptr->current_crc = png_ptr->ancillary_crc;
111
112
else /* critical */
113
png_ptr->current_crc = png_ptr->critical_crc;
114
}
115
116
else
117
png_ptr->current_crc = crc_error_quit; /* for write */
118
119
/* Now do not calculate the CRC if it isn't required: */
120
if (png_ptr->current_crc != crc_quiet_use)
121
# endif /* READ */
122
png_ptr->crc = 0xFFFFFFFFU & crc32(0, chunk_tag, 4);
123
}
124
125
/* Calculate the CRC over a section of data. We can only pass as
126
* much data to this routine as the largest single buffer size. We
127
* also check that this data will actually be used before going to the
128
* trouble of calculating it.
129
*/
130
void /* PRIVATE */
131
png_calculate_crc(png_structrp png_ptr, png_const_voidp ptr, png_size_t length)
132
{
133
/* 'uLong' is defined in zlib.h as unsigned long; this means that on some
134
* systems it is a 64 bit value. crc32, however, returns 32 bits so the
135
* following cast is safe. 'uInt' may be no more than 16 bits, so it is
136
* necessary to perform a loop here.
137
*/
138
# ifdef PNG_READ_SUPPORTED
139
if (png_ptr->current_crc != crc_quiet_use)
140
# endif /* READ */
141
if (length > 0)
142
{
143
uLong crc = png_ptr->crc; /* Should never issue a warning */
144
const Bytef* rptr = png_voidcast(const Bytef*,ptr);
145
146
do
147
{
148
uInt safe_length;
149
150
/* TODO: this uses ZLIB_IO_MAX which may be #defined to less than the
151
* maximum of a uInt, is this the best thing to do?
152
*/
153
if (length > ZLIB_IO_MAX)
154
safe_length = ZLIB_IO_MAX;
155
156
else
157
safe_length = (uInt)/*SAFE*/length;
158
159
crc = crc32(crc, PNGZ_INPUT_CAST(rptr), safe_length);
160
161
/* The following should never issue compiler warnings; if they do the
162
* target system has characteristics that will probably violate other
163
* assumptions within the libpng code.
164
*/
165
rptr += safe_length;
166
length -= safe_length;
167
}
168
while (length > 0);
169
170
/* And the following is always safe because the crc is only 32 bits. */
171
png_ptr->crc = 0xFFFFFFFFU & crc;
172
}
173
}
174
175
/* Check a user supplied version number, called from both read and write
176
* functions that create a png_struct.
177
*/
178
static int
179
png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
180
{
181
/* Libpng versions 1.0.0 and later are binary compatible if the version
182
* string matches through the second '.'; we must recompile any applications
183
* that use any older library version.
184
*/
185
if (user_png_ver != NULL)
186
{
187
int library_match = 1;
188
int i = -1;
189
unsigned int found_dots = 0;
190
191
do
192
{
193
i++;
194
if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
195
library_match = 0;
196
if (user_png_ver[i] == '.')
197
found_dots++;
198
} while (library_match && found_dots < 2 && user_png_ver[i] != 0 &&
199
PNG_LIBPNG_VER_STRING[i] != 0);
200
201
if (library_match)
202
return 1; /* Library matches ok */
203
}
204
205
/* Failure: mismatched library major version number */
206
#ifdef PNG_WARNINGS_SUPPORTED
207
{
208
size_t pos = 0;
209
char m[128];
210
211
pos = png_safecat(m, (sizeof m), pos,
212
"Application built with libpng-");
213
/* This is ok if user_png_ver is NULL, it appends nothing: */
214
pos = png_safecat(m, (sizeof m), pos, user_png_ver);
215
pos = png_safecat(m, (sizeof m), pos, " but running with ");
216
pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
217
PNG_UNUSED(pos)
218
219
png_app_warning(png_ptr, m);
220
}
221
#endif
222
223
return 0; /* Failure */
224
PNG_UNUSED(png_ptr) /* if no warning */
225
}
226
227
/* Generic function to create a png_struct for either read or write - this
228
* contains the common initialization.
229
*/
230
PNG_FUNCTION(png_structp /* PRIVATE */,
231
png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
232
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
233
png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
234
{
235
png_struct create_struct;
236
# ifdef PNG_SETJMP_SUPPORTED
237
jmp_buf create_jmp_buf;
238
# endif
239
240
/* This is a compile-type only test to ensure that the build satisifies the
241
* contraints for the row buffer stack allocations. A 'duplicate case
242
* statements' style of error means that one of the tests below failed:
243
*/
244
switch (0)
245
{
246
case 0:
247
case PNG_ROW_BUFFER_SIZE >= PNG_MIN_ROW_BUFFER_SIZE: /*1*/
248
case 2*(PNG_ROW_BUFFER_SIZE <= PNG_MAX_ROW_BUFFER_SIZE): /*2*/
249
default:
250
break;
251
}
252
253
/* This temporary stack-allocated structure is used to provide a place to
254
* build enough context to allow the user provided memory allocator (if any)
255
* to be called.
256
*/
257
memset(&create_struct, 0, (sizeof create_struct));
258
259
/* These limits are only used on read at present, and if READ is not turned
260
* on neither will USER_LIMITS be. The width/height and chunk malloc limits
261
* are constants, so if they cannot be set they don't get defined in
262
* png_struct, the user_chunk_cache limits is a down-counter, when it reaches
263
* 1 no more chunks will be handled. 0 means unlimited, consequently the
264
* limit is 1 more than the number of chunks that will be handled.
265
*/
266
# ifdef PNG_SET_USER_LIMITS_SUPPORTED
267
create_struct.user_width_max = PNG_USER_WIDTH_MAX;
268
create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
269
create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
270
# endif
271
# ifdef PNG_USER_LIMITS_SUPPORTED
272
/* Must exist even if the initial value is constant */
273
create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
274
# endif
275
276
/* The following two API calls simply set fields in png_struct, so it is safe
277
* to do them now even though error handling is not yet set up.
278
*/
279
# ifdef PNG_USER_MEM_SUPPORTED
280
png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
281
# else
282
PNG_UNUSED(mem_ptr)
283
PNG_UNUSED(malloc_fn)
284
PNG_UNUSED(free_fn)
285
# endif
286
287
/* (*error_fn) can return control to the caller after the error_ptr is set,
288
* this will result in a memory leak unless the error_fn does something
289
* extremely sophisticated. The design lacks merit but is implicit in the
290
* API.
291
*/
292
png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
293
294
# ifdef PNG_SETJMP_SUPPORTED
295
if (!setjmp(create_jmp_buf))
296
# endif
297
{
298
# ifdef PNG_SETJMP_SUPPORTED
299
/* Temporarily fake out the longjmp information until we have
300
* successfully completed this function. This only works if we have
301
* setjmp() support compiled in, but it is safe - this stuff should
302
* never happen.
303
*/
304
create_struct.jmp_buf_ptr = &create_jmp_buf;
305
create_struct.jmp_buf_size = 0; /*stack allocation*/
306
create_struct.longjmp_fn = longjmp;
307
# endif
308
/* Call the general version checker (shared with read and write code):
309
*/
310
if (png_user_version_check(&create_struct, user_png_ver) != 0)
311
{
312
png_structrp png_ptr = png_voidcast(png_structrp,
313
png_malloc_warn(&create_struct, (sizeof *png_ptr)));
314
315
if (png_ptr != NULL)
316
{
317
# ifdef PNG_SETJMP_SUPPORTED
318
/* Eliminate the local error handling: */
319
create_struct.jmp_buf_ptr = NULL;
320
create_struct.jmp_buf_size = 0;
321
create_struct.longjmp_fn = 0;
322
# endif
323
324
*png_ptr = create_struct;
325
326
/* This is the successful return point */
327
return png_ptr;
328
}
329
}
330
}
331
332
/* A longjmp because of a bug in the application storage allocator or a
333
* simple failure to allocate the png_struct.
334
*/
335
return NULL;
336
}
337
338
/* Allocate the memory for an info_struct for the application. */
339
PNG_FUNCTION(png_infop,PNGAPI
340
png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
341
{
342
png_inforp info_ptr;
343
344
png_debug(1, "in png_create_info_struct");
345
346
if (png_ptr == NULL)
347
return NULL;
348
349
/* Use the internal API that does not (or at least should not) error out, so
350
* that this call always returns ok. The application typically sets up the
351
* error handling *after* creating the info_struct because this is the way it
352
* has always been done in 'example.c'.
353
*/
354
info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
355
(sizeof *info_ptr)));
356
357
if (info_ptr != NULL)
358
memset(info_ptr, 0, (sizeof *info_ptr));
359
360
return info_ptr;
361
}
362
363
/* This function frees the memory associated with a single info struct.
364
* Normally, one would use either png_destroy_read_struct() or
365
* png_destroy_write_struct() to free an info struct, but this may be
366
* useful for some applications. From libpng 1.6.0 this function is also used
367
* internally to implement the png_info release part of the 'struct' destroy
368
* APIs. This ensures that all possible approaches free the same data (all of
369
* it).
370
*/
371
void PNGAPI
372
png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
373
{
374
png_inforp info_ptr = NULL;
375
376
png_debug(1, "in png_destroy_info_struct");
377
378
if (png_ptr == NULL)
379
return;
380
381
if (info_ptr_ptr != NULL)
382
info_ptr = *info_ptr_ptr;
383
384
if (info_ptr != NULL)
385
{
386
/* Do this first in case of an error below; if the app implements its own
387
* memory management this can lead to png_free calling png_error, which
388
* will abort this routine and return control to the app error handler.
389
* An infinite loop may result if it then tries to free the same info
390
* ptr.
391
*/
392
*info_ptr_ptr = NULL;
393
394
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
395
memset(info_ptr, 0, (sizeof *info_ptr));
396
png_free(png_ptr, info_ptr);
397
}
398
}
399
400
void PNGAPI
401
png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
402
int num)
403
{
404
png_debug(1, "in png_free_data");
405
406
if (png_ptr == NULL || info_ptr == NULL)
407
return;
408
409
#ifdef PNG_TEXT_SUPPORTED
410
/* Free text item num or (if num == -1) all text items */
411
if (info_ptr->text != 0 &&
412
((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
413
{
414
if (num != -1)
415
{
416
png_free(png_ptr, info_ptr->text[num].key);
417
info_ptr->text[num].key = NULL;
418
}
419
420
else
421
{
422
int i;
423
424
for (i = 0; i < info_ptr->num_text; i++)
425
png_free(png_ptr, info_ptr->text[i].key);
426
427
png_free(png_ptr, info_ptr->text);
428
info_ptr->text = NULL;
429
info_ptr->num_text = 0;
430
info_ptr->max_text = 0;
431
}
432
}
433
#endif
434
435
#ifdef PNG_tRNS_SUPPORTED
436
/* Free any tRNS entry */
437
if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
438
{
439
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_tRNS);
440
png_free(png_ptr, info_ptr->trans_alpha);
441
info_ptr->trans_alpha = NULL;
442
info_ptr->num_trans = 0;
443
}
444
#endif
445
446
#ifdef PNG_sCAL_SUPPORTED
447
/* Free any sCAL entry */
448
if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
449
{
450
png_free(png_ptr, info_ptr->scal_s_width);
451
png_free(png_ptr, info_ptr->scal_s_height);
452
info_ptr->scal_s_width = NULL;
453
info_ptr->scal_s_height = NULL;
454
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sCAL);
455
}
456
#endif
457
458
#ifdef PNG_pCAL_SUPPORTED
459
/* Free any pCAL entry */
460
if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
461
{
462
png_free(png_ptr, info_ptr->pcal_purpose);
463
png_free(png_ptr, info_ptr->pcal_units);
464
info_ptr->pcal_purpose = NULL;
465
info_ptr->pcal_units = NULL;
466
467
if (info_ptr->pcal_params != NULL)
468
{
469
int i;
470
471
for (i = 0; i < info_ptr->pcal_nparams; i++)
472
png_free(png_ptr, info_ptr->pcal_params[i]);
473
474
png_free(png_ptr, info_ptr->pcal_params);
475
info_ptr->pcal_params = NULL;
476
}
477
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_pCAL);
478
}
479
#endif
480
481
#ifdef PNG_iCCP_SUPPORTED
482
/* Free any profile entry */
483
if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
484
{
485
png_free(png_ptr, info_ptr->iccp_name);
486
png_free(png_ptr, info_ptr->iccp_profile);
487
info_ptr->iccp_name = NULL;
488
info_ptr->iccp_profile = NULL;
489
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_iCCP);
490
}
491
#endif
492
493
#ifdef PNG_sPLT_SUPPORTED
494
/* Free a given sPLT entry, or (if num == -1) all sPLT entries */
495
if (info_ptr->splt_palettes != 0 &&
496
((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
497
{
498
if (num != -1)
499
{
500
png_free(png_ptr, info_ptr->splt_palettes[num].name);
501
png_free(png_ptr, info_ptr->splt_palettes[num].entries);
502
info_ptr->splt_palettes[num].name = NULL;
503
info_ptr->splt_palettes[num].entries = NULL;
504
}
505
506
else
507
{
508
int i;
509
510
for (i = 0; i < info_ptr->splt_palettes_num; i++)
511
{
512
png_free(png_ptr, info_ptr->splt_palettes[i].name);
513
png_free(png_ptr, info_ptr->splt_palettes[i].entries);
514
}
515
516
png_free(png_ptr, info_ptr->splt_palettes);
517
info_ptr->splt_palettes = NULL;
518
info_ptr->splt_palettes_num = 0;
519
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sPLT);
520
}
521
}
522
#endif
523
524
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
525
if (info_ptr->unknown_chunks != 0 &&
526
((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
527
{
528
if (num != -1)
529
{
530
png_free(png_ptr, info_ptr->unknown_chunks[num].data);
531
info_ptr->unknown_chunks[num].data = NULL;
532
}
533
534
else
535
{
536
int i;
537
538
for (i = 0; i < info_ptr->unknown_chunks_num; i++)
539
png_free(png_ptr, info_ptr->unknown_chunks[i].data);
540
541
png_free(png_ptr, info_ptr->unknown_chunks);
542
info_ptr->unknown_chunks = NULL;
543
info_ptr->unknown_chunks_num = 0;
544
}
545
}
546
#endif
547
548
#ifdef PNG_hIST_SUPPORTED
549
/* Free any hIST entry */
550
if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
551
{
552
png_free(png_ptr, info_ptr->hist);
553
info_ptr->hist = NULL;
554
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_hIST);
555
}
556
#endif
557
558
/* Free any PLTE entry that was internally allocated */
559
if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
560
{
561
png_free(png_ptr, info_ptr->palette);
562
info_ptr->palette = NULL;
563
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_PLTE);
564
info_ptr->num_palette = 0;
565
}
566
567
#ifdef PNG_INFO_IMAGE_SUPPORTED
568
/* Free any image bits attached to the info structure */
569
if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
570
{
571
if (info_ptr->row_pointers != 0)
572
{
573
png_uint_32 row;
574
for (row = 0; row < info_ptr->height; row++)
575
png_free(png_ptr, info_ptr->row_pointers[row]);
576
577
png_free(png_ptr, info_ptr->row_pointers);
578
info_ptr->row_pointers = NULL;
579
}
580
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_IDAT);
581
}
582
#endif
583
584
if (num != -1)
585
mask &= PNG_BIC_MASK(PNG_FREE_MUL);
586
587
info_ptr->free_me &= ~mask;
588
}
589
#endif /* READ || WRITE */
590
591
/* This function returns a pointer to the io_ptr associated with the user
592
* functions. The application should free any memory associated with this
593
* pointer before png_write_destroy() or png_read_destroy() are called.
594
*/
595
png_voidp PNGAPI
596
png_get_io_ptr(png_const_structrp png_ptr)
597
{
598
if (png_ptr == NULL)
599
return (NULL);
600
601
return (png_ptr->io_ptr);
602
}
603
604
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
605
# ifdef PNG_STDIO_SUPPORTED
606
/* Initialize the default input/output functions for the PNG file. If you
607
* use your own read or write routines, you can call either png_set_read_fn()
608
* or png_set_write_fn() instead of png_init_io(). If you have defined
609
* PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
610
* function of your own because "FILE *" isn't necessarily available.
611
*/
612
void PNGAPI
613
png_init_io(png_structrp png_ptr, png_FILE_p fp)
614
{
615
png_debug(1, "in png_init_io");
616
617
if (png_ptr == NULL)
618
return;
619
620
if (png_ptr->rw_data_fn == NULL)
621
{
622
# ifdef PNG_READ_SUPPORTED
623
if (png_ptr->read_struct)
624
png_set_read_fn(png_ptr, fp, png_default_read_data);
625
# ifdef PNG_WRITE_SUPPORTED
626
else
627
# endif /* WRITE */
628
# endif /* READ */
629
# ifdef PNG_WRITE_SUPPORTED
630
if (!png_ptr->read_struct)
631
# ifdef PNG_WRITE_FLUSH_SUPPORTED
632
png_set_write_fn(png_ptr, fp, png_default_write_data,
633
png_default_flush);
634
# else
635
png_set_write_fn(png_ptr, fp, png_default_write_data, NULL);
636
# endif
637
# endif /* WRITE */
638
}
639
640
else
641
png_ptr->io_ptr = fp;
642
}
643
# endif /* STDIO */
644
645
# ifdef PNG_TIME_RFC1123_SUPPORTED
646
/* Convert the supplied time into an RFC 1123 string suitable for use in
647
* a "Creation Time" or other text-based time string.
648
*/
649
int PNGAPI
650
png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
651
{
652
static PNG_CONST char short_months[12][4] =
653
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
654
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
655
656
if (out == NULL)
657
return 0;
658
659
if (ptime->year > 9999 /* RFC1123 limitation */ ||
660
ptime->month == 0 || ptime->month > 12 ||
661
ptime->day == 0 || ptime->day > 31 ||
662
ptime->hour > 23 || ptime->minute > 59 ||
663
ptime->second > 60)
664
return 0;
665
666
{
667
size_t pos = 0;
668
char number_buf[5]; /* enough for a four-digit year */
669
670
# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
671
# define APPEND_NUMBER(format, value)\
672
APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
673
# define APPEND(ch) if (pos < 28) out[pos++] = (ch)
674
675
APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
676
APPEND(' ');
677
APPEND_STRING(short_months[(ptime->month - 1)]);
678
APPEND(' ');
679
APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
680
APPEND(' ');
681
APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
682
APPEND(':');
683
APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
684
APPEND(':');
685
APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
686
APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
687
688
# undef APPEND
689
# undef APPEND_NUMBER
690
# undef APPEND_STRING
691
}
692
693
return 1;
694
}
695
# endif /* TIME_RFC1123 */
696
697
#endif /* READ || WRITE */
698
699
png_const_charp PNGAPI
700
png_get_copyright(png_const_structrp png_ptr)
701
{
702
PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
703
#ifdef PNG_STRING_COPYRIGHT
704
return PNG_STRING_COPYRIGHT
705
#else
706
# ifdef __STDC__
707
return PNG_STRING_NEWLINE \
708
"libpng version 1.7.0beta90 - August 28, 2017" PNG_STRING_NEWLINE \
709
"Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
710
PNG_STRING_NEWLINE \
711
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
712
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
713
PNG_STRING_NEWLINE;
714
# else
715
return "libpng version 1.7.0beta90 - August 28, 2017\
716
Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
717
Copyright (c) 1996-1997 Andreas Dilger\
718
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
719
# endif
720
#endif
721
}
722
723
/* The following return the library version as a short string in the
724
* format 1.0.0 through 99.99.99zz. To get the version of *.h files
725
* used with your application, print out PNG_LIBPNG_VER_STRING, which
726
* is defined in png.h.
727
* Note: now there is no difference between png_get_libpng_ver() and
728
* png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
729
* it is guaranteed that png.c uses the correct version of png.h.
730
*/
731
png_const_charp PNGAPI
732
png_get_libpng_ver(png_const_structrp png_ptr)
733
{
734
/* Version of *.c files used when building libpng */
735
return png_get_header_ver(png_ptr);
736
}
737
738
png_const_charp PNGAPI
739
png_get_header_ver(png_const_structrp png_ptr)
740
{
741
/* Version of *.h files used when building libpng */
742
PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
743
return PNG_LIBPNG_VER_STRING;
744
}
745
746
png_const_charp PNGAPI
747
png_get_header_version(png_const_structrp png_ptr)
748
{
749
/* Returns longer string containing both version and date */
750
PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
751
#ifdef __STDC__
752
# ifndef PNG_READ_SUPPORTED
753
return PNG_HEADER_VERSION_STRING " (NO READ SUPPORT)" PNG_STRING_NEWLINE;
754
# else
755
return PNG_HEADER_VERSION_STRING PNG_STRING_NEWLINE;
756
# endif
757
#else
758
return PNG_HEADER_VERSION_STRING;
759
#endif
760
}
761
762
#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
763
/* NOTE: this routine is not used internally! */
764
/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
765
* large of png_color. This lets grayscale images be treated as
766
* paletted. Most useful for gamma correction and simplification
767
* of code. This API is not used internally.
768
*/
769
void PNGAPI
770
png_build_grayscale_palette(int bit_depth, png_colorp palette)
771
{
772
int num_palette;
773
png_byte color_inc;
774
int i;
775
png_byte v;
776
777
png_debug(1, "in png_do_build_grayscale_palette");
778
779
if (palette == NULL)
780
return;
781
782
switch (bit_depth)
783
{
784
case 1:
785
num_palette = 2;
786
color_inc = 0xff;
787
break;
788
789
case 2:
790
num_palette = 4;
791
color_inc = 0x55;
792
break;
793
794
case 4:
795
num_palette = 16;
796
color_inc = 0x11;
797
break;
798
799
case 8:
800
num_palette = 256;
801
color_inc = 1;
802
break;
803
804
default:
805
num_palette = 0;
806
color_inc = 0;
807
break;
808
}
809
810
for (i = 0, v = 0; i < num_palette; ++i, v = PNG_BYTE(v+color_inc))
811
palette[i].red = palette[i].green = palette[i].blue = v;
812
}
813
#endif
814
815
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
816
int PNGAPI
817
png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
818
{
819
/* Check chunk_name and return "keep" value if it's on the list, else 0 */
820
png_const_bytep p, p_end;
821
822
if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
823
return PNG_HANDLE_CHUNK_AS_DEFAULT;
824
825
p_end = png_ptr->chunk_list;
826
p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
827
828
/* The code is the fifth byte after each four byte string. Historically this
829
* code was always searched from the end of the list, this is no longer
830
* necessary because the 'set' routine handles duplicate entries correcty.
831
*/
832
do /* num_chunk_list > 0, so at least one */
833
{
834
p -= 5;
835
836
if (memcmp(chunk_name, p, 4) == 0)
837
return p[4];
838
}
839
while (p > p_end);
840
841
/* This means that known chunks should be processed and unknown chunks should
842
* be handled according to the value of png_ptr->unknown_default; this can be
843
* confusing because, as a result, there are two levels of defaulting for
844
* unknown chunks.
845
*/
846
return PNG_HANDLE_CHUNK_AS_DEFAULT;
847
}
848
#endif /* SET_UNKNOWN_CHUNKS */
849
850
/* This function was added to libpng-1.0.7 */
851
png_uint_32 PNGAPI
852
png_access_version_number(void)
853
{
854
/* Version of *.c files used when building libpng */
855
return((png_uint_32)PNG_LIBPNG_VER);
856
}
857
858
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
859
/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
860
* If it doesn't 'ret' is used to set it to something appropriate, even in cases
861
* like Z_OK or Z_STREAM_END where the error code is apparently a success code.
862
*/
863
void /* PRIVATE */
864
png_zstream_error(z_stream *zstream, int ret)
865
{
866
/* Translate 'ret' into an appropriate error string, priority is given to the
867
* one in zstream if set. This always returns a string, even in cases like
868
* Z_OK or Z_STREAM_END where the error code is a success code.
869
*/
870
if (zstream->msg == NULL) switch (ret)
871
{
872
default:
873
case Z_OK:
874
zstream->msg = PNGZ_MSG_CAST("unexpected zlib return code");
875
break;
876
877
case Z_STREAM_END:
878
/* Normal exit */
879
zstream->msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
880
break;
881
882
case Z_NEED_DICT:
883
/* This means the deflate stream did not have a dictionary; this
884
* indicates a bogus PNG.
885
*/
886
zstream->msg = PNGZ_MSG_CAST("missing LZ dictionary");
887
break;
888
889
case Z_ERRNO:
890
/* gz APIs only: should not happen */
891
zstream->msg = PNGZ_MSG_CAST("zlib IO error");
892
break;
893
894
case Z_STREAM_ERROR:
895
/* internal libpng error */
896
zstream->msg = PNGZ_MSG_CAST("bad parameters to zlib");
897
break;
898
899
case Z_DATA_ERROR:
900
zstream->msg = PNGZ_MSG_CAST("damaged LZ stream");
901
break;
902
903
case Z_MEM_ERROR:
904
zstream->msg = PNGZ_MSG_CAST("insufficient memory");
905
break;
906
907
case Z_BUF_ERROR:
908
/* End of input or output; not a problem if the caller is doing
909
* incremental read or write.
910
*/
911
zstream->msg = PNGZ_MSG_CAST("truncated");
912
break;
913
914
case Z_VERSION_ERROR:
915
zstream->msg = PNGZ_MSG_CAST("unsupported zlib version");
916
break;
917
918
case PNG_UNEXPECTED_ZLIB_RETURN:
919
/* Compile errors here mean that zlib now uses the value co-opted in
920
* pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
921
* and change pngpriv.h. Note that this message is "... return",
922
* whereas the default/Z_OK one is "... return code".
923
*/
924
zstream->msg = PNGZ_MSG_CAST("unexpected zlib return");
925
break;
926
}
927
}
928
929
/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
930
* at libpng 1.5.5!
931
*/
932
933
/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
934
#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
935
static int
936
png_colorspace_check_gamma(png_const_structrp png_ptr,
937
png_colorspacerp colorspace, png_fixed_point gAMA, int from)
938
/* This is called to check a new gamma value against an existing one. The
939
* routine returns false if the new gamma value should not be written.
940
*
941
* 'from' says where the new gamma value comes from:
942
*
943
* 0: the new gamma value is the libpng estimate for an ICC profile
944
* 1: the new gamma value comes from a gAMA chunk
945
* 2: the new gamma value comes from an sRGB chunk
946
*
947
* API CHANGE: libpng 1.7.0: prior to 1.7 the check below used the build-time
948
* constant PNG_GAMMA_THRESHOLD_FIXED and the results would therefore depend
949
* on a parameter that was intended for tuning the READ_GAMMA support. In
950
* 1.7 a fixed value of +/-1% is used instead; this reflects the fact that
951
* gamma values are rarely quoted to more than 2 decimal digits of precision.
952
*/
953
{
954
png_fixed_point gtest;
955
956
if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
957
(png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0 ||
958
gtest < PNG_FP_1 - 1000 || gtest > PNG_FP_1 + 1000))
959
{
960
/* Either this is an sRGB image, in which case the calculated gamma
961
* approximation should match, or this is an image with a profile and the
962
* value libpng calculates for the gamma of the profile does not match the
963
* value recorded in the file. The former, sRGB, case is an error, the
964
* latter is just a warning.
965
*/
966
if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
967
{
968
png_chunk_report(png_ptr, "gamma value does not match sRGB",
969
PNG_CHUNK_ERROR);
970
/* Do not overwrite an sRGB value */
971
return from == 2;
972
}
973
974
else /* sRGB tag not involved */
975
{
976
png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
977
PNG_CHUNK_WARNING);
978
return from == 1;
979
}
980
}
981
982
return 1;
983
}
984
985
void /* PRIVATE */
986
png_colorspace_set_gamma(png_const_structrp png_ptr,
987
png_colorspacerp colorspace, png_fixed_point gAMA)
988
{
989
/* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
990
* occur. Since the fixed point representation is asymmetrical it is
991
* possible for 1/gamma to overflow the limit of 21474 and this means the
992
* gamma value must be at least 5/100000 and hence at most 20000.0. For
993
* safety the limits here are a little narrower. The values are 0.00016 to
994
* 6250.0, which are truly ridiculous gamma values (and will produce
995
* displays that are all black or all white.)
996
*
997
* In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
998
* handling code, which only required the value to be >0.
999
*/
1000
# if (defined PNG_TRANSFORM_MECH_SUPPORTED) &&\
1001
(defined PNG_ERROR_TEXT_SUPPORTED)
1002
# define ERRMSG 1
1003
# else
1004
# define ERRMSG 0
1005
# endif
1006
1007
# if ERRMSG
1008
png_const_charp errmsg;
1009
# endif
1010
1011
if (gAMA < 16 || gAMA > 625000000)
1012
{
1013
# if ERRMSG
1014
errmsg = "gamma value out of range";
1015
# endif
1016
}
1017
1018
# ifdef PNG_READ_gAMA_SUPPORTED
1019
/* Allow the application to set the gamma value more than once */
1020
else if (png_ptr->read_struct &&
1021
(colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
1022
{
1023
# if ERRMSG
1024
errmsg = "duplicate";
1025
# endif
1026
}
1027
# endif
1028
1029
/* Do nothing if the colorspace is already invalid */
1030
else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1031
return;
1032
1033
else
1034
{
1035
if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
1036
1/*from gAMA*/) != 0)
1037
{
1038
/* Store this gamma value. */
1039
colorspace->gamma = gAMA;
1040
colorspace->flags |=
1041
(PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
1042
}
1043
1044
/* At present if the check_gamma test fails the gamma of the colorspace is
1045
* not updated however the colorspace is not invalidated. This
1046
* corresponds to the case where the existing gamma comes from an sRGB
1047
* chunk or profile. An error message has already been output.
1048
*/
1049
return;
1050
}
1051
1052
/* Error exit - errmsg has been set. */
1053
# undef ERRMSG
1054
colorspace->flags |= PNG_COLORSPACE_INVALID;
1055
png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
1056
}
1057
1058
void /* PRIVATE */
1059
png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
1060
{
1061
if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
1062
{
1063
/* Everything is invalid */
1064
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
1065
PNG_INFO_iCCP);
1066
1067
# ifdef PNG_COLORSPACE_SUPPORTED
1068
/* Clean up the iCCP profile now if it won't be used. */
1069
png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
1070
# else
1071
PNG_UNUSED(png_ptr)
1072
# endif
1073
}
1074
1075
else
1076
{
1077
# ifdef PNG_COLORSPACE_SUPPORTED
1078
/* Leave the INFO_iCCP flag set if the pngset.c code has already set
1079
* it; this allows a PNG to contain a profile which matches sRGB and
1080
* yet still have that profile retrievable by the application.
1081
*/
1082
if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
1083
info_ptr->valid |= PNG_INFO_sRGB;
1084
1085
else
1086
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_sRGB);
1087
1088
if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
1089
info_ptr->valid |= PNG_INFO_cHRM;
1090
1091
else
1092
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_cHRM);
1093
# endif
1094
1095
if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
1096
info_ptr->valid |= PNG_INFO_gAMA;
1097
1098
else
1099
info_ptr->valid &= PNG_BIC_MASK(PNG_INFO_gAMA);
1100
}
1101
}
1102
1103
#ifdef PNG_READ_SUPPORTED
1104
void /* PRIVATE */
1105
png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
1106
{
1107
if (info_ptr == NULL) /* reduce code size; check here not in the caller */
1108
return;
1109
1110
info_ptr->colorspace = png_ptr->colorspace;
1111
png_colorspace_sync_info(png_ptr, info_ptr);
1112
}
1113
#endif
1114
#endif
1115
1116
#ifdef PNG_COLORSPACE_SUPPORTED
1117
/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
1118
static png_fixed_point
1119
png_reciprocal(png_fixed_point a)
1120
{
1121
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
1122
double r = floor(1E10/a+.5);
1123
1124
if (r <= 2147483647. && r >= -2147483648.)
1125
return (png_fixed_point)r;
1126
#else
1127
png_fixed_point res;
1128
1129
if (png_muldiv(&res, PNG_FP_1, PNG_FP_1, a) != 0)
1130
return res;
1131
#endif
1132
1133
return 0; /* error/overflow */
1134
}
1135
1136
/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
1137
* cHRM, as opposed to using chromaticities. These internal APIs return
1138
* non-zero on a parameter error. The X, Y and Z values are required to be
1139
* positive and less than 1.0.
1140
*/
1141
static int
1142
png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
1143
{
1144
png_int_32 d, dwhite, whiteX, whiteY;
1145
1146
d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
1147
if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
1148
return 1;
1149
if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
1150
return 1;
1151
dwhite = d;
1152
whiteX = XYZ->red_X;
1153
whiteY = XYZ->red_Y;
1154
1155
d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
1156
if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
1157
return 1;
1158
if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
1159
return 1;
1160
dwhite += d;
1161
whiteX += XYZ->green_X;
1162
whiteY += XYZ->green_Y;
1163
1164
d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
1165
if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
1166
return 1;
1167
if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
1168
return 1;
1169
dwhite += d;
1170
whiteX += XYZ->blue_X;
1171
whiteY += XYZ->blue_Y;
1172
1173
/* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
1174
* thus:
1175
*/
1176
if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
1177
return 1;
1178
if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
1179
return 1;
1180
1181
return 0;
1182
}
1183
1184
static int
1185
png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
1186
{
1187
png_fixed_point red_inverse, green_inverse, blue_scale;
1188
png_fixed_point left, right, denominator;
1189
1190
/* Check xy and, implicitly, z. Note that wide gamut color spaces typically
1191
* have end points with 0 tristimulus values (these are impossible end
1192
* points, but they are used to cover the possible colors). We check
1193
* xy->whitey against 5, not 0, to avoid a possible integer overflow.
1194
*/
1195
if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
1196
if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
1197
if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
1198
if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
1199
if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
1200
if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
1201
if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
1202
if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
1203
1204
/* The reverse calculation is more difficult because the original tristimulus
1205
* value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
1206
* derived values were recorded in the cHRM chunk;
1207
* (red,green,blue,white)x(x,y). This loses one degree of freedom and
1208
* therefore an arbitrary ninth value has to be introduced to undo the
1209
* original transformations.
1210
*
1211
* Think of the original end-points as points in (X,Y,Z) space. The
1212
* chromaticity values (c) have the property:
1213
*
1214
* C
1215
* c = ---------
1216
* X + Y + Z
1217
*
1218
* For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
1219
* three chromaticity values (x,y,z) for each end-point obey the
1220
* relationship:
1221
*
1222
* x + y + z = 1
1223
*
1224
* This describes the plane in (X,Y,Z) space that intersects each axis at the
1225
* value 1.0; call this the chromaticity plane. Thus the chromaticity
1226
* calculation has scaled each end-point so that it is on the x+y+z=1 plane
1227
* and chromaticity is the intersection of the vector from the origin to the
1228
* (X,Y,Z) value with the chromaticity plane.
1229
*
1230
* To fully invert the chromaticity calculation we would need the three
1231
* end-point scale factors, (red-scale, green-scale, blue-scale), but these
1232
* were not recorded. Instead we calculated the reference white (X,Y,Z) and
1233
* recorded the chromaticity of this. The reference white (X,Y,Z) would have
1234
* given all three of the scale factors since:
1235
*
1236
* color-C = color-c * color-scale
1237
* white-C = red-C + green-C + blue-C
1238
* = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1239
*
1240
* But cHRM records only white-x and white-y, so we have lost the white scale
1241
* factor:
1242
*
1243
* white-C = white-c*white-scale
1244
*
1245
* To handle this the inverse transformation makes an arbitrary assumption
1246
* about white-scale:
1247
*
1248
* Assume: white-Y = 1.0
1249
* Hence: white-scale = 1/white-y
1250
* Or: red-Y + green-Y + blue-Y = 1.0
1251
*
1252
* Notice the last statement of the assumption gives an equation in three of
1253
* the nine values we want to calculate. 8 more equations come from the
1254
* above routine as summarised at the top above (the chromaticity
1255
* calculation):
1256
*
1257
* Given: color-x = color-X / (color-X + color-Y + color-Z)
1258
* Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
1259
*
1260
* This is 9 simultaneous equations in the 9 variables "color-C" and can be
1261
* solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
1262
* determinants, however this is not as bad as it seems because only 28 of
1263
* the total of 90 terms in the various matrices are non-zero. Nevertheless
1264
* Cramer's rule is notoriously numerically unstable because the determinant
1265
* calculation involves the difference of large, but similar, numbers. It is
1266
* difficult to be sure that the calculation is stable for real world values
1267
* and it is certain that it becomes unstable where the end points are close
1268
* together.
1269
*
1270
* So this code uses the perhaps slightly less optimal but more
1271
* understandable and totally obvious approach of calculating color-scale.
1272
*
1273
* This algorithm depends on the precision in white-scale and that is
1274
* (1/white-y), so we can immediately see that as white-y approaches 0 the
1275
* accuracy inherent in the cHRM chunk drops off substantially.
1276
*
1277
* libpng arithmetic: a simple inversion of the above equations
1278
* ------------------------------------------------------------
1279
*
1280
* white_scale = 1/white-y
1281
* white-X = white-x * white-scale
1282
* white-Y = 1.0
1283
* white-Z = (1 - white-x - white-y) * white_scale
1284
*
1285
* white-C = red-C + green-C + blue-C
1286
* = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
1287
*
1288
* This gives us three equations in (red-scale,green-scale,blue-scale) where
1289
* all the coefficients are now known:
1290
*
1291
* red-x*red-scale + green-x*green-scale + blue-x*blue-scale
1292
* = white-x/white-y
1293
* red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
1294
* red-z*red-scale + green-z*green-scale + blue-z*blue-scale
1295
* = (1 - white-x - white-y)/white-y
1296
*
1297
* In the last equation color-z is (1 - color-x - color-y) so we can add all
1298
* three equations together to get an alternative third:
1299
*
1300
* red-scale + green-scale + blue-scale = 1/white-y = white-scale
1301
*
1302
* So now we have a Cramer's rule solution where the determinants are just
1303
* 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
1304
* multiplication of three coefficients so we can't guarantee to avoid
1305
* overflow in the libpng fixed point representation. Using Cramer's rule in
1306
* floating point is probably a good choice here, but it's not an option for
1307
* fixed point. Instead proceed to simplify the first two equations by
1308
* eliminating what is likely to be the largest value, blue-scale:
1309
*
1310
* blue-scale = white-scale - red-scale - green-scale
1311
*
1312
* Hence:
1313
*
1314
* (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
1315
* (white-x - blue-x)*white-scale
1316
*
1317
* (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
1318
* 1 - blue-y*white-scale
1319
*
1320
* And now we can trivially solve for (red-scale,green-scale):
1321
*
1322
* green-scale =
1323
* (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
1324
* -----------------------------------------------------------
1325
* green-x - blue-x
1326
*
1327
* red-scale =
1328
* 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
1329
* ---------------------------------------------------------
1330
* red-y - blue-y
1331
*
1332
* Hence:
1333
*
1334
* red-scale =
1335
* ( (green-x - blue-x) * (white-y - blue-y) -
1336
* (green-y - blue-y) * (white-x - blue-x) ) / white-y
1337
* -------------------------------------------------------------------------
1338
* (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1339
*
1340
* green-scale =
1341
* ( (red-y - blue-y) * (white-x - blue-x) -
1342
* (red-x - blue-x) * (white-y - blue-y) ) / white-y
1343
* -------------------------------------------------------------------------
1344
* (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
1345
*
1346
* Accuracy:
1347
* The input values have 5 decimal digits of accuracy. The values are all in
1348
* the range 0 < value < 1, so simple products are in the same range but may
1349
* need up to 10 decimal digits to preserve the original precision and avoid
1350
* underflow. Because we are using a 32-bit signed representation we cannot
1351
* match this; the best is a little over 9 decimal digits, less than 10.
1352
*
1353
* The approach used here is to preserve the maximum precision within the
1354
* signed representation. Because the red-scale calculation above uses the
1355
* difference between two products of values that must be in the range -1..+1
1356
* it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
1357
* factor is irrelevant in the calculation because it is applied to both
1358
* numerator and denominator.
1359
*
1360
* Note that the values of the differences of the products of the
1361
* chromaticities in the above equations tend to be small, for example for
1362
* the sRGB chromaticities they are:
1363
*
1364
* red numerator: -0.04751
1365
* green numerator: -0.08788
1366
* denominator: -0.2241 (without white-y multiplication)
1367
*
1368
* The resultant Y coefficients from the chromaticities of some widely used
1369
* color space definitions are (to 15 decimal places):
1370
*
1371
* sRGB
1372
* 0.212639005871510 0.715168678767756 0.072192315360734
1373
* Kodak ProPhoto
1374
* 0.288071128229293 0.711843217810102 0.000085653960605
1375
* Adobe RGB
1376
* 0.297344975250536 0.627363566255466 0.075291458493998
1377
* Adobe Wide Gamut RGB
1378
* 0.258728243040113 0.724682314948566 0.016589442011321
1379
*/
1380
/* By the argument, above overflow should be impossible here. The return
1381
* value of 2 indicates an internal error to the caller.
1382
*/
1383
if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
1384
return 2;
1385
if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
1386
return 2;
1387
denominator = left - right;
1388
1389
/* Now find the red numerator. */
1390
if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
1391
return 2;
1392
if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
1393
return 2;
1394
1395
/* Overflow is possible here and it indicates an extreme set of PNG cHRM
1396
* chunk values. This calculation actually returns the reciprocal of the
1397
* scale value because this allows us to delay the multiplication of white-y
1398
* into the denominator, which tends to produce a small number.
1399
*/
1400
if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
1401
red_inverse <= xy->whitey /* r+g+b scales = white scale */)
1402
return 1;
1403
1404
/* Similarly for green_inverse: */
1405
if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
1406
return 2;
1407
if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
1408
return 2;
1409
if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
1410
green_inverse <= xy->whitey)
1411
return 1;
1412
1413
/* And the blue scale, the checks above guarantee this can't overflow but it
1414
* can still produce 0 for extreme cHRM values.
1415
*/
1416
blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
1417
png_reciprocal(green_inverse);
1418
if (blue_scale <= 0)
1419
return 1;
1420
1421
1422
/* And fill in the png_XYZ: */
1423
if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
1424
return 1;
1425
if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
1426
return 1;
1427
if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
1428
red_inverse) == 0)
1429
return 1;
1430
1431
if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
1432
return 1;
1433
if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
1434
return 1;
1435
if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
1436
green_inverse) == 0)
1437
return 1;
1438
1439
if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
1440
return 1;
1441
if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
1442
return 1;
1443
if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
1444
PNG_FP_1) == 0)
1445
return 1;
1446
1447
return 0; /*success*/
1448
}
1449
1450
static int
1451
png_XYZ_normalize(png_XYZ *XYZ)
1452
{
1453
png_int_32 Y;
1454
1455
if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
1456
XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
1457
XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
1458
return 1;
1459
1460
/* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
1461
* IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
1462
* relying on addition of two positive values producing a negative one is not
1463
* safe.
1464
*/
1465
Y = XYZ->red_Y;
1466
if (0x7fffffff - Y < XYZ->green_X)
1467
return 1;
1468
Y += XYZ->green_Y;
1469
if (0x7fffffff - Y < XYZ->blue_X)
1470
return 1;
1471
Y += XYZ->blue_Y;
1472
1473
if (Y != PNG_FP_1)
1474
{
1475
if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
1476
return 1;
1477
if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
1478
return 1;
1479
if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
1480
return 1;
1481
1482
if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
1483
return 1;
1484
if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
1485
return 1;
1486
if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
1487
return 1;
1488
1489
if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
1490
return 1;
1491
if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
1492
return 1;
1493
if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
1494
return 1;
1495
}
1496
1497
return 0;
1498
}
1499
1500
static int
1501
png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
1502
{
1503
/* Allow an error of +/-0.01 (absolute value) on each chromaticity */
1504
if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
1505
PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
1506
PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
1507
PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
1508
PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
1509
PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
1510
PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
1511
PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta))
1512
return 0;
1513
return 1;
1514
}
1515
1516
/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
1517
* chunk chromaticities. Earlier checks used to simply look for the overflow
1518
* condition (where the determinant of the matrix to solve for XYZ ends up zero
1519
* because the chromaticity values are not all distinct.) Despite this it is
1520
* theoretically possible to produce chromaticities that are apparently valid
1521
* but that rapidly degrade to invalid, potentially crashing, sets because of
1522
* arithmetic inaccuracies when calculations are performed on them. The new
1523
* check is to round-trip xy -> XYZ -> xy and then check that the result is
1524
* within a small percentage of the original.
1525
*/
1526
static int
1527
png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
1528
{
1529
int result;
1530
png_xy xy_test;
1531
1532
/* As a side-effect this routine also returns the XYZ endpoints. */
1533
result = png_XYZ_from_xy(XYZ, xy);
1534
if (result != 0)
1535
return result;
1536
1537
result = png_xy_from_XYZ(&xy_test, XYZ);
1538
if (result != 0)
1539
return result;
1540
1541
if (png_colorspace_endpoints_match(xy, &xy_test,
1542
5/*actually, the math is pretty accurate*/) != 0)
1543
return 0;
1544
1545
/* Too much slip */
1546
return 1;
1547
}
1548
1549
/* This is the check going the other way. The XYZ is modified to normalize it
1550
* (another side-effect) and the xy chromaticities are returned.
1551
*/
1552
static int
1553
png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
1554
{
1555
int result;
1556
png_XYZ XYZtemp;
1557
1558
result = png_XYZ_normalize(XYZ);
1559
if (result != 0)
1560
return result;
1561
1562
result = png_xy_from_XYZ(xy, XYZ);
1563
if (result != 0)
1564
return result;
1565
1566
XYZtemp = *XYZ;
1567
return png_colorspace_check_xy(&XYZtemp, xy);
1568
}
1569
1570
/* Used to check for an endpoint match against sRGB */
1571
static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
1572
{
1573
/* color x y */
1574
/* red */ 64000, 33000,
1575
/* green */ 30000, 60000,
1576
/* blue */ 15000, 6000,
1577
/* white */ 31270, 32900
1578
};
1579
1580
static int
1581
png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
1582
png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
1583
int preferred)
1584
{
1585
if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1586
return 0;
1587
1588
/* The consistency check is performed on the chromaticities; this factors out
1589
* variations because of the normalization (or not) of the end point Y
1590
* values.
1591
*/
1592
if (preferred < 2 &&
1593
(colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
1594
{
1595
/* The end points must be reasonably close to any we already have. The
1596
* following allows an error of up to +/-.001
1597
*/
1598
if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
1599
100) == 0)
1600
{
1601
colorspace->flags |= PNG_COLORSPACE_INVALID;
1602
png_benign_error(png_ptr, "inconsistent chromaticities");
1603
return 0; /* failed */
1604
}
1605
1606
/* Only overwrite with preferred values */
1607
if (preferred == 0)
1608
return 1; /* ok, but no change */
1609
}
1610
1611
colorspace->end_points_xy = *xy;
1612
colorspace->end_points_XYZ = *XYZ;
1613
colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
1614
1615
/* The end points are normally quoted to two decimal digits, so allow +/-0.01
1616
* on this test.
1617
*/
1618
if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
1619
colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
1620
1621
else
1622
colorspace->flags &= PNG_COLORSPACE_CANCEL(
1623
PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
1624
1625
return 2; /* ok and changed */
1626
}
1627
1628
int /* PRIVATE */
1629
png_colorspace_set_chromaticities(png_const_structrp png_ptr,
1630
png_colorspacerp colorspace, const png_xy *xy, int preferred)
1631
{
1632
/* We must check the end points to ensure they are reasonable - in the past
1633
* color management systems have crashed as a result of getting bogus
1634
* colorant values, while this isn't the fault of libpng it is the
1635
* responsibility of libpng because PNG carries the bomb and libpng is in a
1636
* position to protect against it.
1637
*/
1638
png_XYZ XYZ;
1639
1640
switch (png_colorspace_check_xy(&XYZ, xy))
1641
{
1642
case 0: /* success */
1643
return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
1644
preferred);
1645
1646
case 1:
1647
/* We can't invert the chromaticities so we can't produce value XYZ
1648
* values. Likely as not a color management system will fail too.
1649
*/
1650
colorspace->flags |= PNG_COLORSPACE_INVALID;
1651
png_benign_error(png_ptr, "invalid chromaticities");
1652
break;
1653
1654
default:
1655
/* libpng is broken; this should be a warning but if it happens we
1656
* want error reports so for the moment it is an error.
1657
*/
1658
colorspace->flags |= PNG_COLORSPACE_INVALID;
1659
impossible("error checking chromaticities");
1660
break;
1661
}
1662
1663
return 0; /* failed */
1664
}
1665
1666
int /* PRIVATE */
1667
png_colorspace_set_endpoints(png_const_structrp png_ptr,
1668
png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
1669
{
1670
png_XYZ XYZ = *XYZ_in;
1671
png_xy xy;
1672
1673
switch (png_colorspace_check_XYZ(&xy, &XYZ))
1674
{
1675
case 0:
1676
return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
1677
preferred);
1678
1679
case 1:
1680
/* End points are invalid. */
1681
colorspace->flags |= PNG_COLORSPACE_INVALID;
1682
png_benign_error(png_ptr, "invalid end points");
1683
break;
1684
1685
default:
1686
colorspace->flags |= PNG_COLORSPACE_INVALID;
1687
impossible("error checking chromaticities");
1688
break;
1689
}
1690
1691
return 0; /* failed */
1692
}
1693
1694
#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
1695
/* Error message generation */
1696
static char
1697
png_icc_tag_char(png_uint_32 byte)
1698
{
1699
byte &= 0xff;
1700
if (byte >= 32 && byte <= 126)
1701
return (char)/*SAFE*/byte;
1702
else
1703
return '?';
1704
}
1705
1706
static void
1707
png_icc_tag_name(char *name, png_uint_32 tag)
1708
{
1709
name[0] = '\'';
1710
name[1] = png_icc_tag_char(tag >> 24);
1711
name[2] = png_icc_tag_char(tag >> 16);
1712
name[3] = png_icc_tag_char(tag >> 8);
1713
name[4] = png_icc_tag_char(tag );
1714
name[5] = '\'';
1715
}
1716
1717
static int
1718
is_ICC_signature_char(png_alloc_size_t it)
1719
{
1720
return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
1721
(it >= 97 && it <= 122);
1722
}
1723
1724
static int
1725
is_ICC_signature(png_alloc_size_t it)
1726
{
1727
return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
1728
is_ICC_signature_char((it >> 16) & 0xff) &&
1729
is_ICC_signature_char((it >> 8) & 0xff) &&
1730
is_ICC_signature_char(it & 0xff);
1731
}
1732
1733
static int
1734
png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
1735
png_const_charp name, png_alloc_size_t value, png_const_charp reason)
1736
{
1737
size_t pos;
1738
char message[196]; /* see below for calculation */
1739
1740
if (colorspace != NULL)
1741
colorspace->flags |= PNG_COLORSPACE_INVALID;
1742
1743
pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
1744
pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
1745
pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
1746
if (is_ICC_signature(value) != 0)
1747
{
1748
/* So 'value' is at most 4 bytes and the following cast is safe */
1749
png_icc_tag_name(message+pos, (png_uint_32)value);
1750
pos += 6; /* total +8; less than the else clause */
1751
message[pos++] = ':';
1752
message[pos++] = ' ';
1753
}
1754
# ifdef PNG_WARNINGS_SUPPORTED
1755
else
1756
{
1757
char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
1758
1759
pos = png_safecat(message, (sizeof message), pos,
1760
png_format_number(number, number+(sizeof number),
1761
PNG_NUMBER_FORMAT_x, value));
1762
pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
1763
}
1764
# endif
1765
/* The 'reason' is an arbitrary message, allow +79 maximum 195 */
1766
pos = png_safecat(message, (sizeof message), pos, reason);
1767
PNG_UNUSED(pos)
1768
1769
/* This is recoverable, but make it unconditionally an app_error on write to
1770
* avoid writing invalid ICC profiles into PNG files (i.e., we handle them
1771
* on read, with a warning, but on write unless the app turns off
1772
* application errors the PNG won't be written.)
1773
*/
1774
png_chunk_report(png_ptr, message,
1775
(colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
1776
1777
return 0;
1778
}
1779
#endif /* sRGB || iCCP */
1780
1781
#ifdef PNG_sRGB_SUPPORTED
1782
int /* PRIVATE */
1783
png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
1784
int intent)
1785
{
1786
/* sRGB sets known gamma, end points and (from the chunk) intent. */
1787
/* IMPORTANT: these are not necessarily the values found in an ICC profile
1788
* because ICC profiles store values adapted to a D50 environment; it is
1789
* expected that the ICC profile mediaWhitePointTag will be D50; see the
1790
* checks and code elsewhere to understand this better.
1791
*
1792
* These XYZ values, which are accurate to 5dp, produce rgb to gray
1793
* coefficients of (6968,23435,2366), which are reduced (because they add up
1794
* to 32769 not 32768) to (6968,23434,2366). These are the values that
1795
* libpng has traditionally used (and are the best values given the 15bit
1796
* algorithm used by the rgb to gray code.)
1797
*/
1798
static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
1799
{
1800
/* color X Y Z */
1801
/* red */ 41239, 21264, 1933,
1802
/* green */ 35758, 71517, 11919,
1803
/* blue */ 18048, 7219, 95053
1804
};
1805
1806
/* Do nothing if the colorspace is already invalidated. */
1807
if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
1808
return 0;
1809
1810
/* Check the intent, then check for existing settings. It is valid for the
1811
* PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
1812
* be consistent with the correct values. If, however, this function is
1813
* called below because an iCCP chunk matches sRGB then it is quite
1814
* conceivable that an older app recorded incorrect gAMA and cHRM because of
1815
* an incorrect calculation based on the values in the profile - this does
1816
* *not* invalidate the profile (though it still produces an error, which can
1817
* be ignored.)
1818
*/
1819
if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
1820
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
1821
(unsigned)intent, "invalid sRGB rendering intent");
1822
1823
if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
1824
colorspace->rendering_intent != intent)
1825
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
1826
(unsigned)intent, "inconsistent rendering intents");
1827
1828
if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
1829
{
1830
png_benign_error(png_ptr, "duplicate sRGB information ignored");
1831
return 0;
1832
}
1833
1834
/* If the standard sRGB cHRM chunk does not match the one from the PNG file
1835
* warn but overwrite the value with the correct one.
1836
*/
1837
if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
1838
!png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
1839
100))
1840
png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
1841
PNG_CHUNK_ERROR);
1842
1843
/* This check is just done for the error reporting - the routine always
1844
* returns true when the 'from' argument corresponds to sRGB (2).
1845
*/
1846
(void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
1847
2/*from sRGB*/);
1848
1849
/* intent: bugs in GCC force 'int' to be used as the parameter type. */
1850
colorspace->rendering_intent = png_check_u16(png_ptr, intent);
1851
colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
1852
1853
/* endpoints */
1854
colorspace->end_points_xy = sRGB_xy;
1855
colorspace->end_points_XYZ = sRGB_XYZ;
1856
colorspace->flags |=
1857
(PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
1858
1859
/* gamma */
1860
colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
1861
colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
1862
1863
/* Finally record that we have an sRGB profile */
1864
colorspace->flags |=
1865
(PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
1866
1867
return 1; /* set */
1868
}
1869
#endif /* sRGB */
1870
1871
#ifdef PNG_iCCP_SUPPORTED
1872
/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
1873
* is XYZ(0.9642,1.0,0.8249), which scales to:
1874
*
1875
* (63189.8112, 65536, 54060.6464)
1876
*/
1877
static const png_byte D50_nCIEXYZ[12] =
1878
{ 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
1879
1880
int /* PRIVATE */
1881
png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
1882
png_const_charp name, png_uint_32 profile_length)
1883
{
1884
if (profile_length < 132)
1885
return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
1886
"too short");
1887
1888
if (profile_length & 3)
1889
return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
1890
"invalid length");
1891
1892
return 1;
1893
}
1894
1895
int /* PRIVATE */
1896
png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
1897
png_const_charp name, png_uint_32 profile_length,
1898
png_const_bytep profile/* first 132 bytes only */, int is_color)
1899
{
1900
png_uint_32 temp;
1901
1902
/* Length check; this cannot be ignored in this code because profile_length
1903
* is used later to check the tag table, so even if the profile seems over
1904
* long profile_length from the caller must be correct. The caller can fix
1905
* this up on read or write by just passing in the profile header length.
1906
*/
1907
temp = png_get_uint_32(profile);
1908
if (temp != profile_length)
1909
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1910
"length does not match profile");
1911
1912
temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
1913
if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
1914
profile_length < 132+12*temp) /* truncated tag table */
1915
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1916
"tag count too large");
1917
1918
/* The 'intent' must be valid or we can't store it, ICC limits the intent to
1919
* 16 bits.
1920
*/
1921
temp = png_get_uint_32(profile+64);
1922
if (temp >= 0xffff) /* The ICC limit */
1923
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1924
"invalid rendering intent");
1925
1926
/* This is just a warning because the profile may be valid in future
1927
* versions.
1928
*/
1929
if (temp >= PNG_sRGB_INTENT_LAST)
1930
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
1931
"intent outside defined range");
1932
1933
/* At this point the tag table can't be checked because it hasn't necessarily
1934
* been loaded; however, various header fields can be checked. These checks
1935
* are for values permitted by the PNG spec in an ICC profile; the PNG spec
1936
* restricts the profiles that can be passed in an iCCP chunk (they must be
1937
* appropriate to processing PNG data!)
1938
*/
1939
1940
/* Data checks (could be skipped). These checks must be independent of the
1941
* version number; however, the version number doesn't accomodate changes in
1942
* the header fields (just the known tags and the interpretation of the
1943
* data.)
1944
*/
1945
temp = png_get_uint_32(profile+36); /* signature 'ascp' */
1946
if (temp != 0x61637370)
1947
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1948
"invalid signature");
1949
1950
/* Currently the PCS illuminant/adopted white point (the computational
1951
* white point) are required to be D50,
1952
* however the profile contains a record of the illuminant so perhaps ICC
1953
* expects to be able to change this in the future (despite the rationale in
1954
* the introduction for using a fixed PCS adopted white.) Consequently the
1955
* following is just a warning.
1956
*/
1957
if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
1958
(void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
1959
"PCS illuminant is not D50");
1960
1961
/* The PNG spec requires this:
1962
* "If the iCCP chunk is present, the image samples conform to the colour
1963
* space represented by the embedded ICC profile as defined by the
1964
* International Color Consortium [ICC]. The colour space of the ICC profile
1965
* shall be an RGB colour space for colour images (PNG colour types 2, 3, and
1966
* 6), or a greyscale colour space for greyscale images (PNG colour types 0
1967
* and 4)."
1968
*
1969
* This checking code ensures the embedded profile (on either read or write)
1970
* conforms to the specification requirements. Notice that an ICC 'gray'
1971
* color-space profile contains the information to transform the monochrome
1972
* data to XYZ or L*a*b (according to which PCS the profile uses) and this
1973
* should be used in preference to the standard libpng K channel replication
1974
* into R, G and B channels.
1975
*
1976
* Previously it was suggested that an RGB profile on grayscale data could be
1977
* handled. However it it is clear that using an RGB profile in this context
1978
* must be an error - there is no specification of what it means. Thus it is
1979
* almost certainly more correct to ignore the profile.
1980
*/
1981
temp = png_get_uint_32(profile+16); /* data colour space field */
1982
switch (temp)
1983
{
1984
case 0x52474220: /* 'RGB ' */
1985
if (!is_color)
1986
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1987
"RGB color space not permitted on grayscale PNG");
1988
break;
1989
1990
case 0x47524159: /* 'GRAY' */
1991
if (is_color)
1992
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1993
"Gray color space not permitted on RGB PNG");
1994
break;
1995
1996
default:
1997
return png_icc_profile_error(png_ptr, colorspace, name, temp,
1998
"invalid ICC profile color space");
1999
}
2000
2001
/* It is up to the application to check that the profile class matches the
2002
* application requirements; the spec provides no guidance, but it's pretty
2003
* weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
2004
* ('prtr') or 'spac' (for generic color spaces). Issue a warning in these
2005
* cases. Issue an error for device link or abstract profiles - these don't
2006
* contain the records necessary to transform the color-space to anything
2007
* other than the target device (and not even that for an abstract profile).
2008
* Profiles of these classes may not be embedded in images.
2009
*/
2010
temp = png_get_uint_32(profile+12); /* profile/device class */
2011
switch (temp)
2012
{
2013
case 0x73636E72: /* 'scnr' */
2014
case 0x6D6E7472: /* 'mntr' */
2015
case 0x70727472: /* 'prtr' */
2016
case 0x73706163: /* 'spac' */
2017
/* All supported */
2018
break;
2019
2020
case 0x61627374: /* 'abst' */
2021
/* May not be embedded in an image */
2022
return png_icc_profile_error(png_ptr, colorspace, name, temp,
2023
"invalid embedded Abstract ICC profile");
2024
2025
case 0x6C696E6B: /* 'link' */
2026
/* DeviceLink profiles cannot be interpreted in a non-device specific
2027
* fashion, if an app uses the AToB0Tag in the profile the results are
2028
* undefined unless the result is sent to the intended device,
2029
* therefore a DeviceLink profile should not be found embedded in a
2030
* PNG.
2031
*/
2032
return png_icc_profile_error(png_ptr, colorspace, name, temp,
2033
"unexpected DeviceLink ICC profile class");
2034
2035
case 0x6E6D636C: /* 'nmcl' */
2036
/* A NamedColor profile is also device specific, however it doesn't
2037
* contain an AToB0 tag that is open to misinterpretation. Almost
2038
* certainly it will fail the tests below.
2039
*/
2040
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
2041
"unexpected NamedColor ICC profile class");
2042
break;
2043
2044
default:
2045
/* To allow for future enhancements to the profile accept unrecognized
2046
* profile classes with a warning, these then hit the test below on the
2047
* tag content to ensure they are backward compatible with one of the
2048
* understood profiles.
2049
*/
2050
(void)png_icc_profile_error(png_ptr, NULL, name, temp,
2051
"unrecognized ICC profile class");
2052
break;
2053
}
2054
2055
/* For any profile other than a device link one the PCS must be encoded
2056
* either in XYZ or Lab.
2057
*/
2058
temp = png_get_uint_32(profile+20);
2059
switch (temp)
2060
{
2061
case 0x58595A20: /* 'XYZ ' */
2062
case 0x4C616220: /* 'Lab ' */
2063
break;
2064
2065
default:
2066
return png_icc_profile_error(png_ptr, colorspace, name, temp,
2067
"unexpected ICC PCS encoding");
2068
}
2069
2070
return 1;
2071
}
2072
2073
int /* PRIVATE */
2074
png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
2075
png_const_charp name, png_uint_32 profile_length,
2076
png_const_bytep profile /* header plus whole tag table */)
2077
{
2078
png_uint_32 tag_count = png_get_uint_32(profile+128);
2079
png_uint_32 itag;
2080
png_const_bytep tag = profile+132; /* The first tag */
2081
2082
/* First scan all the tags in the table and add bits to the icc_info value
2083
* (temporarily in 'tags').
2084
*/
2085
for (itag=0; itag < tag_count; ++itag, tag += 12)
2086
{
2087
png_uint_32 tag_id = png_get_uint_32(tag+0);
2088
png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
2089
png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
2090
2091
/* The ICC specification does not exclude zero length tags, therefore the
2092
* start might actually be anywhere if there is no data, but this would be
2093
* a clear abuse of the intent of the standard so the start is checked for
2094
* being in range. All defined tag types have an 8 byte header - a 4 byte
2095
* type signature then 0.
2096
*/
2097
if ((tag_start & 3) != 0)
2098
{
2099
/* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
2100
* only a warning here because libpng does not care about the
2101
* alignment.
2102
*/
2103
(void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
2104
"ICC profile tag start not a multiple of 4");
2105
}
2106
2107
/* This is a hard error; potentially it can cause read outside the
2108
* profile.
2109
*/
2110
if (tag_start > profile_length || tag_length > profile_length - tag_start)
2111
return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
2112
"ICC profile tag outside profile");
2113
}
2114
2115
return 1; /* success, maybe with warnings */
2116
}
2117
2118
#ifdef PNG_sRGB_SUPPORTED
2119
#if PNG_sRGB_PROFILE_CHECKS >= 0
2120
/* Information about the known ICC sRGB profiles */
2121
static const struct
2122
{
2123
png_uint_32 adler, crc, length;
2124
png_uint_32 md5[4];
2125
png_byte have_md5;
2126
png_byte is_broken;
2127
png_uint_16 intent;
2128
2129
# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
2130
# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
2131
{ adler, crc, length, md5, broke, intent },
2132
2133
} png_sRGB_checks[] =
2134
{
2135
/* This data comes from contrib/tools/checksum-icc run on downloads of
2136
* all four ICC sRGB profiles from www.color.org.
2137
*/
2138
/* adler32, crc32, MD5[4], intent, date, length, file-name */
2139
PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
2140
PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
2141
"2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
2142
2143
/* ICC sRGB v2 perceptual no black-compensation: */
2144
PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
2145
PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
2146
"2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
2147
2148
PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
2149
PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
2150
"2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
2151
2152
/* ICC sRGB v4 perceptual */
2153
PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
2154
PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
2155
"2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
2156
2157
/* The following profiles have no known MD5 checksum. If there is a match
2158
* on the (empty) MD5 the other fields are used to attempt a match and
2159
* a warning is produced. The first two of these profiles have a 'cprt' tag
2160
* which suggests that they were also made by Hewlett Packard.
2161
*/
2162
PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
2163
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
2164
"2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
2165
2166
/* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
2167
* match the D50 PCS illuminant in the header (it is in fact the D65 values,
2168
* so the white point is recorded as the un-adapted value.) The profiles
2169
* below only differ in one byte - the intent - and are basically the same as
2170
* the previous profile except for the mediaWhitePointTag error and a missing
2171
* chromaticAdaptationTag.
2172
*/
2173
PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
2174
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
2175
"1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
2176
2177
PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
2178
PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
2179
"1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
2180
};
2181
2182
static int
2183
png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
2184
png_const_bytep profile, uLong adler)
2185
{
2186
/* The quick check is to verify just the MD5 signature and trust the
2187
* rest of the data. Because the profile has already been verified for
2188
* correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
2189
* field too, so if the profile has been edited with an intent not defined
2190
* by sRGB (but maybe defined by a later ICC specification) the read of
2191
* the profile will fail at that point.
2192
*/
2193
png_uint_32 length = 0;
2194
png_uint_32 intent = 0x10000; /* invalid */
2195
#if PNG_sRGB_PROFILE_CHECKS > 1
2196
uLong crc = 0; /* the value for 0 length data */
2197
#endif
2198
unsigned int i;
2199
2200
# ifdef PNG_SET_OPTION_SUPPORTED
2201
# ifdef PNG_SKIP_sRGB_CHECK_PROFILE
2202
/* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
2203
if (!png_ptr->skip_sRGB_profile_check)
2204
# endif /* SKIP_sRGB_CHECK_PROFILE */
2205
# endif /* SET_OPTION */
2206
for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
2207
{
2208
if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
2209
png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
2210
png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
2211
png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
2212
{
2213
/* This may be one of the old HP profiles without an MD5, in that
2214
* case we can only use the length and Adler32 (note that these
2215
* are not used by default if there is an MD5!)
2216
*/
2217
# if PNG_sRGB_PROFILE_CHECKS == 0
2218
if (png_sRGB_checks[i].have_md5 != 0)
2219
return 1+png_sRGB_checks[i].is_broken;
2220
# endif
2221
2222
/* Profile is unsigned or more checks have been configured in. */
2223
if (length == 0)
2224
{
2225
length = png_get_uint_32(profile);
2226
intent = png_get_uint_32(profile+64);
2227
}
2228
2229
/* Length *and* intent must match */
2230
if (length == png_sRGB_checks[i].length &&
2231
intent == (png_uint_32) png_sRGB_checks[i].intent)
2232
{
2233
/* Now calculate the adler32 if not done already. */
2234
if (adler == 0)
2235
{
2236
adler = adler32(0, NULL, 0);
2237
adler = adler32(adler, profile, length);
2238
}
2239
2240
if (adler == png_sRGB_checks[i].adler)
2241
{
2242
/* These basic checks suggest that the data has not been
2243
* modified, but if the check level is more than 1 perform
2244
* our own crc32 checksum on the data.
2245
*/
2246
# if PNG_sRGB_PROFILE_CHECKS > 1
2247
if (crc == 0)
2248
{
2249
crc = crc32(0, NULL, 0);
2250
crc = crc32(crc, profile, length);
2251
}
2252
2253
/* So this check must pass for the 'return' below to happen.
2254
*/
2255
if (crc == png_sRGB_checks[i].crc)
2256
# endif
2257
{
2258
if (png_sRGB_checks[i].is_broken != 0)
2259
{
2260
/* These profiles are known to have bad data that may cause
2261
* problems if they are used, therefore attempt to
2262
* discourage their use, skip the 'have_md5' warning below,
2263
* which is made irrelevant by this error.
2264
*/
2265
png_chunk_report(png_ptr, "known incorrect sRGB profile",
2266
PNG_CHUNK_ERROR);
2267
}
2268
2269
/* Warn that this being done; this isn't even an error since
2270
* the profile is perfectly valid, but it would be nice if
2271
* people used the up-to-date ones.
2272
*/
2273
else if (png_sRGB_checks[i].have_md5 == 0)
2274
{
2275
png_chunk_report(png_ptr,
2276
"out-of-date sRGB profile with no signature",
2277
PNG_CHUNK_WARNING);
2278
}
2279
2280
return 1+png_sRGB_checks[i].is_broken;
2281
}
2282
}
2283
2284
# if PNG_sRGB_PROFILE_CHECKS > 0
2285
/* The signature matched, but the profile had been changed in some
2286
* way. This probably indicates a data error or uninformed hacking.
2287
* Fall through to "no match".
2288
*/
2289
png_chunk_report(png_ptr,
2290
"Not recognizing known sRGB profile that has been edited",
2291
PNG_CHUNK_WARNING);
2292
break;
2293
# endif
2294
}
2295
}
2296
}
2297
2298
return 0; /* no match */
2299
}
2300
2301
void /* PRIVATE */
2302
png_icc_set_sRGB(png_const_structrp png_ptr,
2303
png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
2304
{
2305
/* Is this profile one of the known ICC sRGB profiles? If it is, just set
2306
* the sRGB information.
2307
*/
2308
if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
2309
(void)png_colorspace_set_sRGB(png_ptr, colorspace,
2310
(int)/*already checked*/png_get_uint_32(profile+64));
2311
}
2312
#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
2313
#endif /* sRGB */
2314
2315
int /* PRIVATE */
2316
png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
2317
png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
2318
int is_color)
2319
{
2320
if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
2321
return 0;
2322
2323
if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
2324
png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
2325
is_color) != 0 &&
2326
png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
2327
profile) != 0)
2328
{
2329
# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
2330
/* If no sRGB support, don't try storing sRGB information */
2331
png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
2332
# endif
2333
return 1;
2334
}
2335
2336
/* Failure case */
2337
return 0;
2338
}
2339
#endif /* iCCP */
2340
#endif /* COLORSPACE */
2341
2342
png_alloc_size_t /* PRIVATE */
2343
png_calc_rowbytes(png_const_structrp png_ptr, unsigned int pixel_depth,
2344
png_uint_32 row_width)
2345
{
2346
png_alloc_size_t rowbytes = row_width;
2347
2348
/* Carefully calculate the row buffer size. */
2349
if (pixel_depth > 8)
2350
{
2351
if ((pixel_depth & 7) != 0)
2352
png_error(png_ptr, "unsupported pixel byte size");
2353
2354
pixel_depth >>= 3; /* Now in bytes */
2355
2356
if (rowbytes > PNG_SIZE_MAX/pixel_depth)
2357
png_error(png_ptr, "image row exceeds system limits");
2358
2359
rowbytes *= pixel_depth;
2360
}
2361
2362
else /* Less than 1 byte per pixel */ switch (pixel_depth)
2363
{
2364
case 1: rowbytes += 7; rowbytes >>= 3; break;
2365
case 2: rowbytes += 3; rowbytes >>= 2; break;
2366
case 4: rowbytes += 1; rowbytes >>= 1; break;
2367
case 8: break;
2368
default:
2369
png_error(png_ptr, "unsupported pixel bit size");
2370
}
2371
2372
return rowbytes;
2373
}
2374
2375
unsigned int /*PRIVATE*/
2376
png_max_pixel_block(png_const_structrp png_ptr)
2377
{
2378
/* Need the *smallest* pixel size that must occur in alignment units. On
2379
* read this is the PNG pixel depth because the read transforms cannot reduce
2380
* the pixel size below the input size or 8-bits, whichever is smaller.
2381
*
2382
* On write the 'pack' transform can pack 8-bit pixels back to a lower bit
2383
* depth, but the lowest bit depth is still given by the PNG pixel size.
2384
*/
2385
const unsigned int pixel_depth = PNG_PIXEL_DEPTH(*png_ptr);
2386
const unsigned int pixel_block = /* count of pixels in a block */
2387
pixel_depth < 8U ?
2388
PNG_ROW_BUFFER_BYTE_ALIGN * (8U/pixel_depth) :
2389
PNG_ROW_BUFFER_BYTE_ALIGN; /* pixels may be any whole byte size */
2390
/* The maximum block size in bits is MAX_PIXEL_DEPTH*pixel_block so work out
2391
* the minimum number of pixel blocks that can fit in PNG_ROW_BUFFER_SIZE
2392
* bytes and use this to calculate the maximum number of pixels:
2393
*/
2394
return pixel_block *
2395
((8U*PNG_ROW_BUFFER_SIZE) / (png_ptr->row_max_pixel_depth*pixel_block));
2396
}
2397
2398
void /* PRIVATE */
2399
png_copy_row(png_const_structrp png_ptr, png_bytep dp, png_const_bytep sp,
2400
png_uint_32 x/*in INPUT*/, png_uint_32 width/*of INPUT*/,
2401
unsigned int pixel_depth, int clear/*clear the final byte*/, int x_in_dest)
2402
/* Copy the row in row_buffer; this is the non-interlaced copy used in both
2403
* the read and write code. 'x_in_dest' specifies whether the 'x' applies to
2404
* the destination (sp->dp[x], x_in_dest tru) or the source (sp[x]->dp,
2405
* x_in_dest false).
2406
*/
2407
{
2408
png_alloc_size_t cb, offset;
2409
unsigned int remaining; /* remaining bits in a partial byte */
2410
2411
/* Copy 'cb' pixels, but take care with the last byte because it may
2412
* be partially written. 'x' must correspond to the start of a byte, check
2413
* that too:
2414
*/
2415
switch (pixel_depth)
2416
{
2417
case 1U: remaining = width & 7U;
2418
debug((x & 7U) == 0U);
2419
cb = width >> 3;
2420
offset = x >> 3;
2421
break;
2422
case 2U: remaining = (width << 1) & 6U;
2423
debug((x & 3U) == 0U);
2424
cb = width >> 2;
2425
offset = x >> 2;
2426
break;
2427
case 4U: remaining = (width << 2) & 4U;
2428
debug((x & 1U) == 0U);
2429
cb = width >> 1;
2430
offset = x >> 1;
2431
break;
2432
case 8U: remaining = 0U;
2433
cb = width;
2434
offset = x;
2435
break;
2436
default: remaining = 0U;
2437
cb = png_calc_rowbytes(png_ptr, pixel_depth, width);
2438
offset = png_calc_rowbytes(png_ptr, pixel_depth, x);
2439
break;
2440
}
2441
2442
if (x_in_dest)
2443
dp += offset;
2444
2445
else
2446
sp += offset;
2447
2448
memcpy(dp, sp, cb);
2449
2450
if (remaining > 0U)
2451
{
2452
/* 'remaining' is the number of bits still to be copied. Format may be
2453
* little endian; bits to copy in the bottom of 's'. Make 'remaining'
2454
* into a mask of the bits to *preserve* in dp.
2455
*/
2456
# ifdef PNG_TRANSFORM_MECH_SUPPORTED
2457
if ((png_ptr->row_format & PNG_FORMAT_FLAG_SWAPPED) == 0U)
2458
remaining = 0xffU >> remaining;
2459
2460
else
2461
# endif /* TRANSFORM_MECH */
2462
remaining = 0xffU << remaining;
2463
2464
/* remaining is now the bits to *keep* from the destination byte, if
2465
* 'clear' is true the source bytes aren't copied - this is for security
2466
* reasons to avoid copying undefined bits at the end of a row. If
2467
* 'clear' is set the destination bits are not preserved, they are just
2468
* set to 0.
2469
*/
2470
if (clear)
2471
dp[cb] = PNG_BYTE(sp[cb] & ~remaining);
2472
2473
else
2474
dp[cb] = PNG_BYTE((sp[cb] & ~remaining) | (dp[cb] & remaining));
2475
}
2476
}
2477
2478
void /* PRIVATE */
2479
png_check_IHDR(png_const_structrp png_ptr,
2480
png_uint_32 width, png_uint_32 height, int bit_depth,
2481
int color_type, int interlace_type, int compression_type,
2482
int filter_type)
2483
{
2484
int error = 0;
2485
2486
/* Check for width and height valid values */
2487
if (width == 0)
2488
{
2489
png_warning(png_ptr, "Image width is zero in IHDR");
2490
error = 1;
2491
}
2492
2493
if (width > PNG_UINT_31_MAX)
2494
{
2495
png_warning(png_ptr, "Invalid image width in IHDR");
2496
error = 1;
2497
}
2498
2499
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2500
if (width > png_ptr->user_width_max)
2501
{
2502
png_warning(png_ptr, "Image width exceeds user limit in IHDR");
2503
error = 1;
2504
}
2505
#else
2506
if (width > PNG_USER_WIDTH_MAX)
2507
{
2508
png_warning(png_ptr, "Image width exceeds WIDTH_MAX in IHDR");
2509
error = 1;
2510
}
2511
#endif
2512
2513
if (height == 0)
2514
{
2515
png_warning(png_ptr, "Image height is zero in IHDR");
2516
error = 1;
2517
}
2518
2519
if (height > PNG_UINT_31_MAX)
2520
{
2521
png_warning(png_ptr, "Invalid image height in IHDR");
2522
error = 1;
2523
}
2524
2525
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
2526
if (height > png_ptr->user_height_max)
2527
{
2528
png_warning(png_ptr, "Image height exceeds user limit in IHDR");
2529
error = 1;
2530
}
2531
#else
2532
if (height > PNG_USER_HEIGHT_MAX)
2533
{
2534
png_warning(png_ptr, "Image height exceeds HEIGHT_MAX in IHDR");
2535
error = 1;
2536
}
2537
#endif
2538
2539
/* Check other values */
2540
if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
2541
bit_depth != 8 && bit_depth != 16)
2542
{
2543
png_warning(png_ptr, "Invalid bit depth in IHDR");
2544
error = 1;
2545
}
2546
2547
if (color_type < 0 || color_type == 1 ||
2548
color_type == 5 || color_type > 6)
2549
{
2550
png_warning(png_ptr, "Invalid color type in IHDR");
2551
error = 1;
2552
}
2553
2554
if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
2555
((color_type == PNG_COLOR_TYPE_RGB ||
2556
color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
2557
color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
2558
{
2559
png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
2560
error = 1;
2561
}
2562
2563
if (interlace_type >= PNG_INTERLACE_LAST)
2564
{
2565
png_warning(png_ptr, "Unknown interlace method in IHDR");
2566
error = 1;
2567
}
2568
2569
if (compression_type != PNG_COMPRESSION_TYPE_BASE)
2570
{
2571
png_warning(png_ptr, "Unknown compression method in IHDR");
2572
error = 1;
2573
}
2574
2575
#ifdef PNG_MNG_FEATURES_SUPPORTED
2576
/* Accept filter_method 64 (intrapixel differencing) only if
2577
* 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
2578
* 2. Libpng did not read a PNG signature (this filter_method is only
2579
* used in PNG datastreams that are embedded in MNG datastreams) and
2580
* 3. The application called png_permit_mng_features with a mask that
2581
* included PNG_FLAG_MNG_FILTER_64 and
2582
* 4. The filter_method is 64 and
2583
* 5. The color_type is RGB or RGBA
2584
*/
2585
if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
2586
png_ptr->mng_features_permitted != 0)
2587
png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
2588
2589
if (filter_type != PNG_FILTER_TYPE_BASE)
2590
{
2591
if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
2592
(filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
2593
((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
2594
(color_type == PNG_COLOR_TYPE_RGB ||
2595
color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
2596
{
2597
png_warning(png_ptr, "Invalid filter method in IHDR");
2598
error = 1;
2599
}
2600
2601
if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
2602
{
2603
png_warning(png_ptr, "Invalid filter method in IHDR");
2604
error = 1;
2605
}
2606
}
2607
2608
#else /* !MNG_FEATURES */
2609
if (filter_type != PNG_FILTER_TYPE_BASE)
2610
{
2611
png_warning(png_ptr, "Unknown filter method in IHDR");
2612
error = 1;
2613
}
2614
#endif /* !MNG_FEATURES */
2615
2616
if (error == 1)
2617
png_error(png_ptr, "Invalid IHDR data");
2618
2619
/* Finally, if the IHDR data is correct, check it against the system
2620
* limits (NOTE: this need not be done; the IDAT handling code repeats the
2621
* check in both read and write.)
2622
*/
2623
(void)png_calc_rowbytes(png_ptr,
2624
PNG_COLOR_TYPE_CHANNELS(color_type) * bit_depth, width);
2625
}
2626
2627
#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
2628
/* ASCII to fp functions */
2629
/* Check an ASCII formated floating point value, see the more detailed
2630
* comments in pngpriv.h
2631
*/
2632
/* The following is used internally to preserve the sticky flags */
2633
#define png_fp_add(state, flags) ((state) |= (flags))
2634
#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
2635
2636
int /* PRIVATE */
2637
png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
2638
png_size_tp whereami)
2639
{
2640
int state = *statep;
2641
png_size_t i = *whereami;
2642
2643
while (i < size)
2644
{
2645
int type;
2646
/* First find the type of the next character */
2647
switch (string[i])
2648
{
2649
case 43: type = PNG_FP_SAW_SIGN; break;
2650
case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
2651
case 46: type = PNG_FP_SAW_DOT; break;
2652
case 48: type = PNG_FP_SAW_DIGIT; break;
2653
case 49: case 50: case 51: case 52:
2654
case 53: case 54: case 55: case 56:
2655
case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
2656
case 69:
2657
case 101: type = PNG_FP_SAW_E; break;
2658
default: goto PNG_FP_End;
2659
}
2660
2661
/* Now deal with this type according to the current
2662
* state, the type is arranged to not overlap the
2663
* bits of the PNG_FP_STATE.
2664
*/
2665
switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
2666
{
2667
case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
2668
if ((state & PNG_FP_SAW_ANY) != 0)
2669
goto PNG_FP_End; /* not a part of the number */
2670
2671
png_fp_add(state, type);
2672
break;
2673
2674
case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
2675
/* Ok as trailer, ok as lead of fraction. */
2676
if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
2677
goto PNG_FP_End;
2678
2679
else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
2680
png_fp_add(state, type);
2681
2682
else
2683
png_fp_set(state, PNG_FP_FRACTION | type);
2684
2685
break;
2686
2687
case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
2688
if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
2689
png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
2690
2691
png_fp_add(state, type | PNG_FP_WAS_VALID);
2692
2693
break;
2694
2695
case PNG_FP_INTEGER + PNG_FP_SAW_E:
2696
if ((state & PNG_FP_SAW_DIGIT) == 0)
2697
goto PNG_FP_End;
2698
2699
png_fp_set(state, PNG_FP_EXPONENT);
2700
2701
break;
2702
2703
/* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
2704
goto PNG_FP_End; ** no sign in fraction */
2705
2706
/* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
2707
goto PNG_FP_End; ** Because SAW_DOT is always set */
2708
2709
case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
2710
png_fp_add(state, type | PNG_FP_WAS_VALID);
2711
break;
2712
2713
case PNG_FP_FRACTION + PNG_FP_SAW_E:
2714
/* This is correct because the trailing '.' on an
2715
* integer is handled above - so we can only get here
2716
* with the sequence ".E" (with no preceding digits).
2717
*/
2718
if ((state & PNG_FP_SAW_DIGIT) == 0)
2719
goto PNG_FP_End;
2720
2721
png_fp_set(state, PNG_FP_EXPONENT);
2722
2723
break;
2724
2725
case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
2726
if ((state & PNG_FP_SAW_ANY) != 0)
2727
goto PNG_FP_End; /* not a part of the number */
2728
2729
png_fp_add(state, PNG_FP_SAW_SIGN);
2730
2731
break;
2732
2733
/* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
2734
goto PNG_FP_End; */
2735
2736
case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
2737
png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
2738
2739
break;
2740
2741
/* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
2742
goto PNG_FP_End; */
2743
2744
default: goto PNG_FP_End; /* I.e. break 2 */
2745
}
2746
2747
/* The character seems ok, continue. */
2748
++i;
2749
}
2750
2751
PNG_FP_End:
2752
/* Here at the end, update the state and return the correct
2753
* return code.
2754
*/
2755
*statep = state;
2756
*whereami = i;
2757
2758
return (state & PNG_FP_SAW_DIGIT) != 0;
2759
}
2760
2761
2762
/* The same but for a complete string. */
2763
int
2764
png_check_fp_string(png_const_charp string, png_size_t size)
2765
{
2766
int state=0;
2767
png_size_t char_index=0;
2768
2769
if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
2770
(char_index == size || string[char_index] == 0))
2771
return state /* must be non-zero - see above */;
2772
2773
return 0; /* i.e. fail */
2774
}
2775
#endif /* pCAL || sCAL */
2776
2777
#ifdef PNG_sCAL_SUPPORTED
2778
# ifdef PNG_FLOATING_POINT_SUPPORTED
2779
/* Utility used below - a simple accurate power of ten from an integral
2780
* exponent.
2781
*/
2782
static double
2783
png_pow10(int power)
2784
{
2785
int recip = 0;
2786
double d = 1;
2787
2788
/* Handle negative exponent with a reciprocal at the end because
2789
* 10 is exact whereas .1 is inexact in base 2
2790
*/
2791
if (power < 0)
2792
{
2793
if (power < DBL_MIN_10_EXP) return 0;
2794
recip = 1; power = -power;
2795
}
2796
2797
if (power > 0)
2798
{
2799
/* Decompose power bitwise. */
2800
double mult = 10;
2801
do
2802
{
2803
if (power & 1) d *= mult;
2804
mult *= mult;
2805
power >>= 1;
2806
}
2807
while (power > 0);
2808
2809
if (recip != 0) d = 1/d;
2810
}
2811
/* else power is 0 and d is 1 */
2812
2813
return d;
2814
}
2815
2816
/* Function to format a floating point value in ASCII with a given
2817
* precision.
2818
*/
2819
void /* PRIVATE */
2820
png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
2821
double fp, unsigned int precision)
2822
{
2823
/* We use standard functions from math.h, but not printf because
2824
* that would require stdio. The caller must supply a buffer of
2825
* sufficient size or we will png_error. The tests on size and
2826
* the space in ascii[] consumed are indicated below.
2827
*/
2828
if (precision < 1)
2829
precision = DBL_DIG;
2830
2831
/* Enforce the limit of the implementation precision too. */
2832
if (precision > DBL_DIG+1)
2833
precision = DBL_DIG+1;
2834
2835
/* Basic sanity checks */
2836
if (size >= precision+5) /* See the requirements below. */
2837
{
2838
if (fp < 0)
2839
{
2840
fp = -fp;
2841
*ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */
2842
--size;
2843
}
2844
2845
if (fp >= DBL_MIN && fp <= DBL_MAX)
2846
{
2847
int exp_b10; /* A base 10 exponent */
2848
double base; /* 10^exp_b10 */
2849
2850
/* First extract a base 10 exponent of the number,
2851
* the calculation below rounds down when converting
2852
* from base 2 to base 10 (multiply by log10(2) -
2853
* 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
2854
* be increased. Note that the arithmetic shift
2855
* performs a floor() unlike C arithmetic - using a
2856
* C multiply would break the following for negative
2857
* exponents.
2858
*/
2859
(void)frexp(fp, &exp_b10); /* exponent to base 2 */
2860
2861
exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
2862
2863
/* Avoid underflow here. */
2864
base = png_pow10(exp_b10); /* May underflow */
2865
2866
while (base < DBL_MIN || base < fp)
2867
{
2868
/* And this may overflow. */
2869
double test = png_pow10(exp_b10+1);
2870
2871
if (test <= DBL_MAX)
2872
{
2873
++exp_b10; base = test;
2874
}
2875
2876
else
2877
break;
2878
}
2879
2880
/* Normalize fp and correct exp_b10, after this fp is in the
2881
* range [.1,1) and exp_b10 is both the exponent and the digit
2882
* *before* which the decimal point should be inserted
2883
* (starting with 0 for the first digit). Note that this
2884
* works even if 10^exp_b10 is out of range because of the
2885
* test on DBL_MAX above.
2886
*/
2887
fp /= base;
2888
while (fp >= 1)
2889
{
2890
fp /= 10; ++exp_b10;
2891
}
2892
2893
/* Because of the code above fp may, at this point, be
2894
* less than .1, this is ok because the code below can
2895
* handle the leading zeros this generates, so no attempt
2896
* is made to correct that here.
2897
*/
2898
2899
{
2900
unsigned int czero, clead, cdigits;
2901
char exponent[10];
2902
2903
/* Allow up to two leading zeros - this will not lengthen
2904
* the number compared to using E-n.
2905
*/
2906
if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
2907
{
2908
czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
2909
exp_b10 = 0; /* Dot added below before first output. */
2910
}
2911
else
2912
czero = 0; /* No zeros to add */
2913
2914
/* Generate the digit list, stripping trailing zeros and
2915
* inserting a '.' before a digit if the exponent is 0.
2916
*/
2917
clead = czero; /* Count of leading zeros */
2918
cdigits = 0; /* Count of digits in list. */
2919
2920
do
2921
{
2922
double d;
2923
2924
fp *= 10;
2925
/* Use modf here, not floor and subtract, so that
2926
* the separation is done in one step. At the end
2927
* of the loop don't break the number into parts so
2928
* that the final digit is rounded.
2929
*/
2930
if (cdigits+czero+1 < precision+clead)
2931
fp = modf(fp, &d);
2932
2933
else
2934
{
2935
d = floor(fp + .5);
2936
2937
if (d > 9)
2938
{
2939
/* Rounding up to 10, handle that here. */
2940
if (czero > 0)
2941
{
2942
--czero; d = 1;
2943
if (cdigits == 0) --clead;
2944
}
2945
else
2946
{
2947
while (cdigits > 0 && d > 9)
2948
{
2949
int ch = *--ascii;
2950
2951
if (exp_b10 != (-1))
2952
++exp_b10;
2953
2954
else if (ch == 46)
2955
{
2956
ch = *--ascii; ++size;
2957
/* Advance exp_b10 to '1', so that the
2958
* decimal point happens after the
2959
* previous digit.
2960
*/
2961
exp_b10 = 1;
2962
}
2963
2964
--cdigits;
2965
d = ch - 47; /* I.e. 1+(ch-48) */
2966
}
2967
2968
/* Did we reach the beginning? If so adjust the
2969
* exponent but take into account the leading
2970
* decimal point.
2971
*/
2972
if (d > 9) /* cdigits == 0 */
2973
{
2974
if (exp_b10 == (-1))
2975
{
2976
/* Leading decimal point (plus zeros?), if
2977
* we lose the decimal point here it must
2978
* be reentered below.
2979
*/
2980
int ch = *--ascii;
2981
2982
if (ch == 46)
2983
{
2984
++size; exp_b10 = 1;
2985
}
2986
2987
/* Else lost a leading zero, so 'exp_b10' is
2988
* still ok at (-1)
2989
*/
2990
}
2991
else
2992
++exp_b10;
2993
2994
/* In all cases we output a '1' */
2995
d = 1;
2996
}
2997
}
2998
}
2999
fp = 0; /* Guarantees termination below. */
3000
}
3001
3002
if (d == 0)
3003
{
3004
++czero;
3005
if (cdigits == 0) ++clead;
3006
}
3007
else
3008
{
3009
/* Included embedded zeros in the digit count. */
3010
cdigits += czero - clead;
3011
clead = 0;
3012
3013
while (czero > 0)
3014
{
3015
/* exp_b10 == (-1) means we just output the decimal
3016
* place - after the DP don't adjust 'exp_b10' any
3017
* more!
3018
*/
3019
if (exp_b10 != (-1))
3020
{
3021
if (exp_b10 == 0) *ascii++ = 46, --size;
3022
/* PLUS 1: TOTAL 4 */
3023
--exp_b10;
3024
}
3025
*ascii++ = 48, --czero;
3026
}
3027
3028
if (exp_b10 != (-1))
3029
{
3030
if (exp_b10 == 0)
3031
*ascii++ = 46, --size; /* counted above */
3032
3033
--exp_b10;
3034
}
3035
*ascii++ = png_check_char(png_ptr, 48 + (int)d), ++cdigits;
3036
}
3037
}
3038
while (cdigits+czero < precision+clead && fp > DBL_MIN);
3039
3040
/* The total output count (max) is now 4+precision */
3041
3042
/* Check for an exponent, if we don't need one we are
3043
* done and just need to terminate the string. At
3044
* this point exp_b10==(-1) is effectively if flag - it got
3045
* to '-1' because of the decrement after outputting
3046
* the decimal point above (the exponent required is
3047
* *not* -1!)
3048
*/
3049
if (exp_b10 >= (-1) && exp_b10 <= 2)
3050
{
3051
/* The following only happens if we didn't output the
3052
* leading zeros above for negative exponent, so this
3053
* doesn't add to the digit requirement. Note that the
3054
* two zeros here can only be output if the two leading
3055
* zeros were *not* output, so this doesn't increase
3056
* the output count.
3057
*/
3058
while (--exp_b10 >= 0) *ascii++ = 48;
3059
3060
*ascii = 0;
3061
3062
/* Total buffer requirement (including the '\0') is
3063
* 5+precision - see check at the start.
3064
*/
3065
return;
3066
}
3067
3068
/* Here if an exponent is required, adjust size for
3069
* the digits we output but did not count. The total
3070
* digit output here so far is at most 1+precision - no
3071
* decimal point and no leading or trailing zeros have
3072
* been output.
3073
*/
3074
size -= cdigits;
3075
3076
*ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */
3077
3078
/* The following use of an unsigned temporary avoids ambiguities in
3079
* the signed arithmetic on exp_b10 and permits GCC at least to do
3080
* better optimization.
3081
*/
3082
{
3083
unsigned int uexp_b10;
3084
3085
if (exp_b10 < 0)
3086
{
3087
*ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
3088
uexp_b10 = -exp_b10;
3089
}
3090
3091
else
3092
uexp_b10 = exp_b10;
3093
3094
cdigits = 0;
3095
3096
while (uexp_b10 > 0)
3097
{
3098
exponent[cdigits++] = (char)/*SAFE*/(48 + uexp_b10 % 10);
3099
uexp_b10 /= 10;
3100
}
3101
}
3102
3103
/* Need another size check here for the exponent digits, so
3104
* this need not be considered above.
3105
*/
3106
if (size > cdigits)
3107
{
3108
while (cdigits > 0) *ascii++ = exponent[--cdigits];
3109
3110
*ascii = 0;
3111
3112
return;
3113
}
3114
}
3115
}
3116
else if (!(fp >= DBL_MIN))
3117
{
3118
*ascii++ = 48; /* '0' */
3119
*ascii = 0;
3120
return;
3121
}
3122
else
3123
{
3124
*ascii++ = 105; /* 'i' */
3125
*ascii++ = 110; /* 'n' */
3126
*ascii++ = 102; /* 'f' */
3127
*ascii = 0;
3128
return;
3129
}
3130
}
3131
3132
/* Here on buffer too small. */
3133
png_error(png_ptr, "ASCII conversion buffer too small");
3134
}
3135
3136
# endif /* FLOATING_POINT */
3137
3138
# ifdef PNG_FIXED_POINT_SUPPORTED
3139
/* Function to format a fixed point value in ASCII.
3140
*/
3141
void /* PRIVATE */
3142
png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
3143
png_size_t size, png_fixed_point fp)
3144
{
3145
/* Require space for 10 decimal digits, a decimal point, a minus sign and a
3146
* trailing \0, 13 characters:
3147
*/
3148
if (size > 12)
3149
{
3150
png_uint_32 num;
3151
3152
/* Avoid overflow here on the minimum integer. */
3153
if (fp < 0)
3154
*ascii++ = 45, --size, num = -fp;
3155
else
3156
num = fp;
3157
3158
if (num <= 0x80000000) /* else overflowed */
3159
{
3160
unsigned int ndigits = 0, first = 16 /* flag value */;
3161
char digits[10];
3162
3163
while (num)
3164
{
3165
/* Split the low digit off num: */
3166
unsigned int tmp = num/10;
3167
num -= tmp*10;
3168
digits[ndigits++] = png_check_char(png_ptr, 48 + num);
3169
/* Record the first non-zero digit, note that this is a number
3170
* starting at 1, it's not actually the array index.
3171
*/
3172
if (first == 16 && num > 0)
3173
first = ndigits;
3174
num = tmp;
3175
}
3176
3177
if (ndigits > 0)
3178
{
3179
while (ndigits > 5) *ascii++ = digits[--ndigits];
3180
/* The remaining digits are fractional digits, ndigits is '5' or
3181
* smaller at this point. It is certainly not zero. Check for a
3182
* non-zero fractional digit:
3183
*/
3184
if (first <= 5)
3185
{
3186
unsigned int i;
3187
*ascii++ = 46; /* decimal point */
3188
/* ndigits may be <5 for small numbers, output leading zeros
3189
* then ndigits digits to first:
3190
*/
3191
i = 5;
3192
while (ndigits < i)
3193
{
3194
*ascii++ = 48; --i;
3195
}
3196
while (ndigits >= first) *ascii++ = digits[--ndigits];
3197
/* Don't output the trailing zeros! */
3198
}
3199
}
3200
else
3201
*ascii++ = 48;
3202
3203
/* And null terminate the string: */
3204
*ascii = 0;
3205
return;
3206
}
3207
}
3208
3209
/* Here on buffer too small. */
3210
png_error(png_ptr, "ASCII conversion buffer too small");
3211
}
3212
# endif /* FIXED_POINT */
3213
#endif /* SCAL */
3214
3215
#if !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && (\
3216
defined(PNG_FLOATING_POINT_SUPPORTED) && \
3217
(defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
3218
defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
3219
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
3220
(defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) &&\
3221
defined(PNG_sCAL_SUPPORTED)))
3222
png_fixed_point
3223
png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
3224
{
3225
if (fp < 0)
3226
{
3227
if (fp > -21474.836485)
3228
return (png_fixed_point)(100000*fp - .5);
3229
}
3230
3231
else
3232
{
3233
if (fp < 21474.836475)
3234
return (png_fixed_point)(100000*fp + .5);
3235
}
3236
3237
/* Overflow */
3238
png_fixed_error(png_ptr, text);
3239
3240
# ifndef PNG_ERROR_TEXT_SUPPORTED
3241
PNG_UNUSED(text)
3242
# endif
3243
}
3244
#endif
3245
3246
#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
3247
defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
3248
/* muldiv functions */
3249
/* This API takes signed arguments and rounds the result to the nearest
3250
* integer (or, for a fixed point number - the standard argument - to
3251
* the nearest .00001). Overflow and divide by zero are signalled in
3252
* the result, a boolean - true on success, false on overflow.
3253
*/
3254
int
3255
png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
3256
png_int_32 divisor)
3257
{
3258
/* Return a * times / divisor, rounded. */
3259
if (divisor != 0)
3260
{
3261
if (a == 0 || times == 0)
3262
{
3263
*res = 0;
3264
return 1;
3265
}
3266
else
3267
{
3268
#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
3269
double r = a;
3270
r *= times;
3271
r /= divisor;
3272
r = floor(r+.5);
3273
3274
/* A png_fixed_point is a 32-bit integer. */
3275
if (r <= 2147483647. && r >= -2147483648.)
3276
{
3277
*res = (png_fixed_point)r;
3278
return 1;
3279
}
3280
#else
3281
int negative = 0;
3282
png_uint_32 A, T, D;
3283
png_uint_32 s16, s32, s00;
3284
3285
if (a < 0)
3286
negative = 1, A = -a;
3287
else
3288
A = a;
3289
3290
if (times < 0)
3291
negative = !negative, T = -times;
3292
else
3293
T = times;
3294
3295
if (divisor < 0)
3296
negative = !negative, D = -divisor;
3297
else
3298
D = divisor;
3299
3300
/* Following can't overflow because the arguments only
3301
* have 31 bits each, however the result may be 32 bits.
3302
*/
3303
s16 = (A >> 16) * (T & 0xffff) +
3304
(A & 0xffff) * (T >> 16);
3305
/* Can't overflow because the a*times bit is only 30
3306
* bits at most.
3307
*/
3308
s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
3309
s00 = (A & 0xffff) * (T & 0xffff);
3310
3311
s16 = (s16 & 0xffff) << 16;
3312
s00 += s16;
3313
3314
if (s00 < s16)
3315
++s32; /* carry */
3316
3317
if (s32 < D) /* else overflow */
3318
{
3319
/* s32.s00 is now the 64-bit product, do a standard
3320
* division, we know that s32 < D, so the maximum
3321
* required shift is 31.
3322
*/
3323
int bitshift = 32;
3324
png_fixed_point result = 0; /* NOTE: signed */
3325
3326
while (--bitshift >= 0)
3327
{
3328
png_uint_32 d32, d00;
3329
3330
if (bitshift > 0)
3331
d32 = D >> (32-bitshift), d00 = D << bitshift;
3332
3333
else
3334
d32 = 0, d00 = D;
3335
3336
if (s32 > d32)
3337
{
3338
if (s00 < d00) --s32; /* carry */
3339
s32 -= d32, s00 -= d00, result += 1<<bitshift;
3340
}
3341
3342
else
3343
if (s32 == d32 && s00 >= d00)
3344
s32 = 0, s00 -= d00, result += 1<<bitshift;
3345
}
3346
3347
/* Handle the rounding. */
3348
if (s00 >= (D >> 1))
3349
++result;
3350
3351
if (negative != 0)
3352
result = -result;
3353
3354
/* Check for overflow. */
3355
if ((negative != 0 && result <= 0) ||
3356
(negative == 0 && result >= 0))
3357
{
3358
*res = result;
3359
return 1;
3360
}
3361
}
3362
#endif
3363
}
3364
}
3365
3366
return 0;
3367
}
3368
#endif /* GAMMA || INCH_CONVERSIONS */
3369
3370
/* SOFTWARE SETTING SUPPORT */
3371
png_int_32 PNGAPI
3372
png_setting(png_structrp png_ptr, png_uint_32 setting, png_uint_32 parameter,
3373
png_int_32 value)
3374
{
3375
png_int_32 result;
3376
3377
if (png_ptr != NULL)
3378
{
3379
int handle_error = (setting & PNG_SF_ERROR) != 0U;
3380
3381
setting &= ~PNG_SF_ERROR; /* because it is handled below. */
3382
3383
switch (setting & (PNG_SF_READ|PNG_SF_WRITE))
3384
{
3385
# ifdef PNG_READ_SUPPORTED
3386
case PNG_SF_READ:
3387
if (png_ptr->read_struct)
3388
result = png_read_setting(png_ptr, setting, parameter, value);
3389
3390
else
3391
result = PNG_EINVAL; /* read setting on write struct */
3392
break;
3393
# endif /* READ */
3394
3395
# ifdef PNG_WRITE_SUPPORTED
3396
case PNG_SF_WRITE:
3397
if (!png_ptr->read_struct)
3398
result = png_write_setting(png_ptr, setting, parameter,
3399
value);
3400
3401
else
3402
result = PNG_EINVAL; /* write setting on read struct */
3403
break;
3404
# endif /* WRITE */
3405
3406
default:
3407
/* Handle everything else here. This includes the error of not
3408
* having either read or write set; that error will cause a
3409
* PNG_ENOSYS return code.
3410
*/
3411
switch (setting)
3412
{
3413
# ifdef PNG_SET_OPTION_SUPPORTED
3414
case PNG_SRW_OPTION:
3415
if (parameter >= PNG_OPTION_NEXT)
3416
return PNG_OPTION_INVALID;
3417
3418
if (parameter == PNG_SKIP_sRGB_CHECK_PROFILE)
3419
{
3420
if (png_ptr->skip_sRGB_profile_check)
3421
{
3422
if (!value)
3423
png_ptr->skip_sRGB_profile_check = 0U;
3424
result = PNG_OPTION_ON;
3425
}
3426
3427
else
3428
{
3429
if (value)
3430
png_ptr->skip_sRGB_profile_check = 1U;
3431
result = PNG_OPTION_OFF;
3432
}
3433
3434
break;
3435
}
3436
3437
# ifdef PNG_READ_SUPPORTED
3438
if (png_ptr->read_struct)
3439
{
3440
result = png_read_setting(png_ptr, setting,
3441
parameter, value);
3442
break;
3443
}
3444
# endif /* READ */
3445
3446
/* No write options at present */
3447
result = PNG_OPTION_UNSET; /* i.e. ignore it */
3448
break;
3449
# endif /* SET_OPTION */
3450
3451
default:
3452
/* Any other option; handle in the appropriate setting: */
3453
# ifdef PNG_READ_SUPPORTED
3454
if (png_ptr->read_struct)
3455
{
3456
result = png_read_setting(png_ptr, setting,
3457
parameter, value);
3458
break;
3459
}
3460
# endif /* READ */
3461
3462
# ifdef PNG_WRITE_SUPPORTED
3463
if (!png_ptr->read_struct)
3464
{
3465
result = png_write_setting(png_ptr, setting,
3466
parameter, value);
3467
break;
3468
}
3469
# endif /* WRITE */
3470
3471
NOT_REACHED;
3472
result= PNG_ENOSYS;
3473
break;
3474
}
3475
break;
3476
} /* switch */
3477
3478
/* Handle error returns here.
3479
* TODO: this is crude, should use a formatted warning style message and
3480
* output result/setting/parameter/value.
3481
*/
3482
if (handle_error && PNG_FAILED(result))
3483
png_error(png_ptr, "png_setting");
3484
}
3485
3486
else /* png_ptr is NULL */
3487
result = PNG_EINVAL;
3488
3489
return result;
3490
PNG_UNUSED(parameter)
3491
PNG_UNUSED(value)
3492
}
3493
3494
/* sRGB support */
3495
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
3496
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
3497
/* sRGB conversion tables; these are machine generated with the code in
3498
* contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the
3499
* specification (see the article at https://en.wikipedia.org/wiki/SRGB)
3500
* is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
3501
* The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
3502
* The inverse (linear to sRGB) table has accuracies as follows:
3503
*
3504
* For all possible (255*65535+1) input values:
3505
*
3506
* error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
3507
*
3508
* For the input values corresponding to the 65536 16-bit values:
3509
*
3510
* error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
3511
*
3512
* In all cases the inexact readings are only off by one.
3513
*/
3514
3515
#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
3516
/* The convert-to-sRGB table is only currently required for read. */
3517
const png_uint_16 png_sRGB_table[256] =
3518
{
3519
0,20,40,60,80,99,119,139,
3520
159,179,199,219,241,264,288,313,
3521
340,367,396,427,458,491,526,562,
3522
599,637,677,718,761,805,851,898,
3523
947,997,1048,1101,1156,1212,1270,1330,
3524
1391,1453,1517,1583,1651,1720,1790,1863,
3525
1937,2013,2090,2170,2250,2333,2418,2504,
3526
2592,2681,2773,2866,2961,3058,3157,3258,
3527
3360,3464,3570,3678,3788,3900,4014,4129,
3528
4247,4366,4488,4611,4736,4864,4993,5124,
3529
5257,5392,5530,5669,5810,5953,6099,6246,
3530
6395,6547,6700,6856,7014,7174,7335,7500,
3531
7666,7834,8004,8177,8352,8528,8708,8889,
3532
9072,9258,9445,9635,9828,10022,10219,10417,
3533
10619,10822,11028,11235,11446,11658,11873,12090,
3534
12309,12530,12754,12980,13209,13440,13673,13909,
3535
14146,14387,14629,14874,15122,15371,15623,15878,
3536
16135,16394,16656,16920,17187,17456,17727,18001,
3537
18277,18556,18837,19121,19407,19696,19987,20281,
3538
20577,20876,21177,21481,21787,22096,22407,22721,
3539
23038,23357,23678,24002,24329,24658,24990,25325,
3540
25662,26001,26344,26688,27036,27386,27739,28094,
3541
28452,28813,29176,29542,29911,30282,30656,31033,
3542
31412,31794,32179,32567,32957,33350,33745,34143,
3543
34544,34948,35355,35764,36176,36591,37008,37429,
3544
37852,38278,38706,39138,39572,40009,40449,40891,
3545
41337,41785,42236,42690,43147,43606,44069,44534,
3546
45002,45473,45947,46423,46903,47385,47871,48359,
3547
48850,49344,49841,50341,50844,51349,51858,52369,
3548
52884,53401,53921,54445,54971,55500,56032,56567,
3549
57105,57646,58190,58737,59287,59840,60396,60955,
3550
61517,62082,62650,63221,63795,64372,64952,65535
3551
};
3552
3553
#endif /* SIMPLIFIED_READ */
3554
3555
/* The base/delta tables are required for both read and write (but currently
3556
* only the simplified versions.)
3557
*/
3558
const png_uint_16 png_sRGB_base[512] =
3559
{
3560
128,1782,3383,4644,5675,6564,7357,8074,
3561
8732,9346,9921,10463,10977,11466,11935,12384,
3562
12816,13233,13634,14024,14402,14769,15125,15473,
3563
15812,16142,16466,16781,17090,17393,17690,17981,
3564
18266,18546,18822,19093,19359,19621,19879,20133,
3565
20383,20630,20873,21113,21349,21583,21813,22041,
3566
22265,22487,22707,22923,23138,23350,23559,23767,
3567
23972,24175,24376,24575,24772,24967,25160,25352,
3568
25542,25730,25916,26101,26284,26465,26645,26823,
3569
27000,27176,27350,27523,27695,27865,28034,28201,
3570
28368,28533,28697,28860,29021,29182,29341,29500,
3571
29657,29813,29969,30123,30276,30429,30580,30730,
3572
30880,31028,31176,31323,31469,31614,31758,31902,
3573
32045,32186,32327,32468,32607,32746,32884,33021,
3574
33158,33294,33429,33564,33697,33831,33963,34095,
3575
34226,34357,34486,34616,34744,34873,35000,35127,
3576
35253,35379,35504,35629,35753,35876,35999,36122,
3577
36244,36365,36486,36606,36726,36845,36964,37083,
3578
37201,37318,37435,37551,37668,37783,37898,38013,
3579
38127,38241,38354,38467,38580,38692,38803,38915,
3580
39026,39136,39246,39356,39465,39574,39682,39790,
3581
39898,40005,40112,40219,40325,40431,40537,40642,
3582
40747,40851,40955,41059,41163,41266,41369,41471,
3583
41573,41675,41777,41878,41979,42079,42179,42279,
3584
42379,42478,42577,42676,42775,42873,42971,43068,
3585
43165,43262,43359,43456,43552,43648,43743,43839,
3586
43934,44028,44123,44217,44311,44405,44499,44592,
3587
44685,44778,44870,44962,45054,45146,45238,45329,
3588
45420,45511,45601,45692,45782,45872,45961,46051,
3589
46140,46229,46318,46406,46494,46583,46670,46758,
3590
46846,46933,47020,47107,47193,47280,47366,47452,
3591
47538,47623,47709,47794,47879,47964,48048,48133,
3592
48217,48301,48385,48468,48552,48635,48718,48801,
3593
48884,48966,49048,49131,49213,49294,49376,49458,
3594
49539,49620,49701,49782,49862,49943,50023,50103,
3595
50183,50263,50342,50422,50501,50580,50659,50738,
3596
50816,50895,50973,51051,51129,51207,51285,51362,
3597
51439,51517,51594,51671,51747,51824,51900,51977,
3598
52053,52129,52205,52280,52356,52432,52507,52582,
3599
52657,52732,52807,52881,52956,53030,53104,53178,
3600
53252,53326,53400,53473,53546,53620,53693,53766,
3601
53839,53911,53984,54056,54129,54201,54273,54345,
3602
54417,54489,54560,54632,54703,54774,54845,54916,
3603
54987,55058,55129,55199,55269,55340,55410,55480,
3604
55550,55620,55689,55759,55828,55898,55967,56036,
3605
56105,56174,56243,56311,56380,56448,56517,56585,
3606
56653,56721,56789,56857,56924,56992,57059,57127,
3607
57194,57261,57328,57395,57462,57529,57595,57662,
3608
57728,57795,57861,57927,57993,58059,58125,58191,
3609
58256,58322,58387,58453,58518,58583,58648,58713,
3610
58778,58843,58908,58972,59037,59101,59165,59230,
3611
59294,59358,59422,59486,59549,59613,59677,59740,
3612
59804,59867,59930,59993,60056,60119,60182,60245,
3613
60308,60370,60433,60495,60558,60620,60682,60744,
3614
60806,60868,60930,60992,61054,61115,61177,61238,
3615
61300,61361,61422,61483,61544,61605,61666,61727,
3616
61788,61848,61909,61969,62030,62090,62150,62211,
3617
62271,62331,62391,62450,62510,62570,62630,62689,
3618
62749,62808,62867,62927,62986,63045,63104,63163,
3619
63222,63281,63340,63398,63457,63515,63574,63632,
3620
63691,63749,63807,63865,63923,63981,64039,64097,
3621
64155,64212,64270,64328,64385,64443,64500,64557,
3622
64614,64672,64729,64786,64843,64900,64956,65013,
3623
65070,65126,65183,65239,65296,65352,65409,65465
3624
};
3625
3626
const png_byte png_sRGB_delta[512] =
3627
{
3628
207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
3629
52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
3630
35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
3631
28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
3632
23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
3633
21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
3634
19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
3635
17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
3636
16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
3637
15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
3638
14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
3639
13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
3640
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
3641
12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
3642
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3643
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
3644
11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3645
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3646
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
3647
10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3648
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3649
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3650
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
3651
9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3652
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3653
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3654
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3655
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
3656
8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
3657
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3658
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
3659
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
3660
};
3661
#endif /* SIMPLIFIED READ/WRITE sRGB support */
3662
3663
/* SIMPLIFIED READ/WRITE SUPPORT */
3664
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
3665
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
3666
static int
3667
png_image_free_function(png_voidp argument)
3668
{
3669
png_imagep image = png_voidcast(png_imagep, argument);
3670
png_controlp cp = image->opaque;
3671
png_control c;
3672
3673
/* Double check that we have a png_ptr - it should be impossible to get here
3674
* without one.
3675
*/
3676
if (cp->png_ptr == NULL)
3677
return 0;
3678
3679
/* First free any data held in the control structure. */
3680
# ifdef PNG_STDIO_SUPPORTED
3681
if (cp->owned_file != 0)
3682
{
3683
FILE *fp = png_voidcast(FILE*, png_get_io_ptr(cp->png_ptr));
3684
cp->owned_file = 0;
3685
3686
/* Ignore errors here. */
3687
if (fp != NULL)
3688
{
3689
png_init_io(cp->png_ptr, NULL);
3690
(void)fclose(fp);
3691
}
3692
}
3693
# endif
3694
3695
/* Copy the control structure so that the original, allocated, version can be
3696
* safely freed. Notice that a png_error here stops the remainder of the
3697
* cleanup, but this is probably fine because that would indicate bad memory
3698
* problems anyway.
3699
*/
3700
c = *cp;
3701
image->opaque = &c;
3702
png_free(c.png_ptr, cp);
3703
3704
/* Then the structures, calling the correct API. */
3705
if (c.for_write != 0)
3706
{
3707
# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
3708
png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
3709
# else
3710
png_error(c.png_ptr, "simplified write not supported");
3711
# endif
3712
}
3713
else
3714
{
3715
# ifdef PNG_SIMPLIFIED_READ_SUPPORTED
3716
png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
3717
# else
3718
png_error(c.png_ptr, "simplified read not supported");
3719
# endif
3720
}
3721
3722
/* Success. */
3723
return 1;
3724
}
3725
3726
void PNGAPI
3727
png_image_free(png_imagep image)
3728
{
3729
/* Safely call the real function, but only if doing so is safe at this point
3730
* (if not inside an error handling context). Otherwise assume
3731
* png_safe_execute will call this API after the return.
3732
*/
3733
if (image != NULL && image->opaque != NULL &&
3734
image->opaque->error_buf == NULL)
3735
{
3736
/* Ignore errors here: */
3737
(void)png_safe_execute(image, png_image_free_function, image);
3738
image->opaque = NULL;
3739
}
3740
}
3741
3742
int /* PRIVATE */
3743
png_image_error(png_imagep image, png_const_charp error_message)
3744
{
3745
/* Utility to log an error. */
3746
png_safecat(image->message, (sizeof image->message), 0, error_message);
3747
image->warning_or_error |= PNG_IMAGE_ERROR;
3748
png_image_free(image);
3749
return 0;
3750
}
3751
3752
#ifdef PNG_STDIO_SUPPORTED
3753
typedef struct
3754
{
3755
png_structrp png_ptr;
3756
png_FILE_p fp;
3757
}
3758
png_image_init_io_struct;
3759
3760
static int
3761
image_init_io(png_voidp display)
3762
{
3763
png_image_init_io_struct *p =
3764
png_voidcast(png_image_init_io_struct*, display);
3765
3766
png_init_io(p->png_ptr, p->fp);
3767
return 1;
3768
}
3769
3770
int /* PRIVATE */
3771
png_image_init_io(png_imagep image, png_FILE_p fp)
3772
{
3773
png_image_init_io_struct s;
3774
3775
s.png_ptr = image->opaque->png_ptr;
3776
s.fp = fp;
3777
3778
return png_safe_execute(image, image_init_io, &s);
3779
}
3780
#endif /* STDIO */
3781
#endif /* SIMPLIFIED READ/WRITE */
3782
#endif /* READ || WRITE */
3783
3784