2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.19 August 19, 2007
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1998-2007 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(PNG_READ_SUPPORTED)
19 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
20 # define WIN32_WCE_OLD
23 #ifdef PNG_FLOATING_POINT_SUPPORTED
24 # if defined(WIN32_WCE_OLD)
25 /* strtod() function is not supported on WindowsCE */
26 __inline
double png_strtod(png_structp png_ptr
, PNG_CONST
char *nptr
, char **endptr
)
32 len
= MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, NULL
, 0);
33 str
= (wchar_t *)png_malloc(png_ptr
, len
* sizeof(wchar_t));
36 MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, str
, len
);
37 result
= wcstod(str
, &end
);
38 len
= WideCharToMultiByte(CP_ACP
, 0, end
, -1, NULL
, 0, NULL
, NULL
);
39 *endptr
= (char *)nptr
+ (png_strlen(nptr
) - len
+ 1);
40 png_free(png_ptr
, str
);
45 # define png_strtod(p,a,b) strtod(a,b)
50 png_get_uint_31(png_structp png_ptr
, png_bytep buf
)
52 png_uint_32 i
= png_get_uint_32(buf
);
53 if (i
> PNG_UINT_31_MAX
)
54 png_error(png_ptr
, "PNG unsigned integer out of range.");
57 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
58 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
60 png_get_uint_32(png_bytep buf
)
62 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
63 ((png_uint_32
)(*(buf
+ 1)) << 16) +
64 ((png_uint_32
)(*(buf
+ 2)) << 8) +
65 (png_uint_32
)(*(buf
+ 3));
70 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
71 * data is stored in the PNG file in two's complement format, and it is
72 * assumed that the machine format for signed integers is the same. */
74 png_get_int_32(png_bytep buf
)
76 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
77 ((png_int_32
)(*(buf
+ 1)) << 16) +
78 ((png_int_32
)(*(buf
+ 2)) << 8) +
79 (png_int_32
)(*(buf
+ 3));
84 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
86 png_get_uint_16(png_bytep buf
)
88 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
89 (png_uint_16
)(*(buf
+ 1)));
93 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
95 /* Read data, and (optionally) run it through the CRC. */
97 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
99 if(png_ptr
== NULL
) return;
100 png_read_data(png_ptr
, buf
, length
);
101 png_calculate_crc(png_ptr
, buf
, length
);
104 /* Optionally skip data and then check the CRC. Depending on whether we
105 are reading a ancillary or critical chunk, and how the program has set
106 things up, we may calculate the CRC on the data and print a message.
107 Returns '1' if there was a CRC error, '0' otherwise. */
109 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
112 png_size_t istop
= png_ptr
->zbuf_size
;
114 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
116 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
120 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
123 if (png_crc_error(png_ptr
))
125 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
126 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
127 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
128 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
130 png_chunk_warning(png_ptr
, "CRC error");
134 png_chunk_error(png_ptr
, "CRC error");
142 /* Compare the CRC stored in the PNG file with that calculated by libpng from
143 the data it has read thus far. */
145 png_crc_error(png_structp png_ptr
)
147 png_byte crc_bytes
[4];
151 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
153 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
154 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
159 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
163 png_read_data(png_ptr
, crc_bytes
, 4);
167 crc
= png_get_uint_32(crc_bytes
);
168 return ((int)(crc
!= png_ptr
->crc
));
174 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
175 defined(PNG_READ_iCCP_SUPPORTED)
177 * Decompress trailing data in a chunk. The assumption is that chunkdata
178 * points at an allocated area holding the contents of a chunk with a
179 * trailing compressed part. What we get back is an allocated area
180 * holding the original prefix part and an uncompressed version of the
181 * trailing part (the malloc area passed in is freed).
183 png_charp
/* PRIVATE */
184 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
185 png_charp chunkdata
, png_size_t chunklength
,
186 png_size_t prefix_size
, png_size_t
*newlength
)
188 static PNG_CONST
char msg
[] = "Error decoding compressed text";
190 png_size_t text_size
;
192 if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
195 png_ptr
->zstream
.next_in
= (png_bytep
)(chunkdata
+ prefix_size
);
196 png_ptr
->zstream
.avail_in
= (uInt
)(chunklength
- prefix_size
);
197 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
198 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
203 while (png_ptr
->zstream
.avail_in
)
205 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
206 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
208 if (png_ptr
->zstream
.msg
!= NULL
)
209 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
211 png_warning(png_ptr
, msg
);
212 inflateReset(&png_ptr
->zstream
);
213 png_ptr
->zstream
.avail_in
= 0;
217 text_size
= prefix_size
+ png_sizeof(msg
) + 1;
218 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
);
221 png_free(png_ptr
,chunkdata
);
222 png_error(png_ptr
,"Not enough memory to decompress chunk");
224 png_memcpy(text
, chunkdata
, prefix_size
);
227 text
[text_size
- 1] = 0x00;
229 /* Copy what we can of the error message into the text chunk */
230 text_size
= (png_size_t
)(chunklength
- (text
- chunkdata
) - 1);
231 text_size
= png_sizeof(msg
) > text_size
? text_size
:
233 png_memcpy(text
+ prefix_size
, msg
, text_size
+ 1);
236 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
240 text_size
= prefix_size
+
241 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
242 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+ 1);
245 png_free(png_ptr
,chunkdata
);
246 png_error(png_ptr
,"Not enough memory to decompress chunk.");
248 png_memcpy(text
+ prefix_size
, png_ptr
->zbuf
,
249 text_size
- prefix_size
);
250 png_memcpy(text
, chunkdata
, prefix_size
);
251 *(text
+ text_size
) = 0x00;
258 text
= (png_charp
)png_malloc_warn(png_ptr
,
259 (png_uint_32
)(text_size
+
260 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
263 png_free(png_ptr
, tmp
);
264 png_free(png_ptr
, chunkdata
);
265 png_error(png_ptr
,"Not enough memory to decompress chunk..");
267 png_memcpy(text
, tmp
, text_size
);
268 png_free(png_ptr
, tmp
);
269 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
270 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
271 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
272 *(text
+ text_size
) = 0x00;
274 if (ret
== Z_STREAM_END
)
278 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
279 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
283 if (ret
!= Z_STREAM_END
)
285 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
288 if (ret
== Z_BUF_ERROR
)
289 png_snprintf(umsg
, 52,
290 "Buffer error in compressed datastream in %s chunk",
291 png_ptr
->chunk_name
);
292 else if (ret
== Z_DATA_ERROR
)
293 png_snprintf(umsg
, 52,
294 "Data error in compressed datastream in %s chunk",
295 png_ptr
->chunk_name
);
297 png_snprintf(umsg
, 52,
298 "Incomplete compressed datastream in %s chunk",
299 png_ptr
->chunk_name
);
300 png_warning(png_ptr
, umsg
);
303 "Incomplete compressed datastream in chunk other than IDAT");
305 text_size
=prefix_size
;
308 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+1);
311 png_free(png_ptr
, chunkdata
);
312 png_error(png_ptr
,"Not enough memory for text.");
314 png_memcpy(text
, chunkdata
, prefix_size
);
316 *(text
+ text_size
) = 0x00;
319 inflateReset(&png_ptr
->zstream
);
320 png_ptr
->zstream
.avail_in
= 0;
322 png_free(png_ptr
, chunkdata
);
324 *newlength
=text_size
;
326 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
328 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
331 png_snprintf(umsg
, 50,
332 "Unknown zTXt compression type %d", comp_type
);
333 png_warning(png_ptr
, umsg
);
335 png_warning(png_ptr
, "Unknown zTXt compression type");
338 *(chunkdata
+ prefix_size
) = 0x00;
339 *newlength
=prefix_size
;
346 /* read and check the IDHR chunk */
348 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
351 png_uint_32 width
, height
;
352 int bit_depth
, color_type
, compression_type
, filter_type
;
355 png_debug(1, "in png_handle_IHDR\n");
357 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
358 png_error(png_ptr
, "Out of place IHDR");
360 /* check the length */
362 png_error(png_ptr
, "Invalid IHDR chunk");
364 png_ptr
->mode
|= PNG_HAVE_IHDR
;
366 png_crc_read(png_ptr
, buf
, 13);
367 png_crc_finish(png_ptr
, 0);
369 width
= png_get_uint_31(png_ptr
, buf
);
370 height
= png_get_uint_31(png_ptr
, buf
+ 4);
373 compression_type
= buf
[10];
374 filter_type
= buf
[11];
375 interlace_type
= buf
[12];
377 /* set internal variables */
378 png_ptr
->width
= width
;
379 png_ptr
->height
= height
;
380 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
381 png_ptr
->interlaced
= (png_byte
)interlace_type
;
382 png_ptr
->color_type
= (png_byte
)color_type
;
383 #if defined(PNG_MNG_FEATURES_SUPPORTED)
384 png_ptr
->filter_type
= (png_byte
)filter_type
;
386 png_ptr
->compression_type
= (png_byte
)compression_type
;
388 /* find number of channels */
389 switch (png_ptr
->color_type
)
391 case PNG_COLOR_TYPE_GRAY
:
392 case PNG_COLOR_TYPE_PALETTE
:
393 png_ptr
->channels
= 1;
395 case PNG_COLOR_TYPE_RGB
:
396 png_ptr
->channels
= 3;
398 case PNG_COLOR_TYPE_GRAY_ALPHA
:
399 png_ptr
->channels
= 2;
401 case PNG_COLOR_TYPE_RGB_ALPHA
:
402 png_ptr
->channels
= 4;
406 /* set up other useful info */
407 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
409 png_ptr
->rowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,png_ptr
->width
);
410 png_debug1(3,"bit_depth = %d\n", png_ptr
->bit_depth
);
411 png_debug1(3,"channels = %d\n", png_ptr
->channels
);
412 png_debug1(3,"rowbytes = %lu\n", png_ptr
->rowbytes
);
413 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
414 color_type
, interlace_type
, compression_type
, filter_type
);
417 /* read and check the palette */
419 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
421 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
423 #ifndef PNG_NO_POINTER_INDEXING
427 png_debug(1, "in png_handle_PLTE\n");
429 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
430 png_error(png_ptr
, "Missing IHDR before PLTE");
431 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
433 png_warning(png_ptr
, "Invalid PLTE after IDAT");
434 png_crc_finish(png_ptr
, length
);
437 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
438 png_error(png_ptr
, "Duplicate PLTE chunk");
440 png_ptr
->mode
|= PNG_HAVE_PLTE
;
442 if (!(png_ptr
->color_type
&PNG_COLOR_MASK_COLOR
))
445 "Ignoring PLTE chunk in grayscale PNG");
446 png_crc_finish(png_ptr
, length
);
449 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
450 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
452 png_crc_finish(png_ptr
, length
);
457 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
459 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
461 png_warning(png_ptr
, "Invalid palette chunk");
462 png_crc_finish(png_ptr
, length
);
467 png_error(png_ptr
, "Invalid palette chunk");
471 num
= (int)length
/ 3;
473 #ifndef PNG_NO_POINTER_INDEXING
474 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
478 png_crc_read(png_ptr
, buf
, 3);
479 pal_ptr
->red
= buf
[0];
480 pal_ptr
->green
= buf
[1];
481 pal_ptr
->blue
= buf
[2];
484 for (i
= 0; i
< num
; i
++)
488 png_crc_read(png_ptr
, buf
, 3);
489 /* don't depend upon png_color being any order */
490 palette
[i
].red
= buf
[0];
491 palette
[i
].green
= buf
[1];
492 palette
[i
].blue
= buf
[2];
496 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
497 whatever the normal CRC configuration tells us. However, if we
498 have an RGB image, the PLTE can be considered ancillary, so
499 we will act as though it is. */
500 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
501 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
504 png_crc_finish(png_ptr
, 0);
506 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
507 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
509 /* If we don't want to use the data from an ancillary chunk,
510 we have two options: an error abort, or a warning and we
511 ignore the data in this chunk (which should be OK, since
512 it's considered ancillary for a RGB or RGBA image). */
513 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
515 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
517 png_chunk_error(png_ptr
, "CRC error");
521 png_chunk_warning(png_ptr
, "CRC error");
525 /* Otherwise, we (optionally) emit a warning and use the chunk. */
526 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
528 png_chunk_warning(png_ptr
, "CRC error");
533 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
535 #if defined(PNG_READ_tRNS_SUPPORTED)
536 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
538 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
540 if (png_ptr
->num_trans
> (png_uint_16
)num
)
542 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
543 png_ptr
->num_trans
= (png_uint_16
)num
;
545 if (info_ptr
->num_trans
> (png_uint_16
)num
)
547 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
548 info_ptr
->num_trans
= (png_uint_16
)num
;
557 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
559 png_debug(1, "in png_handle_IEND\n");
561 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
563 png_error(png_ptr
, "No image in file");
566 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
570 png_warning(png_ptr
, "Incorrect IEND chunk length");
572 png_crc_finish(png_ptr
, length
);
574 info_ptr
=info_ptr
; /* quiet compiler warnings about unused info_ptr */
577 #if defined(PNG_READ_gAMA_SUPPORTED)
579 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
581 png_fixed_point igamma
;
582 #ifdef PNG_FLOATING_POINT_SUPPORTED
587 png_debug(1, "in png_handle_gAMA\n");
589 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
590 png_error(png_ptr
, "Missing IHDR before gAMA");
591 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
593 png_warning(png_ptr
, "Invalid gAMA after IDAT");
594 png_crc_finish(png_ptr
, length
);
597 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
598 /* Should be an error, but we can cope with it */
599 png_warning(png_ptr
, "Out of place gAMA chunk");
601 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
602 #if defined(PNG_READ_sRGB_SUPPORTED)
603 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
607 png_warning(png_ptr
, "Duplicate gAMA chunk");
608 png_crc_finish(png_ptr
, length
);
614 png_warning(png_ptr
, "Incorrect gAMA chunk length");
615 png_crc_finish(png_ptr
, length
);
619 png_crc_read(png_ptr
, buf
, 4);
620 if (png_crc_finish(png_ptr
, 0))
623 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
624 /* check for zero gamma */
628 "Ignoring gAMA chunk with gamma=0");
632 #if defined(PNG_READ_sRGB_SUPPORTED)
633 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
634 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
637 "Ignoring incorrect gAMA value when sRGB is also present");
638 #ifndef PNG_NO_CONSOLE_IO
639 fprintf(stderr
, "gamma = (%d/100000)\n", (int)igamma
);
643 #endif /* PNG_READ_sRGB_SUPPORTED */
645 #ifdef PNG_FLOATING_POINT_SUPPORTED
646 file_gamma
= (float)igamma
/ (float)100000.0;
647 # ifdef PNG_READ_GAMMA_SUPPORTED
648 png_ptr
->gamma
= file_gamma
;
650 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
652 #ifdef PNG_FIXED_POINT_SUPPORTED
653 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
658 #if defined(PNG_READ_sBIT_SUPPORTED)
660 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
665 png_debug(1, "in png_handle_sBIT\n");
667 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
669 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
670 png_error(png_ptr
, "Missing IHDR before sBIT");
671 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
673 png_warning(png_ptr
, "Invalid sBIT after IDAT");
674 png_crc_finish(png_ptr
, length
);
677 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
679 /* Should be an error, but we can cope with it */
680 png_warning(png_ptr
, "Out of place sBIT chunk");
682 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
684 png_warning(png_ptr
, "Duplicate sBIT chunk");
685 png_crc_finish(png_ptr
, length
);
689 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
692 truelen
= (png_size_t
)png_ptr
->channels
;
694 if (length
!= truelen
|| length
> 4)
696 png_warning(png_ptr
, "Incorrect sBIT chunk length");
697 png_crc_finish(png_ptr
, length
);
701 png_crc_read(png_ptr
, buf
, truelen
);
702 if (png_crc_finish(png_ptr
, 0))
705 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
707 png_ptr
->sig_bit
.red
= buf
[0];
708 png_ptr
->sig_bit
.green
= buf
[1];
709 png_ptr
->sig_bit
.blue
= buf
[2];
710 png_ptr
->sig_bit
.alpha
= buf
[3];
714 png_ptr
->sig_bit
.gray
= buf
[0];
715 png_ptr
->sig_bit
.red
= buf
[0];
716 png_ptr
->sig_bit
.green
= buf
[0];
717 png_ptr
->sig_bit
.blue
= buf
[0];
718 png_ptr
->sig_bit
.alpha
= buf
[1];
720 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
724 #if defined(PNG_READ_cHRM_SUPPORTED)
726 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
729 #ifdef PNG_FLOATING_POINT_SUPPORTED
730 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
732 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
733 int_y_green
, int_x_blue
, int_y_blue
;
735 png_uint_32 uint_x
, uint_y
;
737 png_debug(1, "in png_handle_cHRM\n");
739 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
740 png_error(png_ptr
, "Missing IHDR before cHRM");
741 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
743 png_warning(png_ptr
, "Invalid cHRM after IDAT");
744 png_crc_finish(png_ptr
, length
);
747 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
748 /* Should be an error, but we can cope with it */
749 png_warning(png_ptr
, "Missing PLTE before cHRM");
751 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
752 #if defined(PNG_READ_sRGB_SUPPORTED)
753 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
757 png_warning(png_ptr
, "Duplicate cHRM chunk");
758 png_crc_finish(png_ptr
, length
);
764 png_warning(png_ptr
, "Incorrect cHRM chunk length");
765 png_crc_finish(png_ptr
, length
);
769 png_crc_read(png_ptr
, buf
, 4);
770 uint_x
= png_get_uint_32(buf
);
772 png_crc_read(png_ptr
, buf
, 4);
773 uint_y
= png_get_uint_32(buf
);
775 if (uint_x
> 80000L || uint_y
> 80000L ||
776 uint_x
+ uint_y
> 100000L)
778 png_warning(png_ptr
, "Invalid cHRM white point");
779 png_crc_finish(png_ptr
, 24);
782 int_x_white
= (png_fixed_point
)uint_x
;
783 int_y_white
= (png_fixed_point
)uint_y
;
785 png_crc_read(png_ptr
, buf
, 4);
786 uint_x
= png_get_uint_32(buf
);
788 png_crc_read(png_ptr
, buf
, 4);
789 uint_y
= png_get_uint_32(buf
);
791 if (uint_x
+ uint_y
> 100000L)
793 png_warning(png_ptr
, "Invalid cHRM red point");
794 png_crc_finish(png_ptr
, 16);
797 int_x_red
= (png_fixed_point
)uint_x
;
798 int_y_red
= (png_fixed_point
)uint_y
;
800 png_crc_read(png_ptr
, buf
, 4);
801 uint_x
= png_get_uint_32(buf
);
803 png_crc_read(png_ptr
, buf
, 4);
804 uint_y
= png_get_uint_32(buf
);
806 if (uint_x
+ uint_y
> 100000L)
808 png_warning(png_ptr
, "Invalid cHRM green point");
809 png_crc_finish(png_ptr
, 8);
812 int_x_green
= (png_fixed_point
)uint_x
;
813 int_y_green
= (png_fixed_point
)uint_y
;
815 png_crc_read(png_ptr
, buf
, 4);
816 uint_x
= png_get_uint_32(buf
);
818 png_crc_read(png_ptr
, buf
, 4);
819 uint_y
= png_get_uint_32(buf
);
821 if (uint_x
+ uint_y
> 100000L)
823 png_warning(png_ptr
, "Invalid cHRM blue point");
824 png_crc_finish(png_ptr
, 0);
827 int_x_blue
= (png_fixed_point
)uint_x
;
828 int_y_blue
= (png_fixed_point
)uint_y
;
830 #ifdef PNG_FLOATING_POINT_SUPPORTED
831 white_x
= (float)int_x_white
/ (float)100000.0;
832 white_y
= (float)int_y_white
/ (float)100000.0;
833 red_x
= (float)int_x_red
/ (float)100000.0;
834 red_y
= (float)int_y_red
/ (float)100000.0;
835 green_x
= (float)int_x_green
/ (float)100000.0;
836 green_y
= (float)int_y_green
/ (float)100000.0;
837 blue_x
= (float)int_x_blue
/ (float)100000.0;
838 blue_y
= (float)int_y_blue
/ (float)100000.0;
841 #if defined(PNG_READ_sRGB_SUPPORTED)
842 if ((info_ptr
!= NULL
) && (info_ptr
->valid
& PNG_INFO_sRGB
))
844 if (PNG_OUT_OF_RANGE(int_x_white
, 31270, 1000) ||
845 PNG_OUT_OF_RANGE(int_y_white
, 32900, 1000) ||
846 PNG_OUT_OF_RANGE(int_x_red
, 64000L, 1000) ||
847 PNG_OUT_OF_RANGE(int_y_red
, 33000, 1000) ||
848 PNG_OUT_OF_RANGE(int_x_green
, 30000, 1000) ||
849 PNG_OUT_OF_RANGE(int_y_green
, 60000L, 1000) ||
850 PNG_OUT_OF_RANGE(int_x_blue
, 15000, 1000) ||
851 PNG_OUT_OF_RANGE(int_y_blue
, 6000, 1000))
854 "Ignoring incorrect cHRM value when sRGB is also present");
855 #ifndef PNG_NO_CONSOLE_IO
856 #ifdef PNG_FLOATING_POINT_SUPPORTED
857 fprintf(stderr
,"wx=%f, wy=%f, rx=%f, ry=%f\n",
858 white_x
, white_y
, red_x
, red_y
);
859 fprintf(stderr
,"gx=%f, gy=%f, bx=%f, by=%f\n",
860 green_x
, green_y
, blue_x
, blue_y
);
862 fprintf(stderr
,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
863 int_x_white
, int_y_white
, int_x_red
, int_y_red
);
864 fprintf(stderr
,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
865 int_x_green
, int_y_green
, int_x_blue
, int_y_blue
);
867 #endif /* PNG_NO_CONSOLE_IO */
869 png_crc_finish(png_ptr
, 0);
872 #endif /* PNG_READ_sRGB_SUPPORTED */
874 #ifdef PNG_FLOATING_POINT_SUPPORTED
875 png_set_cHRM(png_ptr
, info_ptr
,
876 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
878 #ifdef PNG_FIXED_POINT_SUPPORTED
879 png_set_cHRM_fixed(png_ptr
, info_ptr
,
880 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
881 int_y_green
, int_x_blue
, int_y_blue
);
883 if (png_crc_finish(png_ptr
, 0))
888 #if defined(PNG_READ_sRGB_SUPPORTED)
890 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
895 png_debug(1, "in png_handle_sRGB\n");
897 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
898 png_error(png_ptr
, "Missing IHDR before sRGB");
899 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
901 png_warning(png_ptr
, "Invalid sRGB after IDAT");
902 png_crc_finish(png_ptr
, length
);
905 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
906 /* Should be an error, but we can cope with it */
907 png_warning(png_ptr
, "Out of place sRGB chunk");
909 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
911 png_warning(png_ptr
, "Duplicate sRGB chunk");
912 png_crc_finish(png_ptr
, length
);
918 png_warning(png_ptr
, "Incorrect sRGB chunk length");
919 png_crc_finish(png_ptr
, length
);
923 png_crc_read(png_ptr
, buf
, 1);
924 if (png_crc_finish(png_ptr
, 0))
928 /* check for bad intent */
929 if (intent
>= PNG_sRGB_INTENT_LAST
)
931 png_warning(png_ptr
, "Unknown sRGB intent");
935 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
936 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
))
938 png_fixed_point igamma
;
939 #ifdef PNG_FIXED_POINT_SUPPORTED
940 igamma
=info_ptr
->int_gamma
;
942 # ifdef PNG_FLOATING_POINT_SUPPORTED
943 igamma
=(png_fixed_point
)(info_ptr
->gamma
* 100000.);
946 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
949 "Ignoring incorrect gAMA value when sRGB is also present");
950 #ifndef PNG_NO_CONSOLE_IO
951 # ifdef PNG_FIXED_POINT_SUPPORTED
952 fprintf(stderr
,"incorrect gamma=(%d/100000)\n",(int)png_ptr
->int_gamma
);
954 # ifdef PNG_FLOATING_POINT_SUPPORTED
955 fprintf(stderr
,"incorrect gamma=%f\n",png_ptr
->gamma
);
961 #endif /* PNG_READ_gAMA_SUPPORTED */
963 #ifdef PNG_READ_cHRM_SUPPORTED
964 #ifdef PNG_FIXED_POINT_SUPPORTED
965 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
))
966 if (PNG_OUT_OF_RANGE(info_ptr
->int_x_white
, 31270, 1000) ||
967 PNG_OUT_OF_RANGE(info_ptr
->int_y_white
, 32900, 1000) ||
968 PNG_OUT_OF_RANGE(info_ptr
->int_x_red
, 64000L, 1000) ||
969 PNG_OUT_OF_RANGE(info_ptr
->int_y_red
, 33000, 1000) ||
970 PNG_OUT_OF_RANGE(info_ptr
->int_x_green
, 30000, 1000) ||
971 PNG_OUT_OF_RANGE(info_ptr
->int_y_green
, 60000L, 1000) ||
972 PNG_OUT_OF_RANGE(info_ptr
->int_x_blue
, 15000, 1000) ||
973 PNG_OUT_OF_RANGE(info_ptr
->int_y_blue
, 6000, 1000))
976 "Ignoring incorrect cHRM value when sRGB is also present");
978 #endif /* PNG_FIXED_POINT_SUPPORTED */
979 #endif /* PNG_READ_cHRM_SUPPORTED */
981 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
983 #endif /* PNG_READ_sRGB_SUPPORTED */
985 #if defined(PNG_READ_iCCP_SUPPORTED)
987 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
988 /* Note: this does not properly handle chunks that are > 64K under DOS */
991 png_byte compression_type
;
994 png_uint_32 skip
= 0;
995 png_uint_32 profile_size
, profile_length
;
996 png_size_t slength
, prefix_length
, data_length
;
998 png_debug(1, "in png_handle_iCCP\n");
1000 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1001 png_error(png_ptr
, "Missing IHDR before iCCP");
1002 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1004 png_warning(png_ptr
, "Invalid iCCP after IDAT");
1005 png_crc_finish(png_ptr
, length
);
1008 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
1009 /* Should be an error, but we can cope with it */
1010 png_warning(png_ptr
, "Out of place iCCP chunk");
1012 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
1014 png_warning(png_ptr
, "Duplicate iCCP chunk");
1015 png_crc_finish(png_ptr
, length
);
1019 #ifdef PNG_MAX_MALLOC_64K
1020 if (length
> (png_uint_32
)65535L)
1022 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
1023 skip
= length
- (png_uint_32
)65535L;
1024 length
= (png_uint_32
)65535L;
1028 chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1029 slength
= (png_size_t
)length
;
1030 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1032 if (png_crc_finish(png_ptr
, skip
))
1034 png_free(png_ptr
, chunkdata
);
1038 chunkdata
[slength
] = 0x00;
1040 for (profile
= chunkdata
; *profile
; profile
++)
1041 /* empty loop to find end of name */ ;
1045 /* there should be at least one zero (the compression type byte)
1046 following the separator, and we should be on it */
1047 if ( profile
>= chunkdata
+ slength
- 1)
1049 png_free(png_ptr
, chunkdata
);
1050 png_warning(png_ptr
, "Malformed iCCP chunk");
1054 /* compression_type should always be zero */
1055 compression_type
= *profile
++;
1056 if (compression_type
)
1058 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1059 compression_type
=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1063 prefix_length
= profile
- chunkdata
;
1064 chunkdata
= png_decompress_chunk(png_ptr
, compression_type
, chunkdata
,
1065 slength
, prefix_length
, &data_length
);
1067 profile_length
= data_length
- prefix_length
;
1069 if ( prefix_length
> data_length
|| profile_length
< 4)
1071 png_free(png_ptr
, chunkdata
);
1072 png_warning(png_ptr
, "Profile size field missing from iCCP chunk");
1076 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1077 pC
= (png_bytep
)(chunkdata
+prefix_length
);
1078 profile_size
= ((*(pC
))<<24) |
1083 if(profile_size
< profile_length
)
1084 profile_length
= profile_size
;
1086 if(profile_size
> profile_length
)
1088 png_free(png_ptr
, chunkdata
);
1089 png_warning(png_ptr
, "Ignoring truncated iCCP profile.");
1093 png_set_iCCP(png_ptr
, info_ptr
, chunkdata
, compression_type
,
1094 chunkdata
+ prefix_length
, profile_length
);
1095 png_free(png_ptr
, chunkdata
);
1097 #endif /* PNG_READ_iCCP_SUPPORTED */
1099 #if defined(PNG_READ_sPLT_SUPPORTED)
1101 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1102 /* Note: this does not properly handle chunks that are > 64K under DOS */
1104 png_bytep chunkdata
;
1105 png_bytep entry_start
;
1106 png_sPLT_t new_palette
;
1107 #ifdef PNG_NO_POINTER_INDEXING
1110 int data_length
, entry_size
, i
;
1111 png_uint_32 skip
= 0;
1114 png_debug(1, "in png_handle_sPLT\n");
1116 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1117 png_error(png_ptr
, "Missing IHDR before sPLT");
1118 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1120 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1121 png_crc_finish(png_ptr
, length
);
1125 #ifdef PNG_MAX_MALLOC_64K
1126 if (length
> (png_uint_32
)65535L)
1128 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1129 skip
= length
- (png_uint_32
)65535L;
1130 length
= (png_uint_32
)65535L;
1134 chunkdata
= (png_bytep
)png_malloc(png_ptr
, length
+ 1);
1135 slength
= (png_size_t
)length
;
1136 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1138 if (png_crc_finish(png_ptr
, skip
))
1140 png_free(png_ptr
, chunkdata
);
1144 chunkdata
[slength
] = 0x00;
1146 for (entry_start
= chunkdata
; *entry_start
; entry_start
++)
1147 /* empty loop to find end of name */ ;
1150 /* a sample depth should follow the separator, and we should be on it */
1151 if (entry_start
> chunkdata
+ slength
- 2)
1153 png_free(png_ptr
, chunkdata
);
1154 png_warning(png_ptr
, "malformed sPLT chunk");
1158 new_palette
.depth
= *entry_start
++;
1159 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1160 data_length
= (slength
- (entry_start
- chunkdata
));
1162 /* integrity-check the data length */
1163 if (data_length
% entry_size
)
1165 png_free(png_ptr
, chunkdata
);
1166 png_warning(png_ptr
, "sPLT chunk has bad length");
1170 new_palette
.nentries
= (png_int_32
) ( data_length
/ entry_size
);
1171 if ((png_uint_32
) new_palette
.nentries
> (png_uint_32
) (PNG_SIZE_MAX
/
1172 png_sizeof(png_sPLT_entry
)))
1174 png_warning(png_ptr
, "sPLT chunk too long");
1177 new_palette
.entries
= (png_sPLT_entryp
)png_malloc_warn(
1178 png_ptr
, new_palette
.nentries
* png_sizeof(png_sPLT_entry
));
1179 if (new_palette
.entries
== NULL
)
1181 png_warning(png_ptr
, "sPLT chunk requires too much memory");
1185 #ifndef PNG_NO_POINTER_INDEXING
1186 for (i
= 0; i
< new_palette
.nentries
; i
++)
1188 png_sPLT_entryp pp
= new_palette
.entries
+ i
;
1190 if (new_palette
.depth
== 8)
1192 pp
->red
= *entry_start
++;
1193 pp
->green
= *entry_start
++;
1194 pp
->blue
= *entry_start
++;
1195 pp
->alpha
= *entry_start
++;
1199 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1200 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1201 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1202 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1204 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1207 pp
= new_palette
.entries
;
1208 for (i
= 0; i
< new_palette
.nentries
; i
++)
1211 if (new_palette
.depth
== 8)
1213 pp
[i
].red
= *entry_start
++;
1214 pp
[i
].green
= *entry_start
++;
1215 pp
[i
].blue
= *entry_start
++;
1216 pp
[i
].alpha
= *entry_start
++;
1220 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1221 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1222 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1223 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1225 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1229 /* discard all chunk data except the name and stash that */
1230 new_palette
.name
= (png_charp
)chunkdata
;
1232 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1234 png_free(png_ptr
, chunkdata
);
1235 png_free(png_ptr
, new_palette
.entries
);
1237 #endif /* PNG_READ_sPLT_SUPPORTED */
1239 #if defined(PNG_READ_tRNS_SUPPORTED)
1241 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1243 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1246 png_debug(1, "in png_handle_tRNS\n");
1248 /* For non-indexed color, mask off any bits in the tRNS value that
1249 * exceed the bit depth. Some creators were writing extra bits there.
1250 * This is not needed for indexed color. */
1251 bit_mask
= (1 << png_ptr
->bit_depth
) - 1;
1253 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1254 png_error(png_ptr
, "Missing IHDR before tRNS");
1255 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1257 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1258 png_crc_finish(png_ptr
, length
);
1261 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1263 png_warning(png_ptr
, "Duplicate tRNS chunk");
1264 png_crc_finish(png_ptr
, length
);
1268 if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1274 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1275 png_crc_finish(png_ptr
, length
);
1279 png_crc_read(png_ptr
, buf
, 2);
1280 png_ptr
->num_trans
= 1;
1281 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
) & bit_mask
;
1283 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1289 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1290 png_crc_finish(png_ptr
, length
);
1293 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1294 png_ptr
->num_trans
= 1;
1295 png_ptr
->trans_values
.red
= png_get_uint_16(buf
) & bit_mask
;
1296 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2) & bit_mask
;
1297 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4) & bit_mask
;
1299 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1301 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1303 /* Should be an error, but we can cope with it. */
1304 png_warning(png_ptr
, "Missing PLTE before tRNS");
1306 if (length
> (png_uint_32
)png_ptr
->num_palette
||
1307 length
> PNG_MAX_PALETTE_LENGTH
)
1309 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1310 png_crc_finish(png_ptr
, length
);
1315 png_warning(png_ptr
, "Zero length tRNS chunk");
1316 png_crc_finish(png_ptr
, length
);
1319 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1320 png_ptr
->num_trans
= (png_uint_16
)length
;
1324 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1325 png_crc_finish(png_ptr
, length
);
1329 if (png_crc_finish(png_ptr
, 0))
1331 png_ptr
->num_trans
= 0;
1335 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1336 &(png_ptr
->trans_values
));
1340 #if defined(PNG_READ_bKGD_SUPPORTED)
1342 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1347 png_debug(1, "in png_handle_bKGD\n");
1349 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1350 png_error(png_ptr
, "Missing IHDR before bKGD");
1351 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1353 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1354 png_crc_finish(png_ptr
, length
);
1357 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1358 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1360 png_warning(png_ptr
, "Missing PLTE before bKGD");
1361 png_crc_finish(png_ptr
, length
);
1364 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1366 png_warning(png_ptr
, "Duplicate bKGD chunk");
1367 png_crc_finish(png_ptr
, length
);
1371 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1373 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1378 if (length
!= truelen
)
1380 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1381 png_crc_finish(png_ptr
, length
);
1385 png_crc_read(png_ptr
, buf
, truelen
);
1386 if (png_crc_finish(png_ptr
, 0))
1389 /* We convert the index value into RGB components so that we can allow
1390 * arbitrary RGB values for background when we have transparency, and
1391 * so it is easy to determine the RGB values of the background color
1392 * from the info_ptr struct. */
1393 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1395 png_ptr
->background
.index
= buf
[0];
1396 if(info_ptr
->num_palette
)
1398 if(buf
[0] > info_ptr
->num_palette
)
1400 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1403 png_ptr
->background
.red
=
1404 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1405 png_ptr
->background
.green
=
1406 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1407 png_ptr
->background
.blue
=
1408 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1411 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1413 png_ptr
->background
.red
=
1414 png_ptr
->background
.green
=
1415 png_ptr
->background
.blue
=
1416 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1420 png_ptr
->background
.red
= png_get_uint_16(buf
);
1421 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1422 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1425 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1429 #if defined(PNG_READ_hIST_SUPPORTED)
1431 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1433 unsigned int num
, i
;
1434 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1436 png_debug(1, "in png_handle_hIST\n");
1438 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1439 png_error(png_ptr
, "Missing IHDR before hIST");
1440 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1442 png_warning(png_ptr
, "Invalid hIST after IDAT");
1443 png_crc_finish(png_ptr
, length
);
1446 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1448 png_warning(png_ptr
, "Missing PLTE before hIST");
1449 png_crc_finish(png_ptr
, length
);
1452 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1454 png_warning(png_ptr
, "Duplicate hIST chunk");
1455 png_crc_finish(png_ptr
, length
);
1460 if (num
!= (unsigned int) png_ptr
->num_palette
|| num
>
1461 (unsigned int) PNG_MAX_PALETTE_LENGTH
)
1463 png_warning(png_ptr
, "Incorrect hIST chunk length");
1464 png_crc_finish(png_ptr
, length
);
1468 for (i
= 0; i
< num
; i
++)
1472 png_crc_read(png_ptr
, buf
, 2);
1473 readbuf
[i
] = png_get_uint_16(buf
);
1476 if (png_crc_finish(png_ptr
, 0))
1479 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1483 #if defined(PNG_READ_pHYs_SUPPORTED)
1485 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1488 png_uint_32 res_x
, res_y
;
1491 png_debug(1, "in png_handle_pHYs\n");
1493 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1494 png_error(png_ptr
, "Missing IHDR before pHYs");
1495 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1497 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1498 png_crc_finish(png_ptr
, length
);
1501 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1503 png_warning(png_ptr
, "Duplicate pHYs chunk");
1504 png_crc_finish(png_ptr
, length
);
1510 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1511 png_crc_finish(png_ptr
, length
);
1515 png_crc_read(png_ptr
, buf
, 9);
1516 if (png_crc_finish(png_ptr
, 0))
1519 res_x
= png_get_uint_32(buf
);
1520 res_y
= png_get_uint_32(buf
+ 4);
1522 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1526 #if defined(PNG_READ_oFFs_SUPPORTED)
1528 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1531 png_int_32 offset_x
, offset_y
;
1534 png_debug(1, "in png_handle_oFFs\n");
1536 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1537 png_error(png_ptr
, "Missing IHDR before oFFs");
1538 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1540 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1541 png_crc_finish(png_ptr
, length
);
1544 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1546 png_warning(png_ptr
, "Duplicate oFFs chunk");
1547 png_crc_finish(png_ptr
, length
);
1553 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1554 png_crc_finish(png_ptr
, length
);
1558 png_crc_read(png_ptr
, buf
, 9);
1559 if (png_crc_finish(png_ptr
, 0))
1562 offset_x
= png_get_int_32(buf
);
1563 offset_y
= png_get_int_32(buf
+ 4);
1565 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1569 #if defined(PNG_READ_pCAL_SUPPORTED)
1570 /* read the pCAL chunk (described in the PNG Extensions document) */
1572 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1576 png_byte type
, nparams
;
1577 png_charp buf
, units
, endptr
;
1582 png_debug(1, "in png_handle_pCAL\n");
1584 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1585 png_error(png_ptr
, "Missing IHDR before pCAL");
1586 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1588 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1589 png_crc_finish(png_ptr
, length
);
1592 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1594 png_warning(png_ptr
, "Duplicate pCAL chunk");
1595 png_crc_finish(png_ptr
, length
);
1599 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1601 purpose
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1602 if (purpose
== NULL
)
1604 png_warning(png_ptr
, "No memory for pCAL purpose.");
1607 slength
= (png_size_t
)length
;
1608 png_crc_read(png_ptr
, (png_bytep
)purpose
, slength
);
1610 if (png_crc_finish(png_ptr
, 0))
1612 png_free(png_ptr
, purpose
);
1616 purpose
[slength
] = 0x00; /* null terminate the last string */
1618 png_debug(3, "Finding end of pCAL purpose string\n");
1619 for (buf
= purpose
; *buf
; buf
++)
1622 endptr
= purpose
+ slength
;
1624 /* We need to have at least 12 bytes after the purpose string
1625 in order to get the parameter information. */
1626 if (endptr
<= buf
+ 12)
1628 png_warning(png_ptr
, "Invalid pCAL data");
1629 png_free(png_ptr
, purpose
);
1633 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1634 X0
= png_get_int_32((png_bytep
)buf
+1);
1635 X1
= png_get_int_32((png_bytep
)buf
+5);
1640 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1641 /* Check that we have the right number of parameters for known
1643 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1644 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1645 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1646 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1648 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1649 png_free(png_ptr
, purpose
);
1652 else if (type
>= PNG_EQUATION_LAST
)
1654 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1657 for (buf
= units
; *buf
; buf
++)
1658 /* Empty loop to move past the units string. */ ;
1660 png_debug(3, "Allocating pCAL parameters array\n");
1661 params
= (png_charpp
)png_malloc_warn(png_ptr
, (png_uint_32
)(nparams
1662 *png_sizeof(png_charp
))) ;
1665 png_free(png_ptr
, purpose
);
1666 png_warning(png_ptr
, "No memory for pCAL params.");
1670 /* Get pointers to the start of each parameter string. */
1671 for (i
= 0; i
< (int)nparams
; i
++)
1673 buf
++; /* Skip the null string terminator from previous parameter. */
1675 png_debug1(3, "Reading pCAL parameter %d\n", i
);
1676 for (params
[i
] = buf
; *buf
!= 0x00 && buf
<= endptr
; buf
++)
1677 /* Empty loop to move past each parameter string */ ;
1679 /* Make sure we haven't run out of data yet */
1682 png_warning(png_ptr
, "Invalid pCAL data");
1683 png_free(png_ptr
, purpose
);
1684 png_free(png_ptr
, params
);
1689 png_set_pCAL(png_ptr
, info_ptr
, purpose
, X0
, X1
, type
, nparams
,
1692 png_free(png_ptr
, purpose
);
1693 png_free(png_ptr
, params
);
1697 #if defined(PNG_READ_sCAL_SUPPORTED)
1698 /* read the sCAL chunk */
1700 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1702 png_charp buffer
, ep
;
1703 #ifdef PNG_FLOATING_POINT_SUPPORTED
1704 double width
, height
;
1707 #ifdef PNG_FIXED_POINT_SUPPORTED
1708 png_charp swidth
, sheight
;
1713 png_debug(1, "in png_handle_sCAL\n");
1715 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1716 png_error(png_ptr
, "Missing IHDR before sCAL");
1717 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1719 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1720 png_crc_finish(png_ptr
, length
);
1723 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1725 png_warning(png_ptr
, "Duplicate sCAL chunk");
1726 png_crc_finish(png_ptr
, length
);
1730 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1732 buffer
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1735 png_warning(png_ptr
, "Out of memory while processing sCAL chunk");
1738 slength
= (png_size_t
)length
;
1739 png_crc_read(png_ptr
, (png_bytep
)buffer
, slength
);
1741 if (png_crc_finish(png_ptr
, 0))
1743 png_free(png_ptr
, buffer
);
1747 buffer
[slength
] = 0x00; /* null terminate the last string */
1749 ep
= buffer
+ 1; /* skip unit byte */
1751 #ifdef PNG_FLOATING_POINT_SUPPORTED
1752 width
= png_strtod(png_ptr
, ep
, &vp
);
1755 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1759 #ifdef PNG_FIXED_POINT_SUPPORTED
1760 swidth
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1763 png_warning(png_ptr
, "Out of memory while processing sCAL chunk width");
1766 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
));
1770 for (ep
= buffer
; *ep
; ep
++)
1774 #ifdef PNG_FLOATING_POINT_SUPPORTED
1775 height
= png_strtod(png_ptr
, ep
, &vp
);
1778 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1782 #ifdef PNG_FIXED_POINT_SUPPORTED
1783 sheight
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1786 png_warning(png_ptr
, "Out of memory while processing sCAL chunk height");
1789 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
));
1793 if (buffer
+ slength
< ep
1794 #ifdef PNG_FLOATING_POINT_SUPPORTED
1795 || width
<= 0. || height
<= 0.
1799 png_warning(png_ptr
, "Invalid sCAL data");
1800 png_free(png_ptr
, buffer
);
1801 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1802 png_free(png_ptr
, swidth
);
1803 png_free(png_ptr
, sheight
);
1809 #ifdef PNG_FLOATING_POINT_SUPPORTED
1810 png_set_sCAL(png_ptr
, info_ptr
, buffer
[0], width
, height
);
1812 #ifdef PNG_FIXED_POINT_SUPPORTED
1813 png_set_sCAL_s(png_ptr
, info_ptr
, buffer
[0], swidth
, sheight
);
1817 png_free(png_ptr
, buffer
);
1818 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1819 png_free(png_ptr
, swidth
);
1820 png_free(png_ptr
, sheight
);
1825 #if defined(PNG_READ_tIME_SUPPORTED)
1827 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1832 png_debug(1, "in png_handle_tIME\n");
1834 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1835 png_error(png_ptr
, "Out of place tIME chunk");
1836 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1838 png_warning(png_ptr
, "Duplicate tIME chunk");
1839 png_crc_finish(png_ptr
, length
);
1843 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1844 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1848 png_warning(png_ptr
, "Incorrect tIME chunk length");
1849 png_crc_finish(png_ptr
, length
);
1853 png_crc_read(png_ptr
, buf
, 7);
1854 if (png_crc_finish(png_ptr
, 0))
1857 mod_time
.second
= buf
[6];
1858 mod_time
.minute
= buf
[5];
1859 mod_time
.hour
= buf
[4];
1860 mod_time
.day
= buf
[3];
1861 mod_time
.month
= buf
[2];
1862 mod_time
.year
= png_get_uint_16(buf
);
1864 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1868 #if defined(PNG_READ_tEXt_SUPPORTED)
1869 /* Note: this does not properly handle chunks that are > 64K under DOS */
1871 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1876 png_uint_32 skip
= 0;
1880 png_debug(1, "in png_handle_tEXt\n");
1882 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1883 png_error(png_ptr
, "Missing IHDR before tEXt");
1885 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1886 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1888 #ifdef PNG_MAX_MALLOC_64K
1889 if (length
> (png_uint_32
)65535L)
1891 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1892 skip
= length
- (png_uint_32
)65535L;
1893 length
= (png_uint_32
)65535L;
1897 key
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1900 png_warning(png_ptr
, "No memory to process text chunk.");
1903 slength
= (png_size_t
)length
;
1904 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1906 if (png_crc_finish(png_ptr
, skip
))
1908 png_free(png_ptr
, key
);
1912 key
[slength
] = 0x00;
1914 for (text
= key
; *text
; text
++)
1915 /* empty loop to find end of key */ ;
1917 if (text
!= key
+ slength
)
1920 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
1921 (png_uint_32
)png_sizeof(png_text
));
1922 if (text_ptr
== NULL
)
1924 png_warning(png_ptr
, "Not enough memory to process text chunk.");
1925 png_free(png_ptr
, key
);
1928 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1929 text_ptr
->key
= key
;
1930 #ifdef PNG_iTXt_SUPPORTED
1931 text_ptr
->lang
= NULL
;
1932 text_ptr
->lang_key
= NULL
;
1933 text_ptr
->itxt_length
= 0;
1935 text_ptr
->text
= text
;
1936 text_ptr
->text_length
= png_strlen(text
);
1938 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
1940 png_free(png_ptr
, key
);
1941 png_free(png_ptr
, text_ptr
);
1943 png_warning(png_ptr
, "Insufficient memory to process text chunk.");
1947 #if defined(PNG_READ_zTXt_SUPPORTED)
1948 /* note: this does not correctly handle chunks that are > 64K under DOS */
1950 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1953 png_charp chunkdata
;
1957 png_size_t slength
, prefix_len
, data_len
;
1959 png_debug(1, "in png_handle_zTXt\n");
1960 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1961 png_error(png_ptr
, "Missing IHDR before zTXt");
1963 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1964 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1966 #ifdef PNG_MAX_MALLOC_64K
1967 /* We will no doubt have problems with chunks even half this size, but
1968 there is no hard and fast rule to tell us where to stop. */
1969 if (length
> (png_uint_32
)65535L)
1971 png_warning(png_ptr
,"zTXt chunk too large to fit in memory");
1972 png_crc_finish(png_ptr
, length
);
1977 chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1978 if (chunkdata
== NULL
)
1980 png_warning(png_ptr
,"Out of memory processing zTXt chunk.");
1983 slength
= (png_size_t
)length
;
1984 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1985 if (png_crc_finish(png_ptr
, 0))
1987 png_free(png_ptr
, chunkdata
);
1991 chunkdata
[slength
] = 0x00;
1993 for (text
= chunkdata
; *text
; text
++)
1996 /* zTXt must have some text after the chunkdataword */
1997 if (text
== chunkdata
+ slength
- 1)
1999 png_warning(png_ptr
, "Truncated zTXt chunk");
2000 png_free(png_ptr
, chunkdata
);
2005 comp_type
= *(++text
);
2006 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
2008 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
2009 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
2011 text
++; /* skip the compression_method byte */
2013 prefix_len
= text
- chunkdata
;
2015 chunkdata
= (png_charp
)png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
2016 (png_size_t
)length
, prefix_len
, &data_len
);
2018 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2019 (png_uint_32
)png_sizeof(png_text
));
2020 if (text_ptr
== NULL
)
2022 png_warning(png_ptr
,"Not enough memory to process zTXt chunk.");
2023 png_free(png_ptr
, chunkdata
);
2026 text_ptr
->compression
= comp_type
;
2027 text_ptr
->key
= chunkdata
;
2028 #ifdef PNG_iTXt_SUPPORTED
2029 text_ptr
->lang
= NULL
;
2030 text_ptr
->lang_key
= NULL
;
2031 text_ptr
->itxt_length
= 0;
2033 text_ptr
->text
= chunkdata
+ prefix_len
;
2034 text_ptr
->text_length
= data_len
;
2036 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2038 png_free(png_ptr
, text_ptr
);
2039 png_free(png_ptr
, chunkdata
);
2041 png_error(png_ptr
, "Insufficient memory to store zTXt chunk.");
2045 #if defined(PNG_READ_iTXt_SUPPORTED)
2046 /* note: this does not correctly handle chunks that are > 64K under DOS */
2048 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2051 png_charp chunkdata
;
2052 png_charp key
, lang
, text
, lang_key
;
2056 png_size_t slength
, prefix_len
, data_len
;
2058 png_debug(1, "in png_handle_iTXt\n");
2060 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2061 png_error(png_ptr
, "Missing IHDR before iTXt");
2063 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2064 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2066 #ifdef PNG_MAX_MALLOC_64K
2067 /* We will no doubt have problems with chunks even half this size, but
2068 there is no hard and fast rule to tell us where to stop. */
2069 if (length
> (png_uint_32
)65535L)
2071 png_warning(png_ptr
,"iTXt chunk too large to fit in memory");
2072 png_crc_finish(png_ptr
, length
);
2077 chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2078 if (chunkdata
== NULL
)
2080 png_warning(png_ptr
, "No memory to process iTXt chunk.");
2083 slength
= (png_size_t
)length
;
2084 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
2085 if (png_crc_finish(png_ptr
, 0))
2087 png_free(png_ptr
, chunkdata
);
2091 chunkdata
[slength
] = 0x00;
2093 for (lang
= chunkdata
; *lang
; lang
++)
2095 lang
++; /* skip NUL separator */
2097 /* iTXt must have a language tag (possibly empty), two compression bytes,
2098 translated keyword (possibly empty), and possibly some text after the
2101 if (lang
>= chunkdata
+ slength
- 3)
2103 png_warning(png_ptr
, "Truncated iTXt chunk");
2104 png_free(png_ptr
, chunkdata
);
2109 comp_flag
= *lang
++;
2110 comp_type
= *lang
++;
2113 for (lang_key
= lang
; *lang_key
; lang_key
++)
2115 lang_key
++; /* skip NUL separator */
2117 for (text
= lang_key
; *text
; text
++)
2119 text
++; /* skip NUL separator */
2120 if (text
>= chunkdata
+ slength
)
2122 png_warning(png_ptr
, "Malformed iTXt chunk");
2123 png_free(png_ptr
, chunkdata
);
2127 prefix_len
= text
- chunkdata
;
2131 chunkdata
= png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
2132 (size_t)length
, prefix_len
, &data_len
);
2134 data_len
=png_strlen(chunkdata
+ prefix_len
);
2135 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2136 (png_uint_32
)png_sizeof(png_text
));
2137 if (text_ptr
== NULL
)
2139 png_warning(png_ptr
,"Not enough memory to process iTXt chunk.");
2140 png_free(png_ptr
, chunkdata
);
2143 text_ptr
->compression
= (int)comp_flag
+ 1;
2144 text_ptr
->lang_key
= chunkdata
+(lang_key
-key
);
2145 text_ptr
->lang
= chunkdata
+(lang
-key
);
2146 text_ptr
->itxt_length
= data_len
;
2147 text_ptr
->text_length
= 0;
2148 text_ptr
->key
= chunkdata
;
2149 text_ptr
->text
= chunkdata
+ prefix_len
;
2151 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2153 png_free(png_ptr
, text_ptr
);
2154 png_free(png_ptr
, chunkdata
);
2156 png_error(png_ptr
, "Insufficient memory to store iTXt chunk.");
2160 /* This function is called when we haven't found a handler for a
2161 chunk. If there isn't a problem with the chunk itself (ie bad
2162 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2163 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2164 case it will be saved away to be written out later. */
2166 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2168 png_uint_32 skip
= 0;
2170 png_debug(1, "in png_handle_unknown\n");
2172 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2174 #ifdef PNG_USE_LOCAL_ARRAYS
2177 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* not an IDAT */
2178 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2181 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
2183 if (!(png_ptr
->chunk_name
[0] & 0x20))
2185 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2186 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2187 PNG_HANDLE_CHUNK_ALWAYS
2188 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2189 && png_ptr
->read_user_chunk_fn
== NULL
2193 png_chunk_error(png_ptr
, "unknown critical chunk");
2196 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2197 if ((png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
) ||
2198 (png_ptr
->read_user_chunk_fn
!= NULL
))
2200 #ifdef PNG_MAX_MALLOC_64K
2201 if (length
> (png_uint_32
)65535L)
2203 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2204 skip
= length
- (png_uint_32
)65535L;
2205 length
= (png_uint_32
)65535L;
2208 png_strncpy((png_charp
)png_ptr
->unknown_chunk
.name
,
2209 (png_charp
)png_ptr
->chunk_name
,
2210 png_sizeof((png_charp
)png_ptr
->chunk_name
));
2211 png_ptr
->unknown_chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2212 png_ptr
->unknown_chunk
.size
= (png_size_t
)length
;
2213 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->unknown_chunk
.data
, length
);
2214 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2215 if(png_ptr
->read_user_chunk_fn
!= NULL
)
2217 /* callback to user unknown chunk handler */
2219 ret
= (*(png_ptr
->read_user_chunk_fn
))
2220 (png_ptr
, &png_ptr
->unknown_chunk
);
2222 png_chunk_error(png_ptr
, "error in user chunk");
2225 if (!(png_ptr
->chunk_name
[0] & 0x20))
2226 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2227 PNG_HANDLE_CHUNK_ALWAYS
)
2228 png_chunk_error(png_ptr
, "unknown critical chunk");
2229 png_set_unknown_chunks(png_ptr
, info_ptr
,
2230 &png_ptr
->unknown_chunk
, 1);
2234 png_set_unknown_chunks(png_ptr
, info_ptr
, &png_ptr
->unknown_chunk
, 1);
2236 png_free(png_ptr
, png_ptr
->unknown_chunk
.data
);
2237 png_ptr
->unknown_chunk
.data
= NULL
;
2243 png_crc_finish(png_ptr
, skip
);
2245 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2246 info_ptr
= info_ptr
; /* quiet compiler warnings about unused info_ptr */
2250 /* This function is called to verify that a chunk name is valid.
2251 This function can't have the "critical chunk check" incorporated
2252 into it, since in the future we will need to be able to call user
2253 functions to handle unknown critical chunks after we check that
2254 the chunk name itself is valid. */
2256 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2259 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2261 png_debug(1, "in png_check_chunk_name\n");
2262 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2263 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2265 png_chunk_error(png_ptr
, "invalid chunk type");
2269 /* Combines the row recently read in with the existing pixels in the
2270 row. This routine takes care of alpha and transparency if requested.
2271 This routine also handles the two methods of progressive display
2272 of interlaced images, depending on the mask value.
2273 The mask value describes which pixels are to be combined with
2274 the row. The pattern always repeats every 8 pixels, so just 8
2275 bits are needed. A one indicates the pixel is to be combined,
2276 a zero indicates the pixel is to be skipped. This is in addition
2277 to any alpha or transparency value associated with the pixel. If
2278 you want all pixels to be combined, pass 0xff (255) in mask. */
2281 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2283 png_debug(1,"in png_combine_row\n");
2286 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2287 PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
, png_ptr
->width
));
2291 switch (png_ptr
->row_info
.pixel_depth
)
2295 png_bytep sp
= png_ptr
->row_buf
+ 1;
2297 int s_inc
, s_start
, s_end
;
2301 png_uint_32 row_width
= png_ptr
->width
;
2303 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2304 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2320 for (i
= 0; i
< row_width
; i
++)
2326 value
= (*sp
>> shift
) & 0x01;
2327 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2328 *dp
|= (png_byte
)(value
<< shift
);
2349 png_bytep sp
= png_ptr
->row_buf
+ 1;
2351 int s_start
, s_end
, s_inc
;
2355 png_uint_32 row_width
= png_ptr
->width
;
2358 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2359 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2375 for (i
= 0; i
< row_width
; i
++)
2379 value
= (*sp
>> shift
) & 0x03;
2380 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2381 *dp
|= (png_byte
)(value
<< shift
);
2401 png_bytep sp
= png_ptr
->row_buf
+ 1;
2403 int s_start
, s_end
, s_inc
;
2407 png_uint_32 row_width
= png_ptr
->width
;
2410 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2411 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2426 for (i
= 0; i
< row_width
; i
++)
2430 value
= (*sp
>> shift
) & 0xf;
2431 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2432 *dp
|= (png_byte
)(value
<< shift
);
2452 png_bytep sp
= png_ptr
->row_buf
+ 1;
2454 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2456 png_uint_32 row_width
= png_ptr
->width
;
2460 for (i
= 0; i
< row_width
; i
++)
2464 png_memcpy(dp
, sp
, pixel_bytes
);
2481 #ifdef PNG_READ_INTERLACING_SUPPORTED
2482 /* OLD pre-1.0.9 interface:
2483 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2484 png_uint_32 transformations)
2487 png_do_read_interlace(png_structp png_ptr
)
2489 png_row_infop row_info
= &(png_ptr
->row_info
);
2490 png_bytep row
= png_ptr
->row_buf
+ 1;
2491 int pass
= png_ptr
->pass
;
2492 png_uint_32 transformations
= png_ptr
->transformations
;
2493 #ifdef PNG_USE_LOCAL_ARRAYS
2494 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2495 /* offset to next interlace block */
2496 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2499 png_debug(1,"in png_do_read_interlace\n");
2500 if (row
!= NULL
&& row_info
!= NULL
)
2502 png_uint_32 final_width
;
2504 final_width
= row_info
->width
* png_pass_inc
[pass
];
2506 switch (row_info
->pixel_depth
)
2510 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2511 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2513 int s_start
, s_end
, s_inc
;
2514 int jstop
= png_pass_inc
[pass
];
2519 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2520 if (transformations
& PNG_PACKSWAP
)
2522 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2523 dshift
= (int)((final_width
+ 7) & 0x07);
2531 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2532 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2538 for (i
= 0; i
< row_info
->width
; i
++)
2540 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2541 for (j
= 0; j
< jstop
; j
++)
2543 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2544 *dp
|= (png_byte
)(v
<< dshift
);
2545 if (dshift
== s_end
)
2553 if (sshift
== s_end
)
2565 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2566 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2568 int s_start
, s_end
, s_inc
;
2569 int jstop
= png_pass_inc
[pass
];
2572 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2573 if (transformations
& PNG_PACKSWAP
)
2575 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2576 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2584 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2585 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2591 for (i
= 0; i
< row_info
->width
; i
++)
2596 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2597 for (j
= 0; j
< jstop
; j
++)
2599 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2600 *dp
|= (png_byte
)(v
<< dshift
);
2601 if (dshift
== s_end
)
2609 if (sshift
== s_end
)
2621 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2622 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2624 int s_start
, s_end
, s_inc
;
2626 int jstop
= png_pass_inc
[pass
];
2628 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2629 if (transformations
& PNG_PACKSWAP
)
2631 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2632 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2640 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2641 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2647 for (i
= 0; i
< row_info
->width
; i
++)
2649 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2652 for (j
= 0; j
< jstop
; j
++)
2654 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2655 *dp
|= (png_byte
)(v
<< dshift
);
2656 if (dshift
== s_end
)
2664 if (sshift
== s_end
)
2676 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2677 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
2678 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2680 int jstop
= png_pass_inc
[pass
];
2683 for (i
= 0; i
< row_info
->width
; i
++)
2688 png_memcpy(v
, sp
, pixel_bytes
);
2689 for (j
= 0; j
< jstop
; j
++)
2691 png_memcpy(dp
, v
, pixel_bytes
);
2699 row_info
->width
= final_width
;
2700 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,final_width
);
2702 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2703 transformations
= transformations
; /* silence compiler warning */
2706 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2709 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2710 png_bytep prev_row
, int filter
)
2712 png_debug(1, "in png_read_filter_row\n");
2713 png_debug2(2,"row = %lu, filter = %d\n", png_ptr
->row_number
, filter
);
2716 case PNG_FILTER_VALUE_NONE
:
2718 case PNG_FILTER_VALUE_SUB
:
2721 png_uint_32 istop
= row_info
->rowbytes
;
2722 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2723 png_bytep rp
= row
+ bpp
;
2726 for (i
= bpp
; i
< istop
; i
++)
2728 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2733 case PNG_FILTER_VALUE_UP
:
2736 png_uint_32 istop
= row_info
->rowbytes
;
2738 png_bytep pp
= prev_row
;
2740 for (i
= 0; i
< istop
; i
++)
2742 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2747 case PNG_FILTER_VALUE_AVG
:
2751 png_bytep pp
= prev_row
;
2753 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2754 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2756 for (i
= 0; i
< bpp
; i
++)
2758 *rp
= (png_byte
)(((int)(*rp
) +
2759 ((int)(*pp
++) / 2 )) & 0xff);
2763 for (i
= 0; i
< istop
; i
++)
2765 *rp
= (png_byte
)(((int)(*rp
) +
2766 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2771 case PNG_FILTER_VALUE_PAETH
:
2775 png_bytep pp
= prev_row
;
2777 png_bytep cp
= prev_row
;
2778 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2779 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
2781 for (i
= 0; i
< bpp
; i
++)
2783 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2787 for (i
= 0; i
< istop
; i
++) /* use leftover rp,pp */
2789 int a
, b
, c
, pa
, pb
, pc
, p
;
2803 pa
= p
< 0 ? -p
: p
;
2804 pb
= pc
< 0 ? -pc
: pc
;
2805 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
2809 if (pa <= pb && pa <= pc)
2817 p
= (pa
<= pb
&& pa
<=pc
) ? a
: (pb
<= pc
) ? b
: c
;
2819 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2825 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2832 png_read_finish_row(png_structp png_ptr
)
2834 #ifdef PNG_USE_LOCAL_ARRAYS
2835 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2837 /* start of interlace block */
2838 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2840 /* offset to next interlace block */
2841 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2843 /* start of interlace block in the y direction */
2844 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2846 /* offset to next interlace block in the y direction */
2847 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2850 png_debug(1, "in png_read_finish_row\n");
2851 png_ptr
->row_number
++;
2852 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2855 if (png_ptr
->interlaced
)
2857 png_ptr
->row_number
= 0;
2858 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0,
2859 png_ptr
->rowbytes
+ 1);
2863 if (png_ptr
->pass
>= 7)
2865 png_ptr
->iwidth
= (png_ptr
->width
+
2866 png_pass_inc
[png_ptr
->pass
] - 1 -
2867 png_pass_start
[png_ptr
->pass
]) /
2868 png_pass_inc
[png_ptr
->pass
];
2870 png_ptr
->irowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,
2871 png_ptr
->iwidth
) + 1;
2873 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2875 png_ptr
->num_rows
= (png_ptr
->height
+
2876 png_pass_yinc
[png_ptr
->pass
] - 1 -
2877 png_pass_ystart
[png_ptr
->pass
]) /
2878 png_pass_yinc
[png_ptr
->pass
];
2879 if (!(png_ptr
->num_rows
))
2882 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2884 } while (png_ptr
->iwidth
== 0);
2886 if (png_ptr
->pass
< 7)
2890 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2892 #ifdef PNG_USE_LOCAL_ARRAYS
2898 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2899 png_ptr
->zstream
.avail_out
= (uInt
)1;
2902 if (!(png_ptr
->zstream
.avail_in
))
2904 while (!png_ptr
->idat_size
)
2906 png_byte chunk_length
[4];
2908 png_crc_finish(png_ptr
, 0);
2910 png_read_data(png_ptr
, chunk_length
, 4);
2911 png_ptr
->idat_size
= png_get_uint_31(png_ptr
, chunk_length
);
2912 png_reset_crc(png_ptr
);
2913 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2914 if (png_memcmp(png_ptr
->chunk_name
, (png_bytep
)png_IDAT
, 4))
2915 png_error(png_ptr
, "Not enough image data");
2918 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2919 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2920 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2921 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2922 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2923 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2925 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2926 if (ret
== Z_STREAM_END
)
2928 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2930 png_warning(png_ptr
, "Extra compressed data");
2931 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2932 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2936 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2937 "Decompression Error");
2939 if (!(png_ptr
->zstream
.avail_out
))
2941 png_warning(png_ptr
, "Extra compressed data.");
2942 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2943 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2948 png_ptr
->zstream
.avail_out
= 0;
2951 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
2952 png_warning(png_ptr
, "Extra compression data");
2954 inflateReset(&png_ptr
->zstream
);
2956 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2960 png_read_start_row(png_structp png_ptr
)
2962 #ifdef PNG_USE_LOCAL_ARRAYS
2963 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2965 /* start of interlace block */
2966 PNG_CONST
int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2968 /* offset to next interlace block */
2969 PNG_CONST
int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2971 /* start of interlace block in the y direction */
2972 PNG_CONST
int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2974 /* offset to next interlace block in the y direction */
2975 PNG_CONST
int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2978 int max_pixel_depth
;
2979 png_uint_32 row_bytes
;
2981 png_debug(1, "in png_read_start_row\n");
2982 png_ptr
->zstream
.avail_in
= 0;
2983 png_init_read_transformations(png_ptr
);
2984 if (png_ptr
->interlaced
)
2986 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2987 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
2988 png_pass_ystart
[0]) / png_pass_yinc
[0];
2990 png_ptr
->num_rows
= png_ptr
->height
;
2992 png_ptr
->iwidth
= (png_ptr
->width
+
2993 png_pass_inc
[png_ptr
->pass
] - 1 -
2994 png_pass_start
[png_ptr
->pass
]) /
2995 png_pass_inc
[png_ptr
->pass
];
2997 row_bytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,png_ptr
->iwidth
) + 1;
2999 png_ptr
->irowbytes
= (png_size_t
)row_bytes
;
3000 if((png_uint_32
)png_ptr
->irowbytes
!= row_bytes
)
3001 png_error(png_ptr
, "Rowbytes overflow in png_read_start_row");
3005 png_ptr
->num_rows
= png_ptr
->height
;
3006 png_ptr
->iwidth
= png_ptr
->width
;
3007 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
3009 max_pixel_depth
= png_ptr
->pixel_depth
;
3011 #if defined(PNG_READ_PACK_SUPPORTED)
3012 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
3013 max_pixel_depth
= 8;
3016 #if defined(PNG_READ_EXPAND_SUPPORTED)
3017 if (png_ptr
->transformations
& PNG_EXPAND
)
3019 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3021 if (png_ptr
->num_trans
)
3022 max_pixel_depth
= 32;
3024 max_pixel_depth
= 24;
3026 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3028 if (max_pixel_depth
< 8)
3029 max_pixel_depth
= 8;
3030 if (png_ptr
->num_trans
)
3031 max_pixel_depth
*= 2;
3033 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3035 if (png_ptr
->num_trans
)
3037 max_pixel_depth
*= 4;
3038 max_pixel_depth
/= 3;
3044 #if defined(PNG_READ_FILLER_SUPPORTED)
3045 if (png_ptr
->transformations
& (PNG_FILLER
))
3047 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3048 max_pixel_depth
= 32;
3049 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3051 if (max_pixel_depth
<= 8)
3052 max_pixel_depth
= 16;
3054 max_pixel_depth
= 32;
3056 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3058 if (max_pixel_depth
<= 32)
3059 max_pixel_depth
= 32;
3061 max_pixel_depth
= 64;
3066 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3067 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
3070 #if defined(PNG_READ_EXPAND_SUPPORTED)
3071 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
3073 #if defined(PNG_READ_FILLER_SUPPORTED)
3074 (png_ptr
->transformations
& (PNG_FILLER
)) ||
3076 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
3078 if (max_pixel_depth
<= 16)
3079 max_pixel_depth
= 32;
3081 max_pixel_depth
= 64;
3085 if (max_pixel_depth
<= 8)
3087 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3088 max_pixel_depth
= 32;
3090 max_pixel_depth
= 24;
3092 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3093 max_pixel_depth
= 64;
3095 max_pixel_depth
= 48;
3100 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3101 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3102 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
3104 int user_pixel_depth
=png_ptr
->user_transform_depth
*
3105 png_ptr
->user_transform_channels
;
3106 if(user_pixel_depth
> max_pixel_depth
)
3107 max_pixel_depth
=user_pixel_depth
;
3111 /* align the width on the next larger 8 pixels. Mainly used
3113 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
3114 /* calculate the maximum bytes needed, adding a byte and a pixel
3115 for safety's sake */
3116 row_bytes
= PNG_ROWBYTES(max_pixel_depth
,row_bytes
) +
3117 1 + ((max_pixel_depth
+ 7) >> 3);
3118 #ifdef PNG_MAX_MALLOC_64K
3119 if (row_bytes
> (png_uint_32
)65536L)
3120 png_error(png_ptr
, "This image requires a row greater than 64KB");
3122 png_ptr
->big_row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
+64);
3123 png_ptr
->row_buf
= png_ptr
->big_row_buf
+32;
3125 #ifdef PNG_MAX_MALLOC_64K
3126 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
3127 png_error(png_ptr
, "This image requires a row greater than 64KB");
3129 if ((png_uint_32
)png_ptr
->rowbytes
> (png_uint_32
)(PNG_SIZE_MAX
- 1))
3130 png_error(png_ptr
, "Row has too many bytes to allocate in memory.");
3131 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
3132 png_ptr
->rowbytes
+ 1));
3134 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
3136 png_debug1(3, "width = %lu,\n", png_ptr
->width
);
3137 png_debug1(3, "height = %lu,\n", png_ptr
->height
);
3138 png_debug1(3, "iwidth = %lu,\n", png_ptr
->iwidth
);
3139 png_debug1(3, "num_rows = %lu\n", png_ptr
->num_rows
);
3140 png_debug1(3, "rowbytes = %lu,\n", png_ptr
->rowbytes
);
3141 png_debug1(3, "irowbytes = %lu,\n", png_ptr
->irowbytes
);
3143 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;
3145 #endif /* PNG_READ_SUPPORTED */