2
/* pngrutil.c - utilities to read a PNG file
4
* libpng 1.2.5 - October 3, 2002
5
* For conditions of distribution and use, see copyright notice in png.h
6
* Copyright (c) 1998-2002 Glenn Randers-Pehrson
7
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
8
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
10
* This file contains routines that are only called from within
11
* libpng itself during the course of reading an image.
17
#if defined(_WIN32_WCE)
18
/* strtod() function is not supported on WindowsCE */
19
# ifdef PNG_FLOATING_POINT_SUPPORTED
20
__inline double strtod(const char *nptr, char **endptr)
26
len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
27
str = (wchar_t *)malloc(len * sizeof(wchar_t));
30
MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
31
result = wcstod(str, &end);
32
len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
33
*endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
41
#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
42
/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
43
png_uint_32 /* PRIVATE */
44
png_get_uint_32(png_bytep buf)
46
png_uint_32 i = ((png_uint_32)(*buf) << 24) +
47
((png_uint_32)(*(buf + 1)) << 16) +
48
((png_uint_32)(*(buf + 2)) << 8) +
49
(png_uint_32)(*(buf + 3));
54
#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
55
/* Grab a signed 32-bit integer from a buffer in big-endian format. The
56
* data is stored in the PNG file in two's complement format, and it is
57
* assumed that the machine format for signed integers is the same. */
58
png_int_32 /* PRIVATE */
59
png_get_int_32(png_bytep buf)
61
png_int_32 i = ((png_int_32)(*buf) << 24) +
62
((png_int_32)(*(buf + 1)) << 16) +
63
((png_int_32)(*(buf + 2)) << 8) +
64
(png_int_32)(*(buf + 3));
68
#endif /* PNG_READ_pCAL_SUPPORTED */
70
/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
71
png_uint_16 /* PRIVATE */
72
png_get_uint_16(png_bytep buf)
74
png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
75
(png_uint_16)(*(buf + 1)));
79
#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
81
/* Read data, and (optionally) run it through the CRC. */
83
png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
85
png_read_data(png_ptr, buf, length);
86
png_calculate_crc(png_ptr, buf, length);
89
/* Optionally skip data and then check the CRC. Depending on whether we
90
are reading a ancillary or critical chunk, and how the program has set
91
things up, we may calculate the CRC on the data and print a message.
92
Returns '1' if there was a CRC error, '0' otherwise. */
94
png_crc_finish(png_structp png_ptr, png_uint_32 skip)
97
png_size_t istop = png_ptr->zbuf_size;
99
for (i = (png_size_t)skip; i > istop; i -= istop)
101
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
105
png_crc_read(png_ptr, png_ptr->zbuf, i);
108
if (png_crc_error(png_ptr))
110
if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
111
!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
112
(!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
113
(png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
115
png_chunk_warning(png_ptr, "CRC error");
119
png_chunk_error(png_ptr, "CRC error");
127
/* Compare the CRC stored in the PNG file with that calculated by libpng from
128
the data it has read thus far. */
130
png_crc_error(png_structp png_ptr)
132
png_byte crc_bytes[4];
136
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
138
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
139
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
144
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
148
png_read_data(png_ptr, crc_bytes, 4);
152
crc = png_get_uint_32(crc_bytes);
153
return ((int)(crc != png_ptr->crc));
159
#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
160
defined(PNG_READ_iCCP_SUPPORTED)
162
* Decompress trailing data in a chunk. The assumption is that chunkdata
163
* points at an allocated area holding the contents of a chunk with a
164
* trailing compressed part. What we get back is an allocated area
165
* holding the original prefix part and an uncompressed version of the
166
* trailing part (the malloc area passed in is freed).
168
png_charp /* PRIVATE */
169
png_decompress_chunk(png_structp png_ptr, int comp_type,
170
png_charp chunkdata, png_size_t chunklength,
171
png_size_t prefix_size, png_size_t *newlength)
173
static char msg[] = "Error decoding compressed text";
174
png_charp text = NULL;
175
png_size_t text_size;
177
if (comp_type == PNG_COMPRESSION_TYPE_BASE)
180
png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
181
png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
182
png_ptr->zstream.next_out = png_ptr->zbuf;
183
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
188
while (png_ptr->zstream.avail_in)
190
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
191
if (ret != Z_OK && ret != Z_STREAM_END)
193
if (png_ptr->zstream.msg != NULL)
194
png_warning(png_ptr, png_ptr->zstream.msg);
196
png_warning(png_ptr, msg);
197
inflateReset(&png_ptr->zstream);
198
png_ptr->zstream.avail_in = 0;
202
text_size = prefix_size + sizeof(msg) + 1;
203
text = (png_charp)png_malloc_warn(png_ptr, text_size);
206
png_free(png_ptr,chunkdata);
207
png_error(png_ptr,"Not enough memory to decompress chunk");
209
png_memcpy(text, chunkdata, prefix_size);
212
text[text_size - 1] = 0x00;
214
/* Copy what we can of the error message into the text chunk */
215
text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
216
text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
217
png_memcpy(text + prefix_size, msg, text_size + 1);
220
if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
224
text_size = prefix_size +
225
png_ptr->zbuf_size - png_ptr->zstream.avail_out;
226
text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
229
png_free(png_ptr,chunkdata);
230
png_error(png_ptr,"Not enough memory to decompress chunk.");
232
png_memcpy(text + prefix_size, png_ptr->zbuf,
233
text_size - prefix_size);
234
png_memcpy(text, chunkdata, prefix_size);
235
*(text + text_size) = 0x00;
242
text = (png_charp)png_malloc_warn(png_ptr,
243
(png_uint_32)(text_size +
244
png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
247
png_free(png_ptr, tmp);
248
png_free(png_ptr, chunkdata);
249
png_error(png_ptr,"Not enough memory to decompress chunk..");
251
png_memcpy(text, tmp, text_size);
252
png_free(png_ptr, tmp);
253
png_memcpy(text + text_size, png_ptr->zbuf,
254
(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
255
text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
256
*(text + text_size) = 0x00;
258
if (ret == Z_STREAM_END)
262
png_ptr->zstream.next_out = png_ptr->zbuf;
263
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
267
if (ret != Z_STREAM_END)
269
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
272
if (ret == Z_BUF_ERROR)
273
sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
274
png_ptr->chunk_name);
275
else if (ret == Z_DATA_ERROR)
276
sprintf(umsg,"Data error in compressed datastream in %s chunk",
277
png_ptr->chunk_name);
279
sprintf(umsg,"Incomplete compressed datastream in %s chunk",
280
png_ptr->chunk_name);
281
png_warning(png_ptr, umsg);
284
"Incomplete compressed datastream in chunk other than IDAT");
286
text_size=prefix_size;
289
text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
292
png_free(png_ptr, chunkdata);
293
png_error(png_ptr,"Not enough memory for text.");
295
png_memcpy(text, chunkdata, prefix_size);
297
*(text + text_size) = 0x00;
300
inflateReset(&png_ptr->zstream);
301
png_ptr->zstream.avail_in = 0;
303
png_free(png_ptr, chunkdata);
305
*newlength=text_size;
307
else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
309
#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
312
sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
313
png_warning(png_ptr, umsg);
315
png_warning(png_ptr, "Unknown zTXt compression type");
318
*(chunkdata + prefix_size) = 0x00;
319
*newlength=prefix_size;
326
/* read and check the IDHR chunk */
328
png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
331
png_uint_32 width, height;
332
int bit_depth, color_type, compression_type, filter_type;
335
png_debug(1, "in png_handle_IHDR\n");
337
if (png_ptr->mode & PNG_HAVE_IHDR)
338
png_error(png_ptr, "Out of place IHDR");
340
/* check the length */
342
png_error(png_ptr, "Invalid IHDR chunk");
344
png_ptr->mode |= PNG_HAVE_IHDR;
346
png_crc_read(png_ptr, buf, 13);
347
png_crc_finish(png_ptr, 0);
349
width = png_get_uint_32(buf);
350
height = png_get_uint_32(buf + 4);
353
compression_type = buf[10];
354
filter_type = buf[11];
355
interlace_type = buf[12];
358
/* set internal variables */
359
png_ptr->width = width;
360
png_ptr->height = height;
361
png_ptr->bit_depth = (png_byte)bit_depth;
362
png_ptr->interlaced = (png_byte)interlace_type;
363
png_ptr->color_type = (png_byte)color_type;
364
#if defined(PNG_MNG_FEATURES_SUPPORTED)
365
png_ptr->filter_type = (png_byte)filter_type;
368
/* find number of channels */
369
switch (png_ptr->color_type)
371
case PNG_COLOR_TYPE_GRAY:
372
case PNG_COLOR_TYPE_PALETTE:
373
png_ptr->channels = 1;
375
case PNG_COLOR_TYPE_RGB:
376
png_ptr->channels = 3;
378
case PNG_COLOR_TYPE_GRAY_ALPHA:
379
png_ptr->channels = 2;
381
case PNG_COLOR_TYPE_RGB_ALPHA:
382
png_ptr->channels = 4;
386
/* set up other useful info */
387
png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
389
png_ptr->rowbytes = ((png_ptr->width *
390
(png_uint_32)png_ptr->pixel_depth + 7) >> 3);
391
png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
392
png_debug1(3,"channels = %d\n", png_ptr->channels);
393
png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
394
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
395
color_type, interlace_type, compression_type, filter_type);
398
/* read and check the palette */
400
png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
402
png_color palette[PNG_MAX_PALETTE_LENGTH];
404
#ifndef PNG_NO_POINTER_INDEXING
408
png_debug(1, "in png_handle_PLTE\n");
410
if (!(png_ptr->mode & PNG_HAVE_IHDR))
411
png_error(png_ptr, "Missing IHDR before PLTE");
412
else if (png_ptr->mode & PNG_HAVE_IDAT)
414
png_warning(png_ptr, "Invalid PLTE after IDAT");
415
png_crc_finish(png_ptr, length);
418
else if (png_ptr->mode & PNG_HAVE_PLTE)
419
png_error(png_ptr, "Duplicate PLTE chunk");
421
png_ptr->mode |= PNG_HAVE_PLTE;
423
if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
426
"Ignoring PLTE chunk in grayscale PNG");
427
png_crc_finish(png_ptr, length);
430
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
431
if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
433
png_crc_finish(png_ptr, length);
438
if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
440
if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
442
png_warning(png_ptr, "Invalid palette chunk");
443
png_crc_finish(png_ptr, length);
448
png_error(png_ptr, "Invalid palette chunk");
452
num = (int)length / 3;
454
#ifndef PNG_NO_POINTER_INDEXING
455
for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
459
png_crc_read(png_ptr, buf, 3);
460
pal_ptr->red = buf[0];
461
pal_ptr->green = buf[1];
462
pal_ptr->blue = buf[2];
465
for (i = 0; i < num; i++)
469
png_crc_read(png_ptr, buf, 3);
470
/* don't depend upon png_color being any order */
471
palette[i].red = buf[0];
472
palette[i].green = buf[1];
473
palette[i].blue = buf[2];
477
/* If we actually NEED the PLTE chunk (ie for a paletted image), we do
478
whatever the normal CRC configuration tells us. However, if we
479
have an RGB image, the PLTE can be considered ancillary, so
480
we will act as though it is. */
481
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
482
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
485
png_crc_finish(png_ptr, 0);
487
#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
488
else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
490
/* If we don't want to use the data from an ancillary chunk,
491
we have two options: an error abort, or a warning and we
492
ignore the data in this chunk (which should be OK, since
493
it's considered ancillary for a RGB or RGBA image). */
494
if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
496
if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
498
png_chunk_error(png_ptr, "CRC error");
502
png_chunk_warning(png_ptr, "CRC error");
506
/* Otherwise, we (optionally) emit a warning and use the chunk. */
507
else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
509
png_chunk_warning(png_ptr, "CRC error");
514
png_set_PLTE(png_ptr, info_ptr, palette, num);
516
#if defined(PNG_READ_tRNS_SUPPORTED)
517
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
519
if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
521
if (png_ptr->num_trans > (png_uint_16)num)
523
png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
524
png_ptr->num_trans = (png_uint_16)num;
526
if (info_ptr->num_trans > (png_uint_16)num)
528
png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
529
info_ptr->num_trans = (png_uint_16)num;
538
png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
540
png_debug(1, "in png_handle_IEND\n");
542
if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
544
png_error(png_ptr, "No image in file");
546
info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
549
png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
553
png_warning(png_ptr, "Incorrect IEND chunk length");
555
png_crc_finish(png_ptr, length);
558
#if defined(PNG_READ_gAMA_SUPPORTED)
560
png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
562
png_fixed_point igamma;
563
#ifdef PNG_FLOATING_POINT_SUPPORTED
568
png_debug(1, "in png_handle_gAMA\n");
570
if (!(png_ptr->mode & PNG_HAVE_IHDR))
571
png_error(png_ptr, "Missing IHDR before gAMA");
572
else if (png_ptr->mode & PNG_HAVE_IDAT)
574
png_warning(png_ptr, "Invalid gAMA after IDAT");
575
png_crc_finish(png_ptr, length);
578
else if (png_ptr->mode & PNG_HAVE_PLTE)
579
/* Should be an error, but we can cope with it */
580
png_warning(png_ptr, "Out of place gAMA chunk");
582
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
583
#if defined(PNG_READ_sRGB_SUPPORTED)
584
&& !(info_ptr->valid & PNG_INFO_sRGB)
588
png_warning(png_ptr, "Duplicate gAMA chunk");
589
png_crc_finish(png_ptr, length);
595
png_warning(png_ptr, "Incorrect gAMA chunk length");
596
png_crc_finish(png_ptr, length);
600
png_crc_read(png_ptr, buf, 4);
601
if (png_crc_finish(png_ptr, 0))
604
igamma = (png_fixed_point)png_get_uint_32(buf);
605
/* check for zero gamma */
609
"Ignoring gAMA chunk with gamma=0");
613
#if defined(PNG_READ_sRGB_SUPPORTED)
614
if (info_ptr->valid & PNG_INFO_sRGB)
615
if(igamma < 45000L || igamma > 46000L)
618
"Ignoring incorrect gAMA value when sRGB is also present");
619
#ifndef PNG_NO_CONSOLE_IO
620
fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
624
#endif /* PNG_READ_sRGB_SUPPORTED */
626
#ifdef PNG_FLOATING_POINT_SUPPORTED
627
file_gamma = (float)igamma / (float)100000.0;
628
# ifdef PNG_READ_GAMMA_SUPPORTED
629
png_ptr->gamma = file_gamma;
631
png_set_gAMA(png_ptr, info_ptr, file_gamma);
633
#ifdef PNG_FIXED_POINT_SUPPORTED
634
png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
639
#if defined(PNG_READ_sBIT_SUPPORTED)
641
png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
646
png_debug(1, "in png_handle_sBIT\n");
648
buf[0] = buf[1] = buf[2] = buf[3] = 0;
650
if (!(png_ptr->mode & PNG_HAVE_IHDR))
651
png_error(png_ptr, "Missing IHDR before sBIT");
652
else if (png_ptr->mode & PNG_HAVE_IDAT)
654
png_warning(png_ptr, "Invalid sBIT after IDAT");
655
png_crc_finish(png_ptr, length);
658
else if (png_ptr->mode & PNG_HAVE_PLTE)
660
/* Should be an error, but we can cope with it */
661
png_warning(png_ptr, "Out of place sBIT chunk");
663
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
665
png_warning(png_ptr, "Duplicate sBIT chunk");
666
png_crc_finish(png_ptr, length);
670
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
673
truelen = (png_size_t)png_ptr->channels;
675
if (length != truelen)
677
png_warning(png_ptr, "Incorrect sBIT chunk length");
678
png_crc_finish(png_ptr, length);
682
png_crc_read(png_ptr, buf, truelen);
683
if (png_crc_finish(png_ptr, 0))
686
if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
688
png_ptr->sig_bit.red = buf[0];
689
png_ptr->sig_bit.green = buf[1];
690
png_ptr->sig_bit.blue = buf[2];
691
png_ptr->sig_bit.alpha = buf[3];
695
png_ptr->sig_bit.gray = buf[0];
696
png_ptr->sig_bit.red = buf[0];
697
png_ptr->sig_bit.green = buf[0];
698
png_ptr->sig_bit.blue = buf[0];
699
png_ptr->sig_bit.alpha = buf[1];
701
png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
705
#if defined(PNG_READ_cHRM_SUPPORTED)
707
png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
710
#ifdef PNG_FLOATING_POINT_SUPPORTED
711
float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
713
png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
714
int_y_green, int_x_blue, int_y_blue;
716
png_uint_32 uint_x, uint_y;
718
png_debug(1, "in png_handle_cHRM\n");
720
if (!(png_ptr->mode & PNG_HAVE_IHDR))
721
png_error(png_ptr, "Missing IHDR before cHRM");
722
else if (png_ptr->mode & PNG_HAVE_IDAT)
724
png_warning(png_ptr, "Invalid cHRM after IDAT");
725
png_crc_finish(png_ptr, length);
728
else if (png_ptr->mode & PNG_HAVE_PLTE)
729
/* Should be an error, but we can cope with it */
730
png_warning(png_ptr, "Missing PLTE before cHRM");
732
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
733
#if defined(PNG_READ_sRGB_SUPPORTED)
734
&& !(info_ptr->valid & PNG_INFO_sRGB)
738
png_warning(png_ptr, "Duplicate cHRM chunk");
739
png_crc_finish(png_ptr, length);
745
png_warning(png_ptr, "Incorrect cHRM chunk length");
746
png_crc_finish(png_ptr, length);
750
png_crc_read(png_ptr, buf, 4);
751
uint_x = png_get_uint_32(buf);
753
png_crc_read(png_ptr, buf, 4);
754
uint_y = png_get_uint_32(buf);
756
if (uint_x > 80000L || uint_y > 80000L ||
757
uint_x + uint_y > 100000L)
759
png_warning(png_ptr, "Invalid cHRM white point");
760
png_crc_finish(png_ptr, 24);
763
int_x_white = (png_fixed_point)uint_x;
764
int_y_white = (png_fixed_point)uint_y;
766
png_crc_read(png_ptr, buf, 4);
767
uint_x = png_get_uint_32(buf);
769
png_crc_read(png_ptr, buf, 4);
770
uint_y = png_get_uint_32(buf);
772
if (uint_x > 80000L || uint_y > 80000L ||
773
uint_x + uint_y > 100000L)
775
png_warning(png_ptr, "Invalid cHRM red point");
776
png_crc_finish(png_ptr, 16);
779
int_x_red = (png_fixed_point)uint_x;
780
int_y_red = (png_fixed_point)uint_y;
782
png_crc_read(png_ptr, buf, 4);
783
uint_x = png_get_uint_32(buf);
785
png_crc_read(png_ptr, buf, 4);
786
uint_y = png_get_uint_32(buf);
788
if (uint_x > 80000L || uint_y > 80000L ||
789
uint_x + uint_y > 100000L)
791
png_warning(png_ptr, "Invalid cHRM green point");
792
png_crc_finish(png_ptr, 8);
795
int_x_green = (png_fixed_point)uint_x;
796
int_y_green = (png_fixed_point)uint_y;
798
png_crc_read(png_ptr, buf, 4);
799
uint_x = png_get_uint_32(buf);
801
png_crc_read(png_ptr, buf, 4);
802
uint_y = png_get_uint_32(buf);
804
if (uint_x > 80000L || uint_y > 80000L ||
805
uint_x + uint_y > 100000L)
807
png_warning(png_ptr, "Invalid cHRM blue point");
808
png_crc_finish(png_ptr, 0);
811
int_x_blue = (png_fixed_point)uint_x;
812
int_y_blue = (png_fixed_point)uint_y;
814
#ifdef PNG_FLOATING_POINT_SUPPORTED
815
white_x = (float)int_x_white / (float)100000.0;
816
white_y = (float)int_y_white / (float)100000.0;
817
red_x = (float)int_x_red / (float)100000.0;
818
red_y = (float)int_y_red / (float)100000.0;
819
green_x = (float)int_x_green / (float)100000.0;
820
green_y = (float)int_y_green / (float)100000.0;
821
blue_x = (float)int_x_blue / (float)100000.0;
822
blue_y = (float)int_y_blue / (float)100000.0;
825
#if defined(PNG_READ_sRGB_SUPPORTED)
826
if (info_ptr->valid & PNG_INFO_sRGB)
828
if (abs(int_x_white - 31270L) > 1000 ||
829
abs(int_y_white - 32900L) > 1000 ||
830
abs(int_x_red - 64000L) > 1000 ||
831
abs(int_y_red - 33000L) > 1000 ||
832
abs(int_x_green - 30000L) > 1000 ||
833
abs(int_y_green - 60000L) > 1000 ||
834
abs(int_x_blue - 15000L) > 1000 ||
835
abs(int_y_blue - 6000L) > 1000)
839
"Ignoring incorrect cHRM value when sRGB is also present");
840
#ifndef PNG_NO_CONSOLE_IO
841
#ifdef PNG_FLOATING_POINT_SUPPORTED
842
fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
843
white_x, white_y, red_x, red_y);
844
fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
845
green_x, green_y, blue_x, blue_y);
847
fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
848
int_x_white, int_y_white, int_x_red, int_y_red);
849
fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
850
int_x_green, int_y_green, int_x_blue, int_y_blue);
852
#endif /* PNG_NO_CONSOLE_IO */
854
png_crc_finish(png_ptr, 0);
857
#endif /* PNG_READ_sRGB_SUPPORTED */
859
#ifdef PNG_FLOATING_POINT_SUPPORTED
860
png_set_cHRM(png_ptr, info_ptr,
861
white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
863
#ifdef PNG_FIXED_POINT_SUPPORTED
864
png_set_cHRM_fixed(png_ptr, info_ptr,
865
int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
866
int_y_green, int_x_blue, int_y_blue);
868
if (png_crc_finish(png_ptr, 0))
873
#if defined(PNG_READ_sRGB_SUPPORTED)
875
png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
880
png_debug(1, "in png_handle_sRGB\n");
882
if (!(png_ptr->mode & PNG_HAVE_IHDR))
883
png_error(png_ptr, "Missing IHDR before sRGB");
884
else if (png_ptr->mode & PNG_HAVE_IDAT)
886
png_warning(png_ptr, "Invalid sRGB after IDAT");
887
png_crc_finish(png_ptr, length);
890
else if (png_ptr->mode & PNG_HAVE_PLTE)
891
/* Should be an error, but we can cope with it */
892
png_warning(png_ptr, "Out of place sRGB chunk");
894
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
896
png_warning(png_ptr, "Duplicate sRGB chunk");
897
png_crc_finish(png_ptr, length);
903
png_warning(png_ptr, "Incorrect sRGB chunk length");
904
png_crc_finish(png_ptr, length);
908
png_crc_read(png_ptr, buf, 1);
909
if (png_crc_finish(png_ptr, 0))
913
/* check for bad intent */
914
if (intent >= PNG_sRGB_INTENT_LAST)
916
png_warning(png_ptr, "Unknown sRGB intent");
920
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
921
if ((info_ptr->valid & PNG_INFO_gAMA))
924
#ifdef PNG_FIXED_POINT_SUPPORTED
925
igamma=(int)info_ptr->int_gamma;
927
# ifdef PNG_FLOATING_POINT_SUPPORTED
928
igamma=(int)(info_ptr->gamma * 100000.);
931
if(igamma < 45000L || igamma > 46000L)
934
"Ignoring incorrect gAMA value when sRGB is also present");
935
#ifndef PNG_NO_CONSOLE_IO
936
# ifdef PNG_FIXED_POINT_SUPPORTED
937
fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
939
# ifdef PNG_FLOATING_POINT_SUPPORTED
940
fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
946
#endif /* PNG_READ_gAMA_SUPPORTED */
948
#ifdef PNG_READ_cHRM_SUPPORTED
949
#ifdef PNG_FIXED_POINT_SUPPORTED
950
if (info_ptr->valid & PNG_INFO_cHRM)
951
if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
952
abs(info_ptr->int_y_white - 32900L) > 1000 ||
953
abs(info_ptr->int_x_red - 64000L) > 1000 ||
954
abs(info_ptr->int_y_red - 33000L) > 1000 ||
955
abs(info_ptr->int_x_green - 30000L) > 1000 ||
956
abs(info_ptr->int_y_green - 60000L) > 1000 ||
957
abs(info_ptr->int_x_blue - 15000L) > 1000 ||
958
abs(info_ptr->int_y_blue - 6000L) > 1000)
961
"Ignoring incorrect cHRM value when sRGB is also present");
963
#endif /* PNG_FIXED_POINT_SUPPORTED */
964
#endif /* PNG_READ_cHRM_SUPPORTED */
966
png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
968
#endif /* PNG_READ_sRGB_SUPPORTED */
970
#if defined(PNG_READ_iCCP_SUPPORTED)
972
png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
973
/* Note: this does not properly handle chunks that are > 64K under DOS */
976
png_byte compression_type;
979
png_uint_32 skip = 0;
980
png_uint_32 profile_size = 0;
981
png_uint_32 profile_length = 0;
982
png_size_t slength, prefix_length, data_length;
984
png_debug(1, "in png_handle_iCCP\n");
986
if (!(png_ptr->mode & PNG_HAVE_IHDR))
987
png_error(png_ptr, "Missing IHDR before iCCP");
988
else if (png_ptr->mode & PNG_HAVE_IDAT)
990
png_warning(png_ptr, "Invalid iCCP after IDAT");
991
png_crc_finish(png_ptr, length);
994
else if (png_ptr->mode & PNG_HAVE_PLTE)
995
/* Should be an error, but we can cope with it */
996
png_warning(png_ptr, "Out of place iCCP chunk");
998
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1000
png_warning(png_ptr, "Duplicate iCCP chunk");
1001
png_crc_finish(png_ptr, length);
1005
#ifdef PNG_MAX_MALLOC_64K
1006
if (length > (png_uint_32)65535L)
1008
png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1009
skip = length - (png_uint_32)65535L;
1010
length = (png_uint_32)65535L;
1014
chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1015
slength = (png_size_t)length;
1016
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1018
if (png_crc_finish(png_ptr, skip))
1020
png_free(png_ptr, chunkdata);
1024
chunkdata[slength] = 0x00;
1026
for (profile = chunkdata; *profile; profile++)
1027
/* empty loop to find end of name */ ;
1031
/* there should be at least one zero (the compression type byte)
1032
following the separator, and we should be on it */
1033
if ( profile >= chunkdata + slength)
1035
png_free(png_ptr, chunkdata);
1036
png_warning(png_ptr, "Malformed iCCP chunk");
1040
/* compression_type should always be zero */
1041
compression_type = *profile++;
1042
if (compression_type)
1044
png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1045
compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1049
prefix_length = profile - chunkdata;
1050
chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
1051
slength, prefix_length, &data_length);
1053
profile_length = data_length - prefix_length;
1055
if ( prefix_length > data_length || profile_length < 4)
1057
png_free(png_ptr, chunkdata);
1058
png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1062
/* Check the profile_size recorded in the first 32 bits of the ICC profile */
1063
pC = (png_bytep)(chunkdata+prefix_length);
1064
profile_size = ((*(pC ))<<24) |
1069
if(profile_size < profile_length)
1070
profile_length = profile_size;
1072
if(profile_size > profile_length)
1074
png_free(png_ptr, chunkdata);
1075
png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
1079
png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
1080
chunkdata + prefix_length, profile_length);
1081
png_free(png_ptr, chunkdata);
1083
#endif /* PNG_READ_iCCP_SUPPORTED */
1085
#if defined(PNG_READ_sPLT_SUPPORTED)
1087
png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1088
/* Note: this does not properly handle chunks that are > 64K under DOS */
1090
png_bytep chunkdata;
1091
png_bytep entry_start;
1092
png_sPLT_t new_palette;
1093
#ifdef PNG_NO_POINTER_INDEXING
1096
int data_length, entry_size, i;
1097
png_uint_32 skip = 0;
1100
png_debug(1, "in png_handle_sPLT\n");
1102
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1103
png_error(png_ptr, "Missing IHDR before sPLT");
1104
else if (png_ptr->mode & PNG_HAVE_IDAT)
1106
png_warning(png_ptr, "Invalid sPLT after IDAT");
1107
png_crc_finish(png_ptr, length);
1111
#ifdef PNG_MAX_MALLOC_64K
1112
if (length > (png_uint_32)65535L)
1114
png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1115
skip = length - (png_uint_32)65535L;
1116
length = (png_uint_32)65535L;
1120
chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
1121
slength = (png_size_t)length;
1122
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1124
if (png_crc_finish(png_ptr, skip))
1126
png_free(png_ptr, chunkdata);
1130
chunkdata[slength] = 0x00;
1132
for (entry_start = chunkdata; *entry_start; entry_start++)
1133
/* empty loop to find end of name */ ;
1136
/* a sample depth should follow the separator, and we should be on it */
1137
if (entry_start > chunkdata + slength)
1139
png_free(png_ptr, chunkdata);
1140
png_warning(png_ptr, "malformed sPLT chunk");
1144
new_palette.depth = *entry_start++;
1145
entry_size = (new_palette.depth == 8 ? 6 : 10);
1146
data_length = (slength - (entry_start - chunkdata));
1148
/* integrity-check the data length */
1149
if (data_length % entry_size)
1151
png_free(png_ptr, chunkdata);
1152
png_warning(png_ptr, "sPLT chunk has bad length");
1156
new_palette.nentries = data_length / entry_size;
1157
new_palette.entries = (png_sPLT_entryp)png_malloc(
1158
png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
1160
#ifndef PNG_NO_POINTER_INDEXING
1161
for (i = 0; i < new_palette.nentries; i++)
1163
png_sPLT_entryp pp = new_palette.entries + i;
1165
if (new_palette.depth == 8)
1167
pp->red = *entry_start++;
1168
pp->green = *entry_start++;
1169
pp->blue = *entry_start++;
1170
pp->alpha = *entry_start++;
1174
pp->red = png_get_uint_16(entry_start); entry_start += 2;
1175
pp->green = png_get_uint_16(entry_start); entry_start += 2;
1176
pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1177
pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1179
pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1182
pp = new_palette.entries;
1183
for (i = 0; i < new_palette.nentries; i++)
1186
if (new_palette.depth == 8)
1188
pp[i].red = *entry_start++;
1189
pp[i].green = *entry_start++;
1190
pp[i].blue = *entry_start++;
1191
pp[i].alpha = *entry_start++;
1195
pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1196
pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1197
pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1198
pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1200
pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1204
/* discard all chunk data except the name and stash that */
1205
new_palette.name = (png_charp)chunkdata;
1207
png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1209
png_free(png_ptr, chunkdata);
1210
png_free(png_ptr, new_palette.entries);
1212
#endif /* PNG_READ_sPLT_SUPPORTED */
1214
#if defined(PNG_READ_tRNS_SUPPORTED)
1216
png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1218
png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1220
png_debug(1, "in png_handle_tRNS\n");
1222
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1223
png_error(png_ptr, "Missing IHDR before tRNS");
1224
else if (png_ptr->mode & PNG_HAVE_IDAT)
1226
png_warning(png_ptr, "Invalid tRNS after IDAT");
1227
png_crc_finish(png_ptr, length);
1230
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1232
png_warning(png_ptr, "Duplicate tRNS chunk");
1233
png_crc_finish(png_ptr, length);
1237
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1239
if (!(png_ptr->mode & PNG_HAVE_PLTE))
1241
/* Should be an error, but we can cope with it */
1242
png_warning(png_ptr, "Missing PLTE before tRNS");
1244
else if (length > (png_uint_32)png_ptr->num_palette)
1246
png_warning(png_ptr, "Incorrect tRNS chunk length");
1247
png_crc_finish(png_ptr, length);
1252
png_warning(png_ptr, "Zero length tRNS chunk");
1253
png_crc_finish(png_ptr, length);
1257
png_crc_read(png_ptr, readbuf, (png_size_t)length);
1258
png_ptr->num_trans = (png_uint_16)length;
1260
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1266
png_warning(png_ptr, "Incorrect tRNS chunk length");
1267
png_crc_finish(png_ptr, length);
1271
png_crc_read(png_ptr, buf, (png_size_t)length);
1272
png_ptr->num_trans = 1;
1273
png_ptr->trans_values.red = png_get_uint_16(buf);
1274
png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1275
png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1277
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1283
png_warning(png_ptr, "Incorrect tRNS chunk length");
1284
png_crc_finish(png_ptr, length);
1288
png_crc_read(png_ptr, buf, 2);
1289
png_ptr->num_trans = 1;
1290
png_ptr->trans_values.gray = png_get_uint_16(buf);
1294
png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1295
png_crc_finish(png_ptr, length);
1299
if (png_crc_finish(png_ptr, 0))
1302
png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1303
&(png_ptr->trans_values));
1307
#if defined(PNG_READ_bKGD_SUPPORTED)
1309
png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1314
png_debug(1, "in png_handle_bKGD\n");
1316
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1317
png_error(png_ptr, "Missing IHDR before bKGD");
1318
else if (png_ptr->mode & PNG_HAVE_IDAT)
1320
png_warning(png_ptr, "Invalid bKGD after IDAT");
1321
png_crc_finish(png_ptr, length);
1324
else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1325
!(png_ptr->mode & PNG_HAVE_PLTE))
1327
png_warning(png_ptr, "Missing PLTE before bKGD");
1328
png_crc_finish(png_ptr, length);
1331
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1333
png_warning(png_ptr, "Duplicate bKGD chunk");
1334
png_crc_finish(png_ptr, length);
1338
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1340
else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1345
if (length != truelen)
1347
png_warning(png_ptr, "Incorrect bKGD chunk length");
1348
png_crc_finish(png_ptr, length);
1352
png_crc_read(png_ptr, buf, truelen);
1353
if (png_crc_finish(png_ptr, 0))
1356
/* We convert the index value into RGB components so that we can allow
1357
* arbitrary RGB values for background when we have transparency, and
1358
* so it is easy to determine the RGB values of the background color
1359
* from the info_ptr struct. */
1360
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1362
png_ptr->background.index = buf[0];
1363
if(info_ptr->num_palette)
1365
if(buf[0] > info_ptr->num_palette)
1367
png_warning(png_ptr, "Incorrect bKGD chunk index value");
1370
png_ptr->background.red =
1371
(png_uint_16)png_ptr->palette[buf[0]].red;
1372
png_ptr->background.green =
1373
(png_uint_16)png_ptr->palette[buf[0]].green;
1374
png_ptr->background.blue =
1375
(png_uint_16)png_ptr->palette[buf[0]].blue;
1378
else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1380
png_ptr->background.red =
1381
png_ptr->background.green =
1382
png_ptr->background.blue =
1383
png_ptr->background.gray = png_get_uint_16(buf);
1387
png_ptr->background.red = png_get_uint_16(buf);
1388
png_ptr->background.green = png_get_uint_16(buf + 2);
1389
png_ptr->background.blue = png_get_uint_16(buf + 4);
1392
png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1396
#if defined(PNG_READ_hIST_SUPPORTED)
1398
png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1401
png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1403
png_debug(1, "in png_handle_hIST\n");
1405
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1406
png_error(png_ptr, "Missing IHDR before hIST");
1407
else if (png_ptr->mode & PNG_HAVE_IDAT)
1409
png_warning(png_ptr, "Invalid hIST after IDAT");
1410
png_crc_finish(png_ptr, length);
1413
else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1415
png_warning(png_ptr, "Missing PLTE before hIST");
1416
png_crc_finish(png_ptr, length);
1419
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1421
png_warning(png_ptr, "Duplicate hIST chunk");
1422
png_crc_finish(png_ptr, length);
1426
num = (int)length / 2 ;
1427
if (num != png_ptr->num_palette)
1429
png_warning(png_ptr, "Incorrect hIST chunk length");
1430
png_crc_finish(png_ptr, length);
1434
for (i = 0; i < num; i++)
1438
png_crc_read(png_ptr, buf, 2);
1439
readbuf[i] = png_get_uint_16(buf);
1442
if (png_crc_finish(png_ptr, 0))
1445
png_set_hIST(png_ptr, info_ptr, readbuf);
1449
#if defined(PNG_READ_pHYs_SUPPORTED)
1451
png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1454
png_uint_32 res_x, res_y;
1457
png_debug(1, "in png_handle_pHYs\n");
1459
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1460
png_error(png_ptr, "Missing IHDR before pHYs");
1461
else if (png_ptr->mode & PNG_HAVE_IDAT)
1463
png_warning(png_ptr, "Invalid pHYs after IDAT");
1464
png_crc_finish(png_ptr, length);
1467
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1469
png_warning(png_ptr, "Duplicate pHYs chunk");
1470
png_crc_finish(png_ptr, length);
1476
png_warning(png_ptr, "Incorrect pHYs chunk length");
1477
png_crc_finish(png_ptr, length);
1481
png_crc_read(png_ptr, buf, 9);
1482
if (png_crc_finish(png_ptr, 0))
1485
res_x = png_get_uint_32(buf);
1486
res_y = png_get_uint_32(buf + 4);
1488
png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1492
#if defined(PNG_READ_oFFs_SUPPORTED)
1494
png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1497
png_int_32 offset_x, offset_y;
1500
png_debug(1, "in png_handle_oFFs\n");
1502
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1503
png_error(png_ptr, "Missing IHDR before oFFs");
1504
else if (png_ptr->mode & PNG_HAVE_IDAT)
1506
png_warning(png_ptr, "Invalid oFFs after IDAT");
1507
png_crc_finish(png_ptr, length);
1510
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1512
png_warning(png_ptr, "Duplicate oFFs chunk");
1513
png_crc_finish(png_ptr, length);
1519
png_warning(png_ptr, "Incorrect oFFs chunk length");
1520
png_crc_finish(png_ptr, length);
1524
png_crc_read(png_ptr, buf, 9);
1525
if (png_crc_finish(png_ptr, 0))
1528
offset_x = png_get_int_32(buf);
1529
offset_y = png_get_int_32(buf + 4);
1531
png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1535
#if defined(PNG_READ_pCAL_SUPPORTED)
1536
/* read the pCAL chunk (described in the PNG Extensions document) */
1538
png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1542
png_byte type, nparams;
1543
png_charp buf, units, endptr;
1548
png_debug(1, "in png_handle_pCAL\n");
1550
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1551
png_error(png_ptr, "Missing IHDR before pCAL");
1552
else if (png_ptr->mode & PNG_HAVE_IDAT)
1554
png_warning(png_ptr, "Invalid pCAL after IDAT");
1555
png_crc_finish(png_ptr, length);
1558
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1560
png_warning(png_ptr, "Duplicate pCAL chunk");
1561
png_crc_finish(png_ptr, length);
1565
png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1567
purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
1568
if (purpose == NULL)
1570
png_warning(png_ptr, "No memory for pCAL purpose.");
1573
slength = (png_size_t)length;
1574
png_crc_read(png_ptr, (png_bytep)purpose, slength);
1576
if (png_crc_finish(png_ptr, 0))
1578
png_free(png_ptr, purpose);
1582
purpose[slength] = 0x00; /* null terminate the last string */
1584
png_debug(3, "Finding end of pCAL purpose string\n");
1585
for (buf = purpose; *buf; buf++)
1588
endptr = purpose + slength;
1590
/* We need to have at least 12 bytes after the purpose string
1591
in order to get the parameter information. */
1592
if (endptr <= buf + 12)
1594
png_warning(png_ptr, "Invalid pCAL data");
1595
png_free(png_ptr, purpose);
1599
png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1600
X0 = png_get_int_32((png_bytep)buf+1);
1601
X1 = png_get_int_32((png_bytep)buf+5);
1606
png_debug(3, "Checking pCAL equation type and number of parameters\n");
1607
/* Check that we have the right number of parameters for known
1609
if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1610
(type == PNG_EQUATION_BASE_E && nparams != 3) ||
1611
(type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1612
(type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1614
png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1615
png_free(png_ptr, purpose);
1618
else if (type >= PNG_EQUATION_LAST)
1620
png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1623
for (buf = units; *buf; buf++)
1624
/* Empty loop to move past the units string. */ ;
1626
png_debug(3, "Allocating pCAL parameters array\n");
1627
params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
1628
*sizeof(png_charp))) ;
1631
png_free(png_ptr, purpose);
1632
png_warning(png_ptr, "No memory for pCAL params.");
1636
/* Get pointers to the start of each parameter string. */
1637
for (i = 0; i < (int)nparams; i++)
1639
buf++; /* Skip the null string terminator from previous parameter. */
1641
png_debug1(3, "Reading pCAL parameter %d\n", i);
1642
for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
1643
/* Empty loop to move past each parameter string */ ;
1645
/* Make sure we haven't run out of data yet */
1648
png_warning(png_ptr, "Invalid pCAL data");
1649
png_free(png_ptr, purpose);
1650
png_free(png_ptr, params);
1655
png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1658
png_free(png_ptr, purpose);
1659
png_free(png_ptr, params);
1663
#if defined(PNG_READ_sCAL_SUPPORTED)
1664
/* read the sCAL chunk */
1666
png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1668
png_charp buffer, ep;
1669
#ifdef PNG_FLOATING_POINT_SUPPORTED
1670
double width, height;
1673
#ifdef PNG_FIXED_POINT_SUPPORTED
1674
png_charp swidth, sheight;
1679
png_debug(1, "in png_handle_sCAL\n");
1681
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1682
png_error(png_ptr, "Missing IHDR before sCAL");
1683
else if (png_ptr->mode & PNG_HAVE_IDAT)
1685
png_warning(png_ptr, "Invalid sCAL after IDAT");
1686
png_crc_finish(png_ptr, length);
1689
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1691
png_warning(png_ptr, "Duplicate sCAL chunk");
1692
png_crc_finish(png_ptr, length);
1696
png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1698
buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
1701
png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1704
slength = (png_size_t)length;
1705
png_crc_read(png_ptr, (png_bytep)buffer, slength);
1707
if (png_crc_finish(png_ptr, 0))
1709
png_free(png_ptr, buffer);
1713
buffer[slength] = 0x00; /* null terminate the last string */
1715
ep = buffer + 1; /* skip unit byte */
1717
#ifdef PNG_FLOATING_POINT_SUPPORTED
1718
width = strtod(ep, &vp);
1721
png_warning(png_ptr, "malformed width string in sCAL chunk");
1725
#ifdef PNG_FIXED_POINT_SUPPORTED
1726
swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1729
png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1732
png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1736
for (ep = buffer; *ep; ep++)
1740
#ifdef PNG_FLOATING_POINT_SUPPORTED
1741
height = strtod(ep, &vp);
1744
png_warning(png_ptr, "malformed height string in sCAL chunk");
1748
#ifdef PNG_FIXED_POINT_SUPPORTED
1749
sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1752
png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1755
png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1759
if (buffer + slength < ep
1760
#ifdef PNG_FLOATING_POINT_SUPPORTED
1761
|| width <= 0. || height <= 0.
1765
png_warning(png_ptr, "Invalid sCAL data");
1766
png_free(png_ptr, buffer);
1767
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1768
png_free(png_ptr, swidth);
1769
png_free(png_ptr, sheight);
1775
#ifdef PNG_FLOATING_POINT_SUPPORTED
1776
png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
1778
#ifdef PNG_FIXED_POINT_SUPPORTED
1779
png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
1783
png_free(png_ptr, buffer);
1784
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1785
png_free(png_ptr, swidth);
1786
png_free(png_ptr, sheight);
1791
#if defined(PNG_READ_tIME_SUPPORTED)
1793
png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1798
png_debug(1, "in png_handle_tIME\n");
1800
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1801
png_error(png_ptr, "Out of place tIME chunk");
1802
else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1804
png_warning(png_ptr, "Duplicate tIME chunk");
1805
png_crc_finish(png_ptr, length);
1809
if (png_ptr->mode & PNG_HAVE_IDAT)
1810
png_ptr->mode |= PNG_AFTER_IDAT;
1814
png_warning(png_ptr, "Incorrect tIME chunk length");
1815
png_crc_finish(png_ptr, length);
1819
png_crc_read(png_ptr, buf, 7);
1820
if (png_crc_finish(png_ptr, 0))
1823
mod_time.second = buf[6];
1824
mod_time.minute = buf[5];
1825
mod_time.hour = buf[4];
1826
mod_time.day = buf[3];
1827
mod_time.month = buf[2];
1828
mod_time.year = png_get_uint_16(buf);
1830
png_set_tIME(png_ptr, info_ptr, &mod_time);
1834
#if defined(PNG_READ_tEXt_SUPPORTED)
1835
/* Note: this does not properly handle chunks that are > 64K under DOS */
1837
png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1842
png_uint_32 skip = 0;
1846
png_debug(1, "in png_handle_tEXt\n");
1848
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1849
png_error(png_ptr, "Missing IHDR before tEXt");
1851
if (png_ptr->mode & PNG_HAVE_IDAT)
1852
png_ptr->mode |= PNG_AFTER_IDAT;
1854
#ifdef PNG_MAX_MALLOC_64K
1855
if (length > (png_uint_32)65535L)
1857
png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1858
skip = length - (png_uint_32)65535L;
1859
length = (png_uint_32)65535L;
1863
key = (png_charp)png_malloc_warn(png_ptr, length + 1);
1866
png_warning(png_ptr, "No memory to process text chunk.");
1869
slength = (png_size_t)length;
1870
png_crc_read(png_ptr, (png_bytep)key, slength);
1872
if (png_crc_finish(png_ptr, skip))
1874
png_free(png_ptr, key);
1878
key[slength] = 0x00;
1880
for (text = key; *text; text++)
1881
/* empty loop to find end of key */ ;
1883
if (text != key + slength)
1886
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1887
if (text_ptr == NULL)
1889
png_warning(png_ptr, "Not enough memory to process text chunk.");
1890
png_free(png_ptr, key);
1893
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1894
text_ptr->key = key;
1895
#ifdef PNG_iTXt_SUPPORTED
1896
text_ptr->lang = NULL;
1897
text_ptr->lang_key = NULL;
1898
text_ptr->itxt_length = 0;
1900
text_ptr->text = text;
1901
text_ptr->text_length = png_strlen(text);
1903
ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1905
png_free(png_ptr, key);
1906
png_free(png_ptr, text_ptr);
1908
png_warning(png_ptr, "Insufficient memory to process text chunk.");
1912
#if defined(PNG_READ_zTXt_SUPPORTED)
1913
/* note: this does not correctly handle chunks that are > 64K under DOS */
1915
png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1918
png_charp chunkdata;
1922
png_size_t slength, prefix_len, data_len;
1924
png_debug(1, "in png_handle_zTXt\n");
1925
if (!(png_ptr->mode & PNG_HAVE_IHDR))
1926
png_error(png_ptr, "Missing IHDR before zTXt");
1928
if (png_ptr->mode & PNG_HAVE_IDAT)
1929
png_ptr->mode |= PNG_AFTER_IDAT;
1931
#ifdef PNG_MAX_MALLOC_64K
1932
/* We will no doubt have problems with chunks even half this size, but
1933
there is no hard and fast rule to tell us where to stop. */
1934
if (length > (png_uint_32)65535L)
1936
png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1937
png_crc_finish(png_ptr, length);
1942
chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1943
if (chunkdata == NULL)
1945
png_warning(png_ptr,"Out of memory processing zTXt chunk.");
1948
slength = (png_size_t)length;
1949
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
1950
if (png_crc_finish(png_ptr, 0))
1952
png_free(png_ptr, chunkdata);
1956
chunkdata[slength] = 0x00;
1958
for (text = chunkdata; *text; text++)
1961
/* zTXt must have some text after the chunkdataword */
1962
if (text == chunkdata + slength)
1964
comp_type = PNG_TEXT_COMPRESSION_NONE;
1965
png_warning(png_ptr, "Zero length zTXt chunk");
1969
comp_type = *(++text);
1970
if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
1972
png_warning(png_ptr, "Unknown compression type in zTXt chunk");
1973
comp_type = PNG_TEXT_COMPRESSION_zTXt;
1975
text++; /* skip the compression_method byte */
1977
prefix_len = text - chunkdata;
1979
chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
1980
(png_size_t)length, prefix_len, &data_len);
1982
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
1983
if (text_ptr == NULL)
1985
png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
1986
png_free(png_ptr, chunkdata);
1989
text_ptr->compression = comp_type;
1990
text_ptr->key = chunkdata;
1991
#ifdef PNG_iTXt_SUPPORTED
1992
text_ptr->lang = NULL;
1993
text_ptr->lang_key = NULL;
1994
text_ptr->itxt_length = 0;
1996
text_ptr->text = chunkdata + prefix_len;
1997
text_ptr->text_length = data_len;
1999
ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2001
png_free(png_ptr, text_ptr);
2002
png_free(png_ptr, chunkdata);
2004
png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2008
#if defined(PNG_READ_iTXt_SUPPORTED)
2009
/* note: this does not correctly handle chunks that are > 64K under DOS */
2011
png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2014
png_charp chunkdata;
2015
png_charp key, lang, text, lang_key;
2019
png_size_t slength, prefix_len, data_len;
2021
png_debug(1, "in png_handle_iTXt\n");
2023
if (!(png_ptr->mode & PNG_HAVE_IHDR))
2024
png_error(png_ptr, "Missing IHDR before iTXt");
2026
if (png_ptr->mode & PNG_HAVE_IDAT)
2027
png_ptr->mode |= PNG_AFTER_IDAT;
2029
#ifdef PNG_MAX_MALLOC_64K
2030
/* We will no doubt have problems with chunks even half this size, but
2031
there is no hard and fast rule to tell us where to stop. */
2032
if (length > (png_uint_32)65535L)
2034
png_warning(png_ptr,"iTXt chunk too large to fit in memory");
2035
png_crc_finish(png_ptr, length);
2040
chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2041
if (chunkdata == NULL)
2043
png_warning(png_ptr, "No memory to process iTXt chunk.");
2046
slength = (png_size_t)length;
2047
png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
2048
if (png_crc_finish(png_ptr, 0))
2050
png_free(png_ptr, chunkdata);
2054
chunkdata[slength] = 0x00;
2056
for (lang = chunkdata; *lang; lang++)
2058
lang++; /* skip NUL separator */
2060
/* iTXt must have a language tag (possibly empty), two compression bytes,
2061
translated keyword (possibly empty), and possibly some text after the
2064
if (lang >= chunkdata + slength)
2066
comp_flag = PNG_TEXT_COMPRESSION_NONE;
2067
png_warning(png_ptr, "Zero length iTXt chunk");
2071
comp_flag = *lang++;
2072
comp_type = *lang++;
2075
for (lang_key = lang; *lang_key; lang_key++)
2077
lang_key++; /* skip NUL separator */
2079
for (text = lang_key; *text; text++)
2081
text++; /* skip NUL separator */
2083
prefix_len = text - chunkdata;
2087
chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
2088
(size_t)length, prefix_len, &data_len);
2090
data_len=png_strlen(chunkdata + prefix_len);
2091
text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
2092
if (text_ptr == NULL)
2094
png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
2095
png_free(png_ptr, chunkdata);
2098
text_ptr->compression = (int)comp_flag + 1;
2099
text_ptr->lang_key = chunkdata+(lang_key-key);
2100
text_ptr->lang = chunkdata+(lang-key);
2101
text_ptr->itxt_length = data_len;
2102
text_ptr->text_length = 0;
2103
text_ptr->key = chunkdata;
2104
text_ptr->text = chunkdata + prefix_len;
2106
ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2108
png_free(png_ptr, text_ptr);
2109
png_free(png_ptr, chunkdata);
2111
png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2115
/* This function is called when we haven't found a handler for a
2116
chunk. If there isn't a problem with the chunk itself (ie bad
2117
chunk name, CRC, or a critical chunk), the chunk is silently ignored
2118
-- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2119
case it will be saved away to be written out later. */
2121
png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2123
png_uint_32 skip = 0;
2125
png_debug(1, "in png_handle_unknown\n");
2127
if (png_ptr->mode & PNG_HAVE_IDAT)
2129
#ifdef PNG_USE_LOCAL_ARRAYS
2132
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
2133
png_ptr->mode |= PNG_AFTER_IDAT;
2136
png_check_chunk_name(png_ptr, png_ptr->chunk_name);
2138
if (!(png_ptr->chunk_name[0] & 0x20))
2140
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2141
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2143
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2144
&& png_ptr->read_user_chunk_fn == NULL
2148
png_chunk_error(png_ptr, "unknown critical chunk");
2151
#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2152
if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2154
png_unknown_chunk chunk;
2156
#ifdef PNG_MAX_MALLOC_64K
2157
if (length > (png_uint_32)65535L)
2159
png_warning(png_ptr, "unknown chunk too large to fit in memory");
2160
skip = length - (png_uint_32)65535L;
2161
length = (png_uint_32)65535L;
2164
png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
2165
chunk.data = (png_bytep)png_malloc(png_ptr, length);
2166
chunk.size = (png_size_t)length;
2167
png_crc_read(png_ptr, (png_bytep)chunk.data, length);
2168
#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2169
if(png_ptr->read_user_chunk_fn != NULL)
2171
/* callback to user unknown chunk handler */
2172
if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
2174
if (!(png_ptr->chunk_name[0] & 0x20))
2175
if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2176
HANDLE_CHUNK_ALWAYS)
2178
png_free(png_ptr, chunk.data);
2179
png_chunk_error(png_ptr, "unknown critical chunk");
2181
png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2186
png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
2187
png_free(png_ptr, chunk.data);
2193
png_crc_finish(png_ptr, skip);
2195
#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2196
info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
2200
/* This function is called to verify that a chunk name is valid.
2201
This function can't have the "critical chunk check" incorporated
2202
into it, since in the future we will need to be able to call user
2203
functions to handle unknown critical chunks after we check that
2204
the chunk name itself is valid. */
2206
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
2209
png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2211
png_debug(1, "in png_check_chunk_name\n");
2212
if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2213
isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2215
png_chunk_error(png_ptr, "invalid chunk type");
2219
/* Combines the row recently read in with the existing pixels in the
2220
row. This routine takes care of alpha and transparency if requested.
2221
This routine also handles the two methods of progressive display
2222
of interlaced images, depending on the mask value.
2223
The mask value describes which pixels are to be combined with
2224
the row. The pattern always repeats every 8 pixels, so just 8
2225
bits are needed. A one indicates the pixel is to be combined,
2226
a zero indicates the pixel is to be skipped. This is in addition
2227
to any alpha or transparency value associated with the pixel. If
2228
you want all pixels to be combined, pass 0xff (255) in mask. */
2229
#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
2231
png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2233
png_debug(1,"in png_combine_row\n");
2236
png_memcpy(row, png_ptr->row_buf + 1,
2237
(png_size_t)((png_ptr->width *
2238
png_ptr->row_info.pixel_depth + 7) >> 3));
2242
switch (png_ptr->row_info.pixel_depth)
2246
png_bytep sp = png_ptr->row_buf + 1;
2248
int s_inc, s_start, s_end;
2252
png_uint_32 row_width = png_ptr->width;
2254
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2255
if (png_ptr->transformations & PNG_PACKSWAP)
2271
for (i = 0; i < row_width; i++)
2277
value = (*sp >> shift) & 0x01;
2278
*dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2279
*dp |= (png_byte)(value << shift);
2300
png_bytep sp = png_ptr->row_buf + 1;
2302
int s_start, s_end, s_inc;
2306
png_uint_32 row_width = png_ptr->width;
2309
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2310
if (png_ptr->transformations & PNG_PACKSWAP)
2326
for (i = 0; i < row_width; i++)
2330
value = (*sp >> shift) & 0x03;
2331
*dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2332
*dp |= (png_byte)(value << shift);
2352
png_bytep sp = png_ptr->row_buf + 1;
2354
int s_start, s_end, s_inc;
2358
png_uint_32 row_width = png_ptr->width;
2361
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2362
if (png_ptr->transformations & PNG_PACKSWAP)
2377
for (i = 0; i < row_width; i++)
2381
value = (*sp >> shift) & 0xf;
2382
*dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2383
*dp |= (png_byte)(value << shift);
2403
png_bytep sp = png_ptr->row_buf + 1;
2405
png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2407
png_uint_32 row_width = png_ptr->width;
2411
for (i = 0; i < row_width; i++)
2415
png_memcpy(dp, sp, pixel_bytes);
2431
#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
2433
#ifdef PNG_READ_INTERLACING_SUPPORTED
2434
#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
2435
/* OLD pre-1.0.9 interface:
2436
void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2437
png_uint_32 transformations)
2440
png_do_read_interlace(png_structp png_ptr)
2442
png_row_infop row_info = &(png_ptr->row_info);
2443
png_bytep row = png_ptr->row_buf + 1;
2444
int pass = png_ptr->pass;
2445
png_uint_32 transformations = png_ptr->transformations;
2446
#ifdef PNG_USE_LOCAL_ARRAYS
2447
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2448
/* offset to next interlace block */
2449
const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2452
png_debug(1,"in png_do_read_interlace (stock C version)\n");
2453
if (row != NULL && row_info != NULL)
2455
png_uint_32 final_width;
2457
final_width = row_info->width * png_pass_inc[pass];
2459
switch (row_info->pixel_depth)
2463
png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2464
png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2466
int s_start, s_end, s_inc;
2467
int jstop = png_pass_inc[pass];
2472
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2473
if (transformations & PNG_PACKSWAP)
2475
sshift = (int)((row_info->width + 7) & 0x07);
2476
dshift = (int)((final_width + 7) & 0x07);
2484
sshift = 7 - (int)((row_info->width + 7) & 0x07);
2485
dshift = 7 - (int)((final_width + 7) & 0x07);
2491
for (i = 0; i < row_info->width; i++)
2493
v = (png_byte)((*sp >> sshift) & 0x01);
2494
for (j = 0; j < jstop; j++)
2496
*dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2497
*dp |= (png_byte)(v << dshift);
2498
if (dshift == s_end)
2506
if (sshift == s_end)
2518
png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2519
png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2521
int s_start, s_end, s_inc;
2522
int jstop = png_pass_inc[pass];
2525
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2526
if (transformations & PNG_PACKSWAP)
2528
sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2529
dshift = (int)(((final_width + 3) & 0x03) << 1);
2537
sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2538
dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2544
for (i = 0; i < row_info->width; i++)
2549
v = (png_byte)((*sp >> sshift) & 0x03);
2550
for (j = 0; j < jstop; j++)
2552
*dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2553
*dp |= (png_byte)(v << dshift);
2554
if (dshift == s_end)
2562
if (sshift == s_end)
2574
png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2575
png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2577
int s_start, s_end, s_inc;
2579
int jstop = png_pass_inc[pass];
2581
#if defined(PNG_READ_PACKSWAP_SUPPORTED)
2582
if (transformations & PNG_PACKSWAP)
2584
sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2585
dshift = (int)(((final_width + 1) & 0x01) << 2);
2593
sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2594
dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2600
for (i = 0; i < row_info->width; i++)
2602
png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2605
for (j = 0; j < jstop; j++)
2607
*dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2608
*dp |= (png_byte)(v << dshift);
2609
if (dshift == s_end)
2617
if (sshift == s_end)
2629
png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2630
png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
2631
png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2633
int jstop = png_pass_inc[pass];
2636
for (i = 0; i < row_info->width; i++)
2641
png_memcpy(v, sp, pixel_bytes);
2642
for (j = 0; j < jstop; j++)
2644
png_memcpy(dp, v, pixel_bytes);
2652
row_info->width = final_width;
2653
row_info->rowbytes = ((final_width *
2654
(png_uint_32)row_info->pixel_depth + 7) >> 3);
2656
#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2657
transformations = transformations; /* silence compiler warning */
2660
#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
2661
#endif /* PNG_READ_INTERLACING_SUPPORTED */
2663
#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
2665
png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2666
png_bytep prev_row, int filter)
2668
png_debug(1, "in png_read_filter_row\n");
2669
png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
2672
case PNG_FILTER_VALUE_NONE:
2674
case PNG_FILTER_VALUE_SUB:
2677
png_uint_32 istop = row_info->rowbytes;
2678
png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2679
png_bytep rp = row + bpp;
2682
for (i = bpp; i < istop; i++)
2684
*rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2689
case PNG_FILTER_VALUE_UP:
2692
png_uint_32 istop = row_info->rowbytes;
2694
png_bytep pp = prev_row;
2696
for (i = 0; i < istop; i++)
2698
*rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2703
case PNG_FILTER_VALUE_AVG:
2707
png_bytep pp = prev_row;
2709
png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2710
png_uint_32 istop = row_info->rowbytes - bpp;
2712
for (i = 0; i < bpp; i++)
2714
*rp = (png_byte)(((int)(*rp) +
2715
((int)(*pp++) / 2 )) & 0xff);
2719
for (i = 0; i < istop; i++)
2721
*rp = (png_byte)(((int)(*rp) +
2722
(int)(*pp++ + *lp++) / 2 ) & 0xff);
2727
case PNG_FILTER_VALUE_PAETH:
2731
png_bytep pp = prev_row;
2733
png_bytep cp = prev_row;
2734
png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2735
png_uint_32 istop=row_info->rowbytes - bpp;
2737
for (i = 0; i < bpp; i++)
2739
*rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2743
for (i = 0; i < istop; i++) /* use leftover rp,pp */
2745
int a, b, c, pa, pb, pc, p;
2759
pa = p < 0 ? -p : p;
2760
pb = pc < 0 ? -pc : pc;
2761
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
2765
if (pa <= pb && pa <= pc)
2773
p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
2775
*rp = (png_byte)(((int)(*rp) + p) & 0xff);
2781
png_warning(png_ptr, "Ignoring bad adaptive filter type");
2786
#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
2789
png_read_finish_row(png_structp png_ptr)
2791
#ifdef PNG_USE_LOCAL_ARRAYS
2792
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2794
/* start of interlace block */
2795
const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2797
/* offset to next interlace block */
2798
const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2800
/* start of interlace block in the y direction */
2801
const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2803
/* offset to next interlace block in the y direction */
2804
const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2807
png_debug(1, "in png_read_finish_row\n");
2808
png_ptr->row_number++;
2809
if (png_ptr->row_number < png_ptr->num_rows)
2812
if (png_ptr->interlaced)
2814
png_ptr->row_number = 0;
2815
png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2819
if (png_ptr->pass >= 7)
2821
png_ptr->iwidth = (png_ptr->width +
2822
png_pass_inc[png_ptr->pass] - 1 -
2823
png_pass_start[png_ptr->pass]) /
2824
png_pass_inc[png_ptr->pass];
2825
png_ptr->irowbytes = ((png_ptr->iwidth *
2826
(png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2828
if (!(png_ptr->transformations & PNG_INTERLACE))
2830
png_ptr->num_rows = (png_ptr->height +
2831
png_pass_yinc[png_ptr->pass] - 1 -
2832
png_pass_ystart[png_ptr->pass]) /
2833
png_pass_yinc[png_ptr->pass];
2834
if (!(png_ptr->num_rows))
2837
else /* if (png_ptr->transformations & PNG_INTERLACE) */
2839
} while (png_ptr->iwidth == 0);
2841
if (png_ptr->pass < 7)
2845
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2847
#ifdef PNG_USE_LOCAL_ARRAYS
2853
png_ptr->zstream.next_out = (Byte *)&extra;
2854
png_ptr->zstream.avail_out = (uInt)1;
2857
if (!(png_ptr->zstream.avail_in))
2859
while (!png_ptr->idat_size)
2861
png_byte chunk_length[4];
2863
png_crc_finish(png_ptr, 0);
2865
png_read_data(png_ptr, chunk_length, 4);
2866
png_ptr->idat_size = png_get_uint_32(chunk_length);
2868
png_reset_crc(png_ptr);
2869
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
2870
if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
2871
png_error(png_ptr, "Not enough image data");
2874
png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
2875
png_ptr->zstream.next_in = png_ptr->zbuf;
2876
if (png_ptr->zbuf_size > png_ptr->idat_size)
2877
png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
2878
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
2879
png_ptr->idat_size -= png_ptr->zstream.avail_in;
2881
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2882
if (ret == Z_STREAM_END)
2884
if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2886
png_warning(png_ptr, "Extra compressed data");
2887
png_ptr->mode |= PNG_AFTER_IDAT;
2888
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2892
png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2893
"Decompression Error");
2895
if (!(png_ptr->zstream.avail_out))
2897
png_warning(png_ptr, "Extra compressed data.");
2898
png_ptr->mode |= PNG_AFTER_IDAT;
2899
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2904
png_ptr->zstream.avail_out = 0;
2907
if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2908
png_warning(png_ptr, "Extra compression data");
2910
inflateReset(&png_ptr->zstream);
2912
png_ptr->mode |= PNG_AFTER_IDAT;
2916
png_read_start_row(png_structp png_ptr)
2918
#ifdef PNG_USE_LOCAL_ARRAYS
2919
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2921
/* start of interlace block */
2922
const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
2924
/* offset to next interlace block */
2925
const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2927
/* start of interlace block in the y direction */
2928
const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
2930
/* offset to next interlace block in the y direction */
2931
const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
2934
int max_pixel_depth;
2935
png_uint_32 row_bytes;
2937
png_debug(1, "in png_read_start_row\n");
2938
png_ptr->zstream.avail_in = 0;
2939
png_init_read_transformations(png_ptr);
2940
if (png_ptr->interlaced)
2942
if (!(png_ptr->transformations & PNG_INTERLACE))
2943
png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
2944
png_pass_ystart[0]) / png_pass_yinc[0];
2946
png_ptr->num_rows = png_ptr->height;
2948
png_ptr->iwidth = (png_ptr->width +
2949
png_pass_inc[png_ptr->pass] - 1 -
2950
png_pass_start[png_ptr->pass]) /
2951
png_pass_inc[png_ptr->pass];
2953
row_bytes = ((png_ptr->iwidth *
2954
(png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
2955
png_ptr->irowbytes = (png_size_t)row_bytes;
2956
if((png_uint_32)png_ptr->irowbytes != row_bytes)
2957
png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
2961
png_ptr->num_rows = png_ptr->height;
2962
png_ptr->iwidth = png_ptr->width;
2963
png_ptr->irowbytes = png_ptr->rowbytes + 1;
2965
max_pixel_depth = png_ptr->pixel_depth;
2967
#if defined(PNG_READ_PACK_SUPPORTED)
2968
if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2969
max_pixel_depth = 8;
2972
#if defined(PNG_READ_EXPAND_SUPPORTED)
2973
if (png_ptr->transformations & PNG_EXPAND)
2975
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2977
if (png_ptr->num_trans)
2978
max_pixel_depth = 32;
2980
max_pixel_depth = 24;
2982
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2984
if (max_pixel_depth < 8)
2985
max_pixel_depth = 8;
2986
if (png_ptr->num_trans)
2987
max_pixel_depth *= 2;
2989
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2991
if (png_ptr->num_trans)
2993
max_pixel_depth *= 4;
2994
max_pixel_depth /= 3;
3000
#if defined(PNG_READ_FILLER_SUPPORTED)
3001
if (png_ptr->transformations & (PNG_FILLER))
3003
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3004
max_pixel_depth = 32;
3005
else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3007
if (max_pixel_depth <= 8)
3008
max_pixel_depth = 16;
3010
max_pixel_depth = 32;
3012
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3014
if (max_pixel_depth <= 32)
3015
max_pixel_depth = 32;
3017
max_pixel_depth = 64;
3022
#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3023
if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3026
#if defined(PNG_READ_EXPAND_SUPPORTED)
3027
(png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3029
#if defined(PNG_READ_FILLER_SUPPORTED)
3030
(png_ptr->transformations & (PNG_FILLER)) ||
3032
png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3034
if (max_pixel_depth <= 16)
3035
max_pixel_depth = 32;
3037
max_pixel_depth = 64;
3041
if (max_pixel_depth <= 8)
3043
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3044
max_pixel_depth = 32;
3046
max_pixel_depth = 24;
3048
else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3049
max_pixel_depth = 64;
3051
max_pixel_depth = 48;
3056
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3057
defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3058
if(png_ptr->transformations & PNG_USER_TRANSFORM)
3060
int user_pixel_depth=png_ptr->user_transform_depth*
3061
png_ptr->user_transform_channels;
3062
if(user_pixel_depth > max_pixel_depth)
3063
max_pixel_depth=user_pixel_depth;
3067
/* align the width on the next larger 8 pixels. Mainly used
3069
row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3070
/* calculate the maximum bytes needed, adding a byte and a pixel
3071
for safety's sake */
3072
row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
3073
1 + ((max_pixel_depth + 7) >> 3);
3074
#ifdef PNG_MAX_MALLOC_64K
3075
if (row_bytes > (png_uint_32)65536L)
3076
png_error(png_ptr, "This image requires a row greater than 64KB");
3078
png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
3079
png_ptr->row_buf = png_ptr->big_row_buf+32;
3080
#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3081
png_ptr->row_buf_size = row_bytes;
3084
#ifdef PNG_MAX_MALLOC_64K
3085
if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
3086
png_error(png_ptr, "This image requires a row greater than 64KB");
3088
png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3089
png_ptr->rowbytes + 1));
3091
png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3093
png_debug1(3, "width = %lu,\n", png_ptr->width);
3094
png_debug1(3, "height = %lu,\n", png_ptr->height);
3095
png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
3096
png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
3097
png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
3098
png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
3100
png_ptr->flags |= PNG_FLAG_ROW_INIT;