2 /* pngrutil.c - utilities to read a PNG file
4 * Last changed in libpng 1.2.17 May 15, 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 #ifdef PNG_FLOATING_POINT_SUPPORTED
20 # if defined(_WIN32_WCE)
21 /* strtod() function is not supported on WindowsCE */
22 __inline
double png_strtod(png_structp png_ptr
, const char *nptr
, char **endptr
)
28 len
= MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, NULL
, 0);
29 str
= (wchar_t *)png_malloc(png_ptr
, len
* sizeof(wchar_t));
32 MultiByteToWideChar(CP_ACP
, 0, nptr
, -1, str
, len
);
33 result
= wcstod(str
, &end
);
34 len
= WideCharToMultiByte(CP_ACP
, 0, end
, -1, NULL
, 0, NULL
, NULL
);
35 *endptr
= (char *)nptr
+ (png_strlen(nptr
) - len
+ 1);
41 # define png_strtod(p,a,b) strtod(a,b)
46 png_get_uint_31(png_structp png_ptr
, png_bytep buf
)
48 png_uint_32 i
= png_get_uint_32(buf
);
49 if (i
> PNG_UINT_31_MAX
)
50 png_error(png_ptr
, "PNG unsigned integer out of range.");
53 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
54 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
56 png_get_uint_32(png_bytep buf
)
58 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
59 ((png_uint_32
)(*(buf
+ 1)) << 16) +
60 ((png_uint_32
)(*(buf
+ 2)) << 8) +
61 (png_uint_32
)(*(buf
+ 3));
66 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
67 * data is stored in the PNG file in two's complement format, and it is
68 * assumed that the machine format for signed integers is the same. */
70 png_get_int_32(png_bytep buf
)
72 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
73 ((png_int_32
)(*(buf
+ 1)) << 16) +
74 ((png_int_32
)(*(buf
+ 2)) << 8) +
75 (png_int_32
)(*(buf
+ 3));
80 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
82 png_get_uint_16(png_bytep buf
)
84 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
85 (png_uint_16
)(*(buf
+ 1)));
89 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
91 /* Read data, and (optionally) run it through the CRC. */
93 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
95 if(png_ptr
== NULL
) return;
96 png_read_data(png_ptr
, buf
, length
);
97 png_calculate_crc(png_ptr
, buf
, length
);
100 /* Optionally skip data and then check the CRC. Depending on whether we
101 are reading a ancillary or critical chunk, and how the program has set
102 things up, we may calculate the CRC on the data and print a message.
103 Returns '1' if there was a CRC error, '0' otherwise. */
105 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
108 png_size_t istop
= png_ptr
->zbuf_size
;
110 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
112 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
116 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
119 if (png_crc_error(png_ptr
))
121 if (((png_ptr
->chunk_name
[0] & 0x20) && /* Ancillary */
122 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
123 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
124 (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
)))
126 png_chunk_warning(png_ptr
, "CRC error");
130 png_chunk_error(png_ptr
, "CRC error");
138 /* Compare the CRC stored in the PNG file with that calculated by libpng from
139 the data it has read thus far. */
141 png_crc_error(png_structp png_ptr
)
143 png_byte crc_bytes
[4];
147 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
149 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
150 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
155 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
159 png_read_data(png_ptr
, crc_bytes
, 4);
163 crc
= png_get_uint_32(crc_bytes
);
164 return ((int)(crc
!= png_ptr
->crc
));
170 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
171 defined(PNG_READ_iCCP_SUPPORTED)
173 * Decompress trailing data in a chunk. The assumption is that chunkdata
174 * points at an allocated area holding the contents of a chunk with a
175 * trailing compressed part. What we get back is an allocated area
176 * holding the original prefix part and an uncompressed version of the
177 * trailing part (the malloc area passed in is freed).
179 png_charp
/* PRIVATE */
180 png_decompress_chunk(png_structp png_ptr
, int comp_type
,
181 png_charp chunkdata
, png_size_t chunklength
,
182 png_size_t prefix_size
, png_size_t
*newlength
)
184 const static char msg
[] = "Error decoding compressed text";
186 png_size_t text_size
;
188 if (comp_type
== PNG_COMPRESSION_TYPE_BASE
)
191 png_ptr
->zstream
.next_in
= (png_bytep
)(chunkdata
+ prefix_size
);
192 png_ptr
->zstream
.avail_in
= (uInt
)(chunklength
- prefix_size
);
193 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
194 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
199 while (png_ptr
->zstream
.avail_in
)
201 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
202 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
204 if (png_ptr
->zstream
.msg
!= NULL
)
205 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
207 png_warning(png_ptr
, msg
);
208 inflateReset(&png_ptr
->zstream
);
209 png_ptr
->zstream
.avail_in
= 0;
213 text_size
= prefix_size
+ png_sizeof(msg
) + 1;
214 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
);
217 png_free(png_ptr
,chunkdata
);
218 png_error(png_ptr
,"Not enough memory to decompress chunk");
220 png_memcpy(text
, chunkdata
, prefix_size
);
223 text
[text_size
- 1] = 0x00;
225 /* Copy what we can of the error message into the text chunk */
226 text_size
= (png_size_t
)(chunklength
- (text
- chunkdata
) - 1);
227 text_size
= png_sizeof(msg
) > text_size
? text_size
:
229 png_memcpy(text
+ prefix_size
, msg
, text_size
+ 1);
232 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
236 text_size
= prefix_size
+
237 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
238 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+ 1);
241 png_free(png_ptr
,chunkdata
);
242 png_error(png_ptr
,"Not enough memory to decompress chunk.");
244 png_memcpy(text
+ prefix_size
, png_ptr
->zbuf
,
245 text_size
- prefix_size
);
246 png_memcpy(text
, chunkdata
, prefix_size
);
247 *(text
+ text_size
) = 0x00;
254 text
= (png_charp
)png_malloc_warn(png_ptr
,
255 (png_uint_32
)(text_size
+
256 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
259 png_free(png_ptr
, tmp
);
260 png_free(png_ptr
, chunkdata
);
261 png_error(png_ptr
,"Not enough memory to decompress chunk..");
263 png_memcpy(text
, tmp
, text_size
);
264 png_free(png_ptr
, tmp
);
265 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
266 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
267 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
268 *(text
+ text_size
) = 0x00;
270 if (ret
== Z_STREAM_END
)
274 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
275 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
279 if (ret
!= Z_STREAM_END
)
281 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
284 if (ret
== Z_BUF_ERROR
)
285 sprintf(umsg
,"Buffer error in compressed datastream in %s chunk",
286 png_ptr
->chunk_name
);
287 else if (ret
== Z_DATA_ERROR
)
288 sprintf(umsg
,"Data error in compressed datastream in %s chunk",
289 png_ptr
->chunk_name
);
291 sprintf(umsg
,"Incomplete compressed datastream in %s chunk",
292 png_ptr
->chunk_name
);
293 png_warning(png_ptr
, umsg
);
296 "Incomplete compressed datastream in chunk other than IDAT");
298 text_size
=prefix_size
;
301 text
= (png_charp
)png_malloc_warn(png_ptr
, text_size
+1);
304 png_free(png_ptr
, chunkdata
);
305 png_error(png_ptr
,"Not enough memory for text.");
307 png_memcpy(text
, chunkdata
, prefix_size
);
309 *(text
+ text_size
) = 0x00;
312 inflateReset(&png_ptr
->zstream
);
313 png_ptr
->zstream
.avail_in
= 0;
315 png_free(png_ptr
, chunkdata
);
317 *newlength
=text_size
;
319 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
321 #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
324 sprintf(umsg
, "Unknown zTXt compression type %d", comp_type
);
325 png_warning(png_ptr
, umsg
);
327 png_warning(png_ptr
, "Unknown zTXt compression type");
330 *(chunkdata
+ prefix_size
) = 0x00;
331 *newlength
=prefix_size
;
338 /* read and check the IDHR chunk */
340 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
343 png_uint_32 width
, height
;
344 int bit_depth
, color_type
, compression_type
, filter_type
;
347 png_debug(1, "in png_handle_IHDR\n");
349 if (png_ptr
->mode
& PNG_HAVE_IHDR
)
350 png_error(png_ptr
, "Out of place IHDR");
352 /* check the length */
354 png_error(png_ptr
, "Invalid IHDR chunk");
356 png_ptr
->mode
|= PNG_HAVE_IHDR
;
358 png_crc_read(png_ptr
, buf
, 13);
359 png_crc_finish(png_ptr
, 0);
361 width
= png_get_uint_31(png_ptr
, buf
);
362 height
= png_get_uint_31(png_ptr
, buf
+ 4);
365 compression_type
= buf
[10];
366 filter_type
= buf
[11];
367 interlace_type
= buf
[12];
369 /* set internal variables */
370 png_ptr
->width
= width
;
371 png_ptr
->height
= height
;
372 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
373 png_ptr
->interlaced
= (png_byte
)interlace_type
;
374 png_ptr
->color_type
= (png_byte
)color_type
;
375 #if defined(PNG_MNG_FEATURES_SUPPORTED)
376 png_ptr
->filter_type
= (png_byte
)filter_type
;
378 png_ptr
->compression_type
= (png_byte
)compression_type
;
380 /* find number of channels */
381 switch (png_ptr
->color_type
)
383 case PNG_COLOR_TYPE_GRAY
:
384 case PNG_COLOR_TYPE_PALETTE
:
385 png_ptr
->channels
= 1;
387 case PNG_COLOR_TYPE_RGB
:
388 png_ptr
->channels
= 3;
390 case PNG_COLOR_TYPE_GRAY_ALPHA
:
391 png_ptr
->channels
= 2;
393 case PNG_COLOR_TYPE_RGB_ALPHA
:
394 png_ptr
->channels
= 4;
398 /* set up other useful info */
399 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
401 png_ptr
->rowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,png_ptr
->width
);
402 png_debug1(3,"bit_depth = %d\n", png_ptr
->bit_depth
);
403 png_debug1(3,"channels = %d\n", png_ptr
->channels
);
404 png_debug1(3,"rowbytes = %lu\n", png_ptr
->rowbytes
);
405 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
406 color_type
, interlace_type
, compression_type
, filter_type
);
409 /* read and check the palette */
411 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
413 png_color palette
[PNG_MAX_PALETTE_LENGTH
];
415 #ifndef PNG_NO_POINTER_INDEXING
419 png_debug(1, "in png_handle_PLTE\n");
421 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
422 png_error(png_ptr
, "Missing IHDR before PLTE");
423 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
425 png_warning(png_ptr
, "Invalid PLTE after IDAT");
426 png_crc_finish(png_ptr
, length
);
429 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
430 png_error(png_ptr
, "Duplicate PLTE chunk");
432 png_ptr
->mode
|= PNG_HAVE_PLTE
;
434 if (!(png_ptr
->color_type
&PNG_COLOR_MASK_COLOR
))
437 "Ignoring PLTE chunk in grayscale PNG");
438 png_crc_finish(png_ptr
, length
);
441 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
442 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
444 png_crc_finish(png_ptr
, length
);
449 if (length
> 3*PNG_MAX_PALETTE_LENGTH
|| length
% 3)
451 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
453 png_warning(png_ptr
, "Invalid palette chunk");
454 png_crc_finish(png_ptr
, length
);
459 png_error(png_ptr
, "Invalid palette chunk");
463 num
= (int)length
/ 3;
465 #ifndef PNG_NO_POINTER_INDEXING
466 for (i
= 0, pal_ptr
= palette
; i
< num
; i
++, pal_ptr
++)
470 png_crc_read(png_ptr
, buf
, 3);
471 pal_ptr
->red
= buf
[0];
472 pal_ptr
->green
= buf
[1];
473 pal_ptr
->blue
= buf
[2];
476 for (i
= 0; i
< num
; i
++)
480 png_crc_read(png_ptr
, buf
, 3);
481 /* don't depend upon png_color being any order */
482 palette
[i
].red
= buf
[0];
483 palette
[i
].green
= buf
[1];
484 palette
[i
].blue
= buf
[2];
488 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
489 whatever the normal CRC configuration tells us. However, if we
490 have an RGB image, the PLTE can be considered ancillary, so
491 we will act as though it is. */
492 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
493 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
496 png_crc_finish(png_ptr
, 0);
498 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
499 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
501 /* If we don't want to use the data from an ancillary chunk,
502 we have two options: an error abort, or a warning and we
503 ignore the data in this chunk (which should be OK, since
504 it's considered ancillary for a RGB or RGBA image). */
505 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
507 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
509 png_chunk_error(png_ptr
, "CRC error");
513 png_chunk_warning(png_ptr
, "CRC error");
517 /* Otherwise, we (optionally) emit a warning and use the chunk. */
518 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
520 png_chunk_warning(png_ptr
, "CRC error");
525 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
527 #if defined(PNG_READ_tRNS_SUPPORTED)
528 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
530 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
532 if (png_ptr
->num_trans
> (png_uint_16
)num
)
534 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
535 png_ptr
->num_trans
= (png_uint_16
)num
;
537 if (info_ptr
->num_trans
> (png_uint_16
)num
)
539 png_warning(png_ptr
, "Truncating incorrect info tRNS chunk length");
540 info_ptr
->num_trans
= (png_uint_16
)num
;
549 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
551 png_debug(1, "in png_handle_IEND\n");
553 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
555 png_error(png_ptr
, "No image in file");
558 png_ptr
->mode
|= (PNG_AFTER_IDAT
| PNG_HAVE_IEND
);
562 png_warning(png_ptr
, "Incorrect IEND chunk length");
564 png_crc_finish(png_ptr
, length
);
566 if (&info_ptr
== NULL
) /* quiet compiler warnings about unused info_ptr */
570 #if defined(PNG_READ_gAMA_SUPPORTED)
572 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
574 png_fixed_point igamma
;
575 #ifdef PNG_FLOATING_POINT_SUPPORTED
580 png_debug(1, "in png_handle_gAMA\n");
582 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
583 png_error(png_ptr
, "Missing IHDR before gAMA");
584 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
586 png_warning(png_ptr
, "Invalid gAMA after IDAT");
587 png_crc_finish(png_ptr
, length
);
590 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
591 /* Should be an error, but we can cope with it */
592 png_warning(png_ptr
, "Out of place gAMA chunk");
594 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
)
595 #if defined(PNG_READ_sRGB_SUPPORTED)
596 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
600 png_warning(png_ptr
, "Duplicate gAMA chunk");
601 png_crc_finish(png_ptr
, length
);
607 png_warning(png_ptr
, "Incorrect gAMA chunk length");
608 png_crc_finish(png_ptr
, length
);
612 png_crc_read(png_ptr
, buf
, 4);
613 if (png_crc_finish(png_ptr
, 0))
616 igamma
= (png_fixed_point
)png_get_uint_32(buf
);
617 /* check for zero gamma */
621 "Ignoring gAMA chunk with gamma=0");
625 #if defined(PNG_READ_sRGB_SUPPORTED)
626 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
627 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
630 "Ignoring incorrect gAMA value when sRGB is also present");
631 #ifndef PNG_NO_CONSOLE_IO
632 fprintf(stderr
, "gamma = (%d/100000)\n", (int)igamma
);
636 #endif /* PNG_READ_sRGB_SUPPORTED */
638 #ifdef PNG_FLOATING_POINT_SUPPORTED
639 file_gamma
= (float)igamma
/ (float)100000.0;
640 # ifdef PNG_READ_GAMMA_SUPPORTED
641 png_ptr
->gamma
= file_gamma
;
643 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
645 #ifdef PNG_FIXED_POINT_SUPPORTED
646 png_set_gAMA_fixed(png_ptr
, info_ptr
, igamma
);
651 #if defined(PNG_READ_sBIT_SUPPORTED)
653 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
658 png_debug(1, "in png_handle_sBIT\n");
660 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
662 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
663 png_error(png_ptr
, "Missing IHDR before sBIT");
664 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
666 png_warning(png_ptr
, "Invalid sBIT after IDAT");
667 png_crc_finish(png_ptr
, length
);
670 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
672 /* Should be an error, but we can cope with it */
673 png_warning(png_ptr
, "Out of place sBIT chunk");
675 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sBIT
))
677 png_warning(png_ptr
, "Duplicate sBIT chunk");
678 png_crc_finish(png_ptr
, length
);
682 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
685 truelen
= (png_size_t
)png_ptr
->channels
;
687 if (length
!= truelen
|| length
> 4)
689 png_warning(png_ptr
, "Incorrect sBIT chunk length");
690 png_crc_finish(png_ptr
, length
);
694 png_crc_read(png_ptr
, buf
, truelen
);
695 if (png_crc_finish(png_ptr
, 0))
698 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
700 png_ptr
->sig_bit
.red
= buf
[0];
701 png_ptr
->sig_bit
.green
= buf
[1];
702 png_ptr
->sig_bit
.blue
= buf
[2];
703 png_ptr
->sig_bit
.alpha
= buf
[3];
707 png_ptr
->sig_bit
.gray
= buf
[0];
708 png_ptr
->sig_bit
.red
= buf
[0];
709 png_ptr
->sig_bit
.green
= buf
[0];
710 png_ptr
->sig_bit
.blue
= buf
[0];
711 png_ptr
->sig_bit
.alpha
= buf
[1];
713 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
717 #if defined(PNG_READ_cHRM_SUPPORTED)
719 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
722 #ifdef PNG_FLOATING_POINT_SUPPORTED
723 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
725 png_fixed_point int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
726 int_y_green
, int_x_blue
, int_y_blue
;
728 png_uint_32 uint_x
, uint_y
;
730 png_debug(1, "in png_handle_cHRM\n");
732 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
733 png_error(png_ptr
, "Missing IHDR before cHRM");
734 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
736 png_warning(png_ptr
, "Invalid cHRM after IDAT");
737 png_crc_finish(png_ptr
, length
);
740 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
741 /* Should be an error, but we can cope with it */
742 png_warning(png_ptr
, "Missing PLTE before cHRM");
744 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
)
745 #if defined(PNG_READ_sRGB_SUPPORTED)
746 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
750 png_warning(png_ptr
, "Duplicate cHRM chunk");
751 png_crc_finish(png_ptr
, length
);
757 png_warning(png_ptr
, "Incorrect cHRM chunk length");
758 png_crc_finish(png_ptr
, length
);
762 png_crc_read(png_ptr
, buf
, 4);
763 uint_x
= png_get_uint_32(buf
);
765 png_crc_read(png_ptr
, buf
, 4);
766 uint_y
= png_get_uint_32(buf
);
768 if (uint_x
> 80000L || uint_y
> 80000L ||
769 uint_x
+ uint_y
> 100000L)
771 png_warning(png_ptr
, "Invalid cHRM white point");
772 png_crc_finish(png_ptr
, 24);
775 int_x_white
= (png_fixed_point
)uint_x
;
776 int_y_white
= (png_fixed_point
)uint_y
;
778 png_crc_read(png_ptr
, buf
, 4);
779 uint_x
= png_get_uint_32(buf
);
781 png_crc_read(png_ptr
, buf
, 4);
782 uint_y
= png_get_uint_32(buf
);
784 if (uint_x
+ uint_y
> 100000L)
786 png_warning(png_ptr
, "Invalid cHRM red point");
787 png_crc_finish(png_ptr
, 16);
790 int_x_red
= (png_fixed_point
)uint_x
;
791 int_y_red
= (png_fixed_point
)uint_y
;
793 png_crc_read(png_ptr
, buf
, 4);
794 uint_x
= png_get_uint_32(buf
);
796 png_crc_read(png_ptr
, buf
, 4);
797 uint_y
= png_get_uint_32(buf
);
799 if (uint_x
+ uint_y
> 100000L)
801 png_warning(png_ptr
, "Invalid cHRM green point");
802 png_crc_finish(png_ptr
, 8);
805 int_x_green
= (png_fixed_point
)uint_x
;
806 int_y_green
= (png_fixed_point
)uint_y
;
808 png_crc_read(png_ptr
, buf
, 4);
809 uint_x
= png_get_uint_32(buf
);
811 png_crc_read(png_ptr
, buf
, 4);
812 uint_y
= png_get_uint_32(buf
);
814 if (uint_x
+ uint_y
> 100000L)
816 png_warning(png_ptr
, "Invalid cHRM blue point");
817 png_crc_finish(png_ptr
, 0);
820 int_x_blue
= (png_fixed_point
)uint_x
;
821 int_y_blue
= (png_fixed_point
)uint_y
;
823 #ifdef PNG_FLOATING_POINT_SUPPORTED
824 white_x
= (float)int_x_white
/ (float)100000.0;
825 white_y
= (float)int_y_white
/ (float)100000.0;
826 red_x
= (float)int_x_red
/ (float)100000.0;
827 red_y
= (float)int_y_red
/ (float)100000.0;
828 green_x
= (float)int_x_green
/ (float)100000.0;
829 green_y
= (float)int_y_green
/ (float)100000.0;
830 blue_x
= (float)int_x_blue
/ (float)100000.0;
831 blue_y
= (float)int_y_blue
/ (float)100000.0;
834 #if defined(PNG_READ_sRGB_SUPPORTED)
835 if ((info_ptr
!= NULL
) && (info_ptr
->valid
& PNG_INFO_sRGB
))
837 if (PNG_OUT_OF_RANGE(int_x_white
, 31270, 1000) ||
838 PNG_OUT_OF_RANGE(int_y_white
, 32900, 1000) ||
839 PNG_OUT_OF_RANGE(int_x_red
, 64000L, 1000) ||
840 PNG_OUT_OF_RANGE(int_y_red
, 33000, 1000) ||
841 PNG_OUT_OF_RANGE(int_x_green
, 30000, 1000) ||
842 PNG_OUT_OF_RANGE(int_y_green
, 60000L, 1000) ||
843 PNG_OUT_OF_RANGE(int_x_blue
, 15000, 1000) ||
844 PNG_OUT_OF_RANGE(int_y_blue
, 6000, 1000))
847 "Ignoring incorrect cHRM value when sRGB is also present");
848 #ifndef PNG_NO_CONSOLE_IO
849 #ifdef PNG_FLOATING_POINT_SUPPORTED
850 fprintf(stderr
,"wx=%f, wy=%f, rx=%f, ry=%f\n",
851 white_x
, white_y
, red_x
, red_y
);
852 fprintf(stderr
,"gx=%f, gy=%f, bx=%f, by=%f\n",
853 green_x
, green_y
, blue_x
, blue_y
);
855 fprintf(stderr
,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
856 int_x_white
, int_y_white
, int_x_red
, int_y_red
);
857 fprintf(stderr
,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
858 int_x_green
, int_y_green
, int_x_blue
, int_y_blue
);
860 #endif /* PNG_NO_CONSOLE_IO */
862 png_crc_finish(png_ptr
, 0);
865 #endif /* PNG_READ_sRGB_SUPPORTED */
867 #ifdef PNG_FLOATING_POINT_SUPPORTED
868 png_set_cHRM(png_ptr
, info_ptr
,
869 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
871 #ifdef PNG_FIXED_POINT_SUPPORTED
872 png_set_cHRM_fixed(png_ptr
, info_ptr
,
873 int_x_white
, int_y_white
, int_x_red
, int_y_red
, int_x_green
,
874 int_y_green
, int_x_blue
, int_y_blue
);
876 if (png_crc_finish(png_ptr
, 0))
881 #if defined(PNG_READ_sRGB_SUPPORTED)
883 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
888 png_debug(1, "in png_handle_sRGB\n");
890 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
891 png_error(png_ptr
, "Missing IHDR before sRGB");
892 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
894 png_warning(png_ptr
, "Invalid sRGB after IDAT");
895 png_crc_finish(png_ptr
, length
);
898 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
899 /* Should be an error, but we can cope with it */
900 png_warning(png_ptr
, "Out of place sRGB chunk");
902 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sRGB
))
904 png_warning(png_ptr
, "Duplicate sRGB chunk");
905 png_crc_finish(png_ptr
, length
);
911 png_warning(png_ptr
, "Incorrect sRGB chunk length");
912 png_crc_finish(png_ptr
, length
);
916 png_crc_read(png_ptr
, buf
, 1);
917 if (png_crc_finish(png_ptr
, 0))
921 /* check for bad intent */
922 if (intent
>= PNG_sRGB_INTENT_LAST
)
924 png_warning(png_ptr
, "Unknown sRGB intent");
928 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
929 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_gAMA
))
931 png_fixed_point igamma
;
932 #ifdef PNG_FIXED_POINT_SUPPORTED
933 igamma
=info_ptr
->int_gamma
;
935 # ifdef PNG_FLOATING_POINT_SUPPORTED
936 igamma
=(png_fixed_point
)(info_ptr
->gamma
* 100000.);
939 if (PNG_OUT_OF_RANGE(igamma
, 45500L, 500))
942 "Ignoring incorrect gAMA value when sRGB is also present");
943 #ifndef PNG_NO_CONSOLE_IO
944 # ifdef PNG_FIXED_POINT_SUPPORTED
945 fprintf(stderr
,"incorrect gamma=(%d/100000)\n",(int)png_ptr
->int_gamma
);
947 # ifdef PNG_FLOATING_POINT_SUPPORTED
948 fprintf(stderr
,"incorrect gamma=%f\n",png_ptr
->gamma
);
954 #endif /* PNG_READ_gAMA_SUPPORTED */
956 #ifdef PNG_READ_cHRM_SUPPORTED
957 #ifdef PNG_FIXED_POINT_SUPPORTED
958 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_cHRM
))
959 if (PNG_OUT_OF_RANGE(info_ptr
->int_x_white
, 31270, 1000) ||
960 PNG_OUT_OF_RANGE(info_ptr
->int_y_white
, 32900, 1000) ||
961 PNG_OUT_OF_RANGE(info_ptr
->int_x_red
, 64000L, 1000) ||
962 PNG_OUT_OF_RANGE(info_ptr
->int_y_red
, 33000, 1000) ||
963 PNG_OUT_OF_RANGE(info_ptr
->int_x_green
, 30000, 1000) ||
964 PNG_OUT_OF_RANGE(info_ptr
->int_y_green
, 60000L, 1000) ||
965 PNG_OUT_OF_RANGE(info_ptr
->int_x_blue
, 15000, 1000) ||
966 PNG_OUT_OF_RANGE(info_ptr
->int_y_blue
, 6000, 1000))
969 "Ignoring incorrect cHRM value when sRGB is also present");
971 #endif /* PNG_FIXED_POINT_SUPPORTED */
972 #endif /* PNG_READ_cHRM_SUPPORTED */
974 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
976 #endif /* PNG_READ_sRGB_SUPPORTED */
978 #if defined(PNG_READ_iCCP_SUPPORTED)
980 png_handle_iCCP(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
981 /* Note: this does not properly handle chunks that are > 64K under DOS */
984 png_byte compression_type
;
987 png_uint_32 skip
= 0;
988 png_uint_32 profile_size
, profile_length
;
989 png_size_t slength
, prefix_length
, data_length
;
991 png_debug(1, "in png_handle_iCCP\n");
993 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
994 png_error(png_ptr
, "Missing IHDR before iCCP");
995 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
997 png_warning(png_ptr
, "Invalid iCCP after IDAT");
998 png_crc_finish(png_ptr
, length
);
1001 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
1002 /* Should be an error, but we can cope with it */
1003 png_warning(png_ptr
, "Out of place iCCP chunk");
1005 if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_iCCP
))
1007 png_warning(png_ptr
, "Duplicate iCCP chunk");
1008 png_crc_finish(png_ptr
, length
);
1012 #ifdef PNG_MAX_MALLOC_64K
1013 if (length
> (png_uint_32
)65535L)
1015 png_warning(png_ptr
, "iCCP chunk too large to fit in memory");
1016 skip
= length
- (png_uint_32
)65535L;
1017 length
= (png_uint_32
)65535L;
1021 chunkdata
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1022 slength
= (png_size_t
)length
;
1023 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1025 if (png_crc_finish(png_ptr
, skip
))
1027 png_free(png_ptr
, chunkdata
);
1031 chunkdata
[slength
] = 0x00;
1033 for (profile
= chunkdata
; *profile
; profile
++)
1034 /* empty loop to find end of name */ ;
1038 /* there should be at least one zero (the compression type byte)
1039 following the separator, and we should be on it */
1040 if ( profile
>= chunkdata
+ slength
)
1042 png_free(png_ptr
, chunkdata
);
1043 png_warning(png_ptr
, "Malformed iCCP chunk");
1047 /* compression_type should always be zero */
1048 compression_type
= *profile
++;
1049 if (compression_type
)
1051 png_warning(png_ptr
, "Ignoring nonzero compression type in iCCP chunk");
1052 compression_type
=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1056 prefix_length
= profile
- chunkdata
;
1057 chunkdata
= png_decompress_chunk(png_ptr
, compression_type
, chunkdata
,
1058 slength
, prefix_length
, &data_length
);
1060 profile_length
= data_length
- prefix_length
;
1062 if ( prefix_length
> data_length
|| profile_length
< 4)
1064 png_free(png_ptr
, chunkdata
);
1065 png_warning(png_ptr
, "Profile size field missing from iCCP chunk");
1069 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1070 pC
= (png_bytep
)(chunkdata
+prefix_length
);
1071 profile_size
= ((*(pC
))<<24) |
1076 if(profile_size
< profile_length
)
1077 profile_length
= profile_size
;
1079 if(profile_size
> profile_length
)
1081 png_free(png_ptr
, chunkdata
);
1082 png_warning(png_ptr
, "Ignoring truncated iCCP profile.");
1086 png_set_iCCP(png_ptr
, info_ptr
, chunkdata
, compression_type
,
1087 chunkdata
+ prefix_length
, profile_length
);
1088 png_free(png_ptr
, chunkdata
);
1090 #endif /* PNG_READ_iCCP_SUPPORTED */
1092 #if defined(PNG_READ_sPLT_SUPPORTED)
1094 png_handle_sPLT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1095 /* Note: this does not properly handle chunks that are > 64K under DOS */
1097 png_bytep chunkdata
;
1098 png_bytep entry_start
;
1099 png_sPLT_t new_palette
;
1100 #ifdef PNG_NO_POINTER_INDEXING
1103 int data_length
, entry_size
, i
;
1104 png_uint_32 skip
= 0;
1107 png_debug(1, "in png_handle_sPLT\n");
1109 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1110 png_error(png_ptr
, "Missing IHDR before sPLT");
1111 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1113 png_warning(png_ptr
, "Invalid sPLT after IDAT");
1114 png_crc_finish(png_ptr
, length
);
1118 #ifdef PNG_MAX_MALLOC_64K
1119 if (length
> (png_uint_32
)65535L)
1121 png_warning(png_ptr
, "sPLT chunk too large to fit in memory");
1122 skip
= length
- (png_uint_32
)65535L;
1123 length
= (png_uint_32
)65535L;
1127 chunkdata
= (png_bytep
)png_malloc(png_ptr
, length
+ 1);
1128 slength
= (png_size_t
)length
;
1129 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1131 if (png_crc_finish(png_ptr
, skip
))
1133 png_free(png_ptr
, chunkdata
);
1137 chunkdata
[slength
] = 0x00;
1139 for (entry_start
= chunkdata
; *entry_start
; entry_start
++)
1140 /* empty loop to find end of name */ ;
1143 /* a sample depth should follow the separator, and we should be on it */
1144 if (entry_start
> chunkdata
+ slength
)
1146 png_free(png_ptr
, chunkdata
);
1147 png_warning(png_ptr
, "malformed sPLT chunk");
1151 new_palette
.depth
= *entry_start
++;
1152 entry_size
= (new_palette
.depth
== 8 ? 6 : 10);
1153 data_length
= (slength
- (entry_start
- chunkdata
));
1155 /* integrity-check the data length */
1156 if (data_length
% entry_size
)
1158 png_free(png_ptr
, chunkdata
);
1159 png_warning(png_ptr
, "sPLT chunk has bad length");
1163 new_palette
.nentries
= (png_int_32
) ( data_length
/ entry_size
);
1164 if ((png_uint_32
) new_palette
.nentries
> (png_uint_32
) (PNG_SIZE_MAX
/
1165 png_sizeof(png_sPLT_entry
)))
1167 png_warning(png_ptr
, "sPLT chunk too long");
1170 new_palette
.entries
= (png_sPLT_entryp
)png_malloc_warn(
1171 png_ptr
, new_palette
.nentries
* png_sizeof(png_sPLT_entry
));
1172 if (new_palette
.entries
== NULL
)
1174 png_warning(png_ptr
, "sPLT chunk requires too much memory");
1178 #ifndef PNG_NO_POINTER_INDEXING
1179 for (i
= 0; i
< new_palette
.nentries
; i
++)
1181 png_sPLT_entryp pp
= new_palette
.entries
+ i
;
1183 if (new_palette
.depth
== 8)
1185 pp
->red
= *entry_start
++;
1186 pp
->green
= *entry_start
++;
1187 pp
->blue
= *entry_start
++;
1188 pp
->alpha
= *entry_start
++;
1192 pp
->red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1193 pp
->green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1194 pp
->blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1195 pp
->alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1197 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1200 pp
= new_palette
.entries
;
1201 for (i
= 0; i
< new_palette
.nentries
; i
++)
1204 if (new_palette
.depth
== 8)
1206 pp
[i
].red
= *entry_start
++;
1207 pp
[i
].green
= *entry_start
++;
1208 pp
[i
].blue
= *entry_start
++;
1209 pp
[i
].alpha
= *entry_start
++;
1213 pp
[i
].red
= png_get_uint_16(entry_start
); entry_start
+= 2;
1214 pp
[i
].green
= png_get_uint_16(entry_start
); entry_start
+= 2;
1215 pp
[i
].blue
= png_get_uint_16(entry_start
); entry_start
+= 2;
1216 pp
[i
].alpha
= png_get_uint_16(entry_start
); entry_start
+= 2;
1218 pp
->frequency
= png_get_uint_16(entry_start
); entry_start
+= 2;
1222 /* discard all chunk data except the name and stash that */
1223 new_palette
.name
= (png_charp
)chunkdata
;
1225 png_set_sPLT(png_ptr
, info_ptr
, &new_palette
, 1);
1227 png_free(png_ptr
, chunkdata
);
1228 png_free(png_ptr
, new_palette
.entries
);
1230 #endif /* PNG_READ_sPLT_SUPPORTED */
1232 #if defined(PNG_READ_tRNS_SUPPORTED)
1234 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1236 png_byte readbuf
[PNG_MAX_PALETTE_LENGTH
];
1238 png_debug(1, "in png_handle_tRNS\n");
1240 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1241 png_error(png_ptr
, "Missing IHDR before tRNS");
1242 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1244 png_warning(png_ptr
, "Invalid tRNS after IDAT");
1245 png_crc_finish(png_ptr
, length
);
1248 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tRNS
))
1250 png_warning(png_ptr
, "Duplicate tRNS chunk");
1251 png_crc_finish(png_ptr
, length
);
1255 if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
1261 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1262 png_crc_finish(png_ptr
, length
);
1266 png_crc_read(png_ptr
, buf
, 2);
1267 png_ptr
->num_trans
= 1;
1268 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
1270 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
1276 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1277 png_crc_finish(png_ptr
, length
);
1280 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
1281 png_ptr
->num_trans
= 1;
1282 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
1283 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
1284 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
1286 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1288 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1290 /* Should be an error, but we can cope with it. */
1291 png_warning(png_ptr
, "Missing PLTE before tRNS");
1293 if (length
> (png_uint_32
)png_ptr
->num_palette
||
1294 length
> PNG_MAX_PALETTE_LENGTH
)
1296 png_warning(png_ptr
, "Incorrect tRNS chunk length");
1297 png_crc_finish(png_ptr
, length
);
1302 png_warning(png_ptr
, "Zero length tRNS chunk");
1303 png_crc_finish(png_ptr
, length
);
1306 png_crc_read(png_ptr
, readbuf
, (png_size_t
)length
);
1307 png_ptr
->num_trans
= (png_uint_16
)length
;
1311 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
1312 png_crc_finish(png_ptr
, length
);
1316 if (png_crc_finish(png_ptr
, 0))
1318 png_ptr
->num_trans
= 0;
1322 png_set_tRNS(png_ptr
, info_ptr
, readbuf
, png_ptr
->num_trans
,
1323 &(png_ptr
->trans_values
));
1327 #if defined(PNG_READ_bKGD_SUPPORTED)
1329 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1334 png_debug(1, "in png_handle_bKGD\n");
1336 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1337 png_error(png_ptr
, "Missing IHDR before bKGD");
1338 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1340 png_warning(png_ptr
, "Invalid bKGD after IDAT");
1341 png_crc_finish(png_ptr
, length
);
1344 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
1345 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
1347 png_warning(png_ptr
, "Missing PLTE before bKGD");
1348 png_crc_finish(png_ptr
, length
);
1351 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_bKGD
))
1353 png_warning(png_ptr
, "Duplicate bKGD chunk");
1354 png_crc_finish(png_ptr
, length
);
1358 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1360 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
1365 if (length
!= truelen
)
1367 png_warning(png_ptr
, "Incorrect bKGD chunk length");
1368 png_crc_finish(png_ptr
, length
);
1372 png_crc_read(png_ptr
, buf
, truelen
);
1373 if (png_crc_finish(png_ptr
, 0))
1376 /* We convert the index value into RGB components so that we can allow
1377 * arbitrary RGB values for background when we have transparency, and
1378 * so it is easy to determine the RGB values of the background color
1379 * from the info_ptr struct. */
1380 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
1382 png_ptr
->background
.index
= buf
[0];
1383 if(info_ptr
->num_palette
)
1385 if(buf
[0] > info_ptr
->num_palette
)
1387 png_warning(png_ptr
, "Incorrect bKGD chunk index value");
1390 png_ptr
->background
.red
=
1391 (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
1392 png_ptr
->background
.green
=
1393 (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
1394 png_ptr
->background
.blue
=
1395 (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
1398 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
1400 png_ptr
->background
.red
=
1401 png_ptr
->background
.green
=
1402 png_ptr
->background
.blue
=
1403 png_ptr
->background
.gray
= png_get_uint_16(buf
);
1407 png_ptr
->background
.red
= png_get_uint_16(buf
);
1408 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
1409 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
1412 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
1416 #if defined(PNG_READ_hIST_SUPPORTED)
1418 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1420 unsigned int num
, i
;
1421 png_uint_16 readbuf
[PNG_MAX_PALETTE_LENGTH
];
1423 png_debug(1, "in png_handle_hIST\n");
1425 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1426 png_error(png_ptr
, "Missing IHDR before hIST");
1427 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1429 png_warning(png_ptr
, "Invalid hIST after IDAT");
1430 png_crc_finish(png_ptr
, length
);
1433 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
1435 png_warning(png_ptr
, "Missing PLTE before hIST");
1436 png_crc_finish(png_ptr
, length
);
1439 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_hIST
))
1441 png_warning(png_ptr
, "Duplicate hIST chunk");
1442 png_crc_finish(png_ptr
, length
);
1447 if (num
!= (unsigned int) png_ptr
->num_palette
|| num
>
1448 (unsigned int) PNG_MAX_PALETTE_LENGTH
)
1450 png_warning(png_ptr
, "Incorrect hIST chunk length");
1451 png_crc_finish(png_ptr
, length
);
1455 for (i
= 0; i
< num
; i
++)
1459 png_crc_read(png_ptr
, buf
, 2);
1460 readbuf
[i
] = png_get_uint_16(buf
);
1463 if (png_crc_finish(png_ptr
, 0))
1466 png_set_hIST(png_ptr
, info_ptr
, readbuf
);
1470 #if defined(PNG_READ_pHYs_SUPPORTED)
1472 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1475 png_uint_32 res_x
, res_y
;
1478 png_debug(1, "in png_handle_pHYs\n");
1480 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1481 png_error(png_ptr
, "Missing IHDR before pHYs");
1482 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1484 png_warning(png_ptr
, "Invalid pHYs after IDAT");
1485 png_crc_finish(png_ptr
, length
);
1488 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pHYs
))
1490 png_warning(png_ptr
, "Duplicate pHYs chunk");
1491 png_crc_finish(png_ptr
, length
);
1497 png_warning(png_ptr
, "Incorrect pHYs chunk length");
1498 png_crc_finish(png_ptr
, length
);
1502 png_crc_read(png_ptr
, buf
, 9);
1503 if (png_crc_finish(png_ptr
, 0))
1506 res_x
= png_get_uint_32(buf
);
1507 res_y
= png_get_uint_32(buf
+ 4);
1509 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
1513 #if defined(PNG_READ_oFFs_SUPPORTED)
1515 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1518 png_int_32 offset_x
, offset_y
;
1521 png_debug(1, "in png_handle_oFFs\n");
1523 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1524 png_error(png_ptr
, "Missing IHDR before oFFs");
1525 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1527 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1528 png_crc_finish(png_ptr
, length
);
1531 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_oFFs
))
1533 png_warning(png_ptr
, "Duplicate oFFs chunk");
1534 png_crc_finish(png_ptr
, length
);
1540 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1541 png_crc_finish(png_ptr
, length
);
1545 png_crc_read(png_ptr
, buf
, 9);
1546 if (png_crc_finish(png_ptr
, 0))
1549 offset_x
= png_get_int_32(buf
);
1550 offset_y
= png_get_int_32(buf
+ 4);
1552 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1556 #if defined(PNG_READ_pCAL_SUPPORTED)
1557 /* read the pCAL chunk (described in the PNG Extensions document) */
1559 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1563 png_byte type
, nparams
;
1564 png_charp buf
, units
, endptr
;
1569 png_debug(1, "in png_handle_pCAL\n");
1571 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1572 png_error(png_ptr
, "Missing IHDR before pCAL");
1573 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1575 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1576 png_crc_finish(png_ptr
, length
);
1579 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_pCAL
))
1581 png_warning(png_ptr
, "Duplicate pCAL chunk");
1582 png_crc_finish(png_ptr
, length
);
1586 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
1588 purpose
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1589 if (purpose
== NULL
)
1591 png_warning(png_ptr
, "No memory for pCAL purpose.");
1594 slength
= (png_size_t
)length
;
1595 png_crc_read(png_ptr
, (png_bytep
)purpose
, slength
);
1597 if (png_crc_finish(png_ptr
, 0))
1599 png_free(png_ptr
, purpose
);
1603 purpose
[slength
] = 0x00; /* null terminate the last string */
1605 png_debug(3, "Finding end of pCAL purpose string\n");
1606 for (buf
= purpose
; *buf
; buf
++)
1609 endptr
= purpose
+ slength
;
1611 /* We need to have at least 12 bytes after the purpose string
1612 in order to get the parameter information. */
1613 if (endptr
<= buf
+ 12)
1615 png_warning(png_ptr
, "Invalid pCAL data");
1616 png_free(png_ptr
, purpose
);
1620 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1621 X0
= png_get_int_32((png_bytep
)buf
+1);
1622 X1
= png_get_int_32((png_bytep
)buf
+5);
1627 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1628 /* Check that we have the right number of parameters for known
1630 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1631 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1632 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1633 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1635 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1636 png_free(png_ptr
, purpose
);
1639 else if (type
>= PNG_EQUATION_LAST
)
1641 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1644 for (buf
= units
; *buf
; buf
++)
1645 /* Empty loop to move past the units string. */ ;
1647 png_debug(3, "Allocating pCAL parameters array\n");
1648 params
= (png_charpp
)png_malloc_warn(png_ptr
, (png_uint_32
)(nparams
1649 *png_sizeof(png_charp
))) ;
1652 png_free(png_ptr
, purpose
);
1653 png_warning(png_ptr
, "No memory for pCAL params.");
1657 /* Get pointers to the start of each parameter string. */
1658 for (i
= 0; i
< (int)nparams
; i
++)
1660 buf
++; /* Skip the null string terminator from previous parameter. */
1662 png_debug1(3, "Reading pCAL parameter %d\n", i
);
1663 for (params
[i
] = buf
; *buf
!= 0x00 && buf
<= endptr
; buf
++)
1664 /* Empty loop to move past each parameter string */ ;
1666 /* Make sure we haven't run out of data yet */
1669 png_warning(png_ptr
, "Invalid pCAL data");
1670 png_free(png_ptr
, purpose
);
1671 png_free(png_ptr
, params
);
1676 png_set_pCAL(png_ptr
, info_ptr
, purpose
, X0
, X1
, type
, nparams
,
1679 png_free(png_ptr
, purpose
);
1680 png_free(png_ptr
, params
);
1684 #if defined(PNG_READ_sCAL_SUPPORTED)
1685 /* read the sCAL chunk */
1687 png_handle_sCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1689 png_charp buffer
, ep
;
1690 #ifdef PNG_FLOATING_POINT_SUPPORTED
1691 double width
, height
;
1694 #ifdef PNG_FIXED_POINT_SUPPORTED
1695 png_charp swidth
, sheight
;
1700 png_debug(1, "in png_handle_sCAL\n");
1702 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1703 png_error(png_ptr
, "Missing IHDR before sCAL");
1704 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1706 png_warning(png_ptr
, "Invalid sCAL after IDAT");
1707 png_crc_finish(png_ptr
, length
);
1710 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_sCAL
))
1712 png_warning(png_ptr
, "Duplicate sCAL chunk");
1713 png_crc_finish(png_ptr
, length
);
1717 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
1719 buffer
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1722 png_warning(png_ptr
, "Out of memory while processing sCAL chunk");
1725 slength
= (png_size_t
)length
;
1726 png_crc_read(png_ptr
, (png_bytep
)buffer
, slength
);
1728 if (png_crc_finish(png_ptr
, 0))
1730 png_free(png_ptr
, buffer
);
1734 buffer
[slength
] = 0x00; /* null terminate the last string */
1736 ep
= buffer
+ 1; /* skip unit byte */
1738 #ifdef PNG_FLOATING_POINT_SUPPORTED
1739 width
= png_strtod(png_ptr
, ep
, &vp
);
1742 png_warning(png_ptr
, "malformed width string in sCAL chunk");
1746 #ifdef PNG_FIXED_POINT_SUPPORTED
1747 swidth
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1750 png_warning(png_ptr
, "Out of memory while processing sCAL chunk width");
1753 png_memcpy(swidth
, ep
, (png_size_t
)png_strlen(ep
));
1757 for (ep
= buffer
; *ep
; ep
++)
1761 #ifdef PNG_FLOATING_POINT_SUPPORTED
1762 height
= png_strtod(png_ptr
, ep
, &vp
);
1765 png_warning(png_ptr
, "malformed height string in sCAL chunk");
1769 #ifdef PNG_FIXED_POINT_SUPPORTED
1770 sheight
= (png_charp
)png_malloc_warn(png_ptr
, png_strlen(ep
) + 1);
1773 png_warning(png_ptr
, "Out of memory while processing sCAL chunk height");
1776 png_memcpy(sheight
, ep
, (png_size_t
)png_strlen(ep
));
1780 if (buffer
+ slength
< ep
1781 #ifdef PNG_FLOATING_POINT_SUPPORTED
1782 || width
<= 0. || height
<= 0.
1786 png_warning(png_ptr
, "Invalid sCAL data");
1787 png_free(png_ptr
, buffer
);
1788 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1789 png_free(png_ptr
, swidth
);
1790 png_free(png_ptr
, sheight
);
1796 #ifdef PNG_FLOATING_POINT_SUPPORTED
1797 png_set_sCAL(png_ptr
, info_ptr
, buffer
[0], width
, height
);
1799 #ifdef PNG_FIXED_POINT_SUPPORTED
1800 png_set_sCAL_s(png_ptr
, info_ptr
, buffer
[0], swidth
, sheight
);
1804 png_free(png_ptr
, buffer
);
1805 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1806 png_free(png_ptr
, swidth
);
1807 png_free(png_ptr
, sheight
);
1812 #if defined(PNG_READ_tIME_SUPPORTED)
1814 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1819 png_debug(1, "in png_handle_tIME\n");
1821 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1822 png_error(png_ptr
, "Out of place tIME chunk");
1823 else if (info_ptr
!= NULL
&& (info_ptr
->valid
& PNG_INFO_tIME
))
1825 png_warning(png_ptr
, "Duplicate tIME chunk");
1826 png_crc_finish(png_ptr
, length
);
1830 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1831 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1835 png_warning(png_ptr
, "Incorrect tIME chunk length");
1836 png_crc_finish(png_ptr
, length
);
1840 png_crc_read(png_ptr
, buf
, 7);
1841 if (png_crc_finish(png_ptr
, 0))
1844 mod_time
.second
= buf
[6];
1845 mod_time
.minute
= buf
[5];
1846 mod_time
.hour
= buf
[4];
1847 mod_time
.day
= buf
[3];
1848 mod_time
.month
= buf
[2];
1849 mod_time
.year
= png_get_uint_16(buf
);
1851 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1855 #if defined(PNG_READ_tEXt_SUPPORTED)
1856 /* Note: this does not properly handle chunks that are > 64K under DOS */
1858 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1863 png_uint_32 skip
= 0;
1867 png_debug(1, "in png_handle_tEXt\n");
1869 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1870 png_error(png_ptr
, "Missing IHDR before tEXt");
1872 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1873 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1875 #ifdef PNG_MAX_MALLOC_64K
1876 if (length
> (png_uint_32
)65535L)
1878 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1879 skip
= length
- (png_uint_32
)65535L;
1880 length
= (png_uint_32
)65535L;
1884 key
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1887 png_warning(png_ptr
, "No memory to process text chunk.");
1890 slength
= (png_size_t
)length
;
1891 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1893 if (png_crc_finish(png_ptr
, skip
))
1895 png_free(png_ptr
, key
);
1899 key
[slength
] = 0x00;
1901 for (text
= key
; *text
; text
++)
1902 /* empty loop to find end of key */ ;
1904 if (text
!= key
+ slength
)
1907 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
1908 (png_uint_32
)png_sizeof(png_text
));
1909 if (text_ptr
== NULL
)
1911 png_warning(png_ptr
, "Not enough memory to process text chunk.");
1912 png_free(png_ptr
, key
);
1915 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1916 text_ptr
->key
= key
;
1917 #ifdef PNG_iTXt_SUPPORTED
1918 text_ptr
->lang
= NULL
;
1919 text_ptr
->lang_key
= NULL
;
1920 text_ptr
->itxt_length
= 0;
1922 text_ptr
->text
= text
;
1923 text_ptr
->text_length
= png_strlen(text
);
1925 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
1927 png_free(png_ptr
, key
);
1928 png_free(png_ptr
, text_ptr
);
1930 png_warning(png_ptr
, "Insufficient memory to process text chunk.");
1934 #if defined(PNG_READ_zTXt_SUPPORTED)
1935 /* note: this does not correctly handle chunks that are > 64K under DOS */
1937 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1940 png_charp chunkdata
;
1944 png_size_t slength
, prefix_len
, data_len
;
1946 png_debug(1, "in png_handle_zTXt\n");
1947 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1948 png_error(png_ptr
, "Missing IHDR before zTXt");
1950 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1951 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1953 #ifdef PNG_MAX_MALLOC_64K
1954 /* We will no doubt have problems with chunks even half this size, but
1955 there is no hard and fast rule to tell us where to stop. */
1956 if (length
> (png_uint_32
)65535L)
1958 png_warning(png_ptr
,"zTXt chunk too large to fit in memory");
1959 png_crc_finish(png_ptr
, length
);
1964 chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
1965 if (chunkdata
== NULL
)
1967 png_warning(png_ptr
,"Out of memory processing zTXt chunk.");
1970 slength
= (png_size_t
)length
;
1971 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
1972 if (png_crc_finish(png_ptr
, 0))
1974 png_free(png_ptr
, chunkdata
);
1978 chunkdata
[slength
] = 0x00;
1980 for (text
= chunkdata
; *text
; text
++)
1983 /* zTXt must have some text after the chunkdataword */
1984 if (text
== chunkdata
+ slength
)
1986 comp_type
= PNG_TEXT_COMPRESSION_NONE
;
1987 png_warning(png_ptr
, "Zero length zTXt chunk");
1991 comp_type
= *(++text
);
1992 if (comp_type
!= PNG_TEXT_COMPRESSION_zTXt
)
1994 png_warning(png_ptr
, "Unknown compression type in zTXt chunk");
1995 comp_type
= PNG_TEXT_COMPRESSION_zTXt
;
1997 text
++; /* skip the compression_method byte */
1999 prefix_len
= text
- chunkdata
;
2001 chunkdata
= (png_charp
)png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
2002 (png_size_t
)length
, prefix_len
, &data_len
);
2004 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2005 (png_uint_32
)png_sizeof(png_text
));
2006 if (text_ptr
== NULL
)
2008 png_warning(png_ptr
,"Not enough memory to process zTXt chunk.");
2009 png_free(png_ptr
, chunkdata
);
2012 text_ptr
->compression
= comp_type
;
2013 text_ptr
->key
= chunkdata
;
2014 #ifdef PNG_iTXt_SUPPORTED
2015 text_ptr
->lang
= NULL
;
2016 text_ptr
->lang_key
= NULL
;
2017 text_ptr
->itxt_length
= 0;
2019 text_ptr
->text
= chunkdata
+ prefix_len
;
2020 text_ptr
->text_length
= data_len
;
2022 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2024 png_free(png_ptr
, text_ptr
);
2025 png_free(png_ptr
, chunkdata
);
2027 png_error(png_ptr
, "Insufficient memory to store zTXt chunk.");
2031 #if defined(PNG_READ_iTXt_SUPPORTED)
2032 /* note: this does not correctly handle chunks that are > 64K under DOS */
2034 png_handle_iTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2037 png_charp chunkdata
;
2038 png_charp key
, lang
, text
, lang_key
;
2042 png_size_t slength
, prefix_len
, data_len
;
2044 png_debug(1, "in png_handle_iTXt\n");
2046 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
2047 png_error(png_ptr
, "Missing IHDR before iTXt");
2049 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2050 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2052 #ifdef PNG_MAX_MALLOC_64K
2053 /* We will no doubt have problems with chunks even half this size, but
2054 there is no hard and fast rule to tell us where to stop. */
2055 if (length
> (png_uint_32
)65535L)
2057 png_warning(png_ptr
,"iTXt chunk too large to fit in memory");
2058 png_crc_finish(png_ptr
, length
);
2063 chunkdata
= (png_charp
)png_malloc_warn(png_ptr
, length
+ 1);
2064 if (chunkdata
== NULL
)
2066 png_warning(png_ptr
, "No memory to process iTXt chunk.");
2069 slength
= (png_size_t
)length
;
2070 png_crc_read(png_ptr
, (png_bytep
)chunkdata
, slength
);
2071 if (png_crc_finish(png_ptr
, 0))
2073 png_free(png_ptr
, chunkdata
);
2077 chunkdata
[slength
] = 0x00;
2079 for (lang
= chunkdata
; *lang
; lang
++)
2081 lang
++; /* skip NUL separator */
2083 /* iTXt must have a language tag (possibly empty), two compression bytes,
2084 translated keyword (possibly empty), and possibly some text after the
2087 if (lang
>= chunkdata
+ slength
)
2089 comp_flag
= PNG_TEXT_COMPRESSION_NONE
;
2090 png_warning(png_ptr
, "Zero length iTXt chunk");
2094 comp_flag
= *lang
++;
2095 comp_type
= *lang
++;
2098 for (lang_key
= lang
; *lang_key
; lang_key
++)
2100 lang_key
++; /* skip NUL separator */
2102 for (text
= lang_key
; *text
; text
++)
2104 text
++; /* skip NUL separator */
2106 prefix_len
= text
- chunkdata
;
2110 chunkdata
= png_decompress_chunk(png_ptr
, comp_type
, chunkdata
,
2111 (size_t)length
, prefix_len
, &data_len
);
2113 data_len
=png_strlen(chunkdata
+ prefix_len
);
2114 text_ptr
= (png_textp
)png_malloc_warn(png_ptr
,
2115 (png_uint_32
)png_sizeof(png_text
));
2116 if (text_ptr
== NULL
)
2118 png_warning(png_ptr
,"Not enough memory to process iTXt chunk.");
2119 png_free(png_ptr
, chunkdata
);
2122 text_ptr
->compression
= (int)comp_flag
+ 1;
2123 text_ptr
->lang_key
= chunkdata
+(lang_key
-key
);
2124 text_ptr
->lang
= chunkdata
+(lang
-key
);
2125 text_ptr
->itxt_length
= data_len
;
2126 text_ptr
->text_length
= 0;
2127 text_ptr
->key
= chunkdata
;
2128 text_ptr
->text
= chunkdata
+ prefix_len
;
2130 ret
=png_set_text_2(png_ptr
, info_ptr
, text_ptr
, 1);
2132 png_free(png_ptr
, text_ptr
);
2133 png_free(png_ptr
, chunkdata
);
2135 png_error(png_ptr
, "Insufficient memory to store iTXt chunk.");
2139 /* This function is called when we haven't found a handler for a
2140 chunk. If there isn't a problem with the chunk itself (ie bad
2141 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2142 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2143 case it will be saved away to be written out later. */
2145 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
2147 png_uint_32 skip
= 0;
2149 png_debug(1, "in png_handle_unknown\n");
2151 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
2153 #ifdef PNG_USE_LOCAL_ARRAYS
2156 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4)) /* not an IDAT */
2157 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2160 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
2162 if (!(png_ptr
->chunk_name
[0] & 0x20))
2164 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2165 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2166 PNG_HANDLE_CHUNK_ALWAYS
2167 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2168 && png_ptr
->read_user_chunk_fn
== NULL
2172 png_chunk_error(png_ptr
, "unknown critical chunk");
2175 #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
2176 if ((png_ptr
->flags
& PNG_FLAG_KEEP_UNKNOWN_CHUNKS
) ||
2177 (png_ptr
->read_user_chunk_fn
!= NULL
))
2179 #ifdef PNG_MAX_MALLOC_64K
2180 if (length
> (png_uint_32
)65535L)
2182 png_warning(png_ptr
, "unknown chunk too large to fit in memory");
2183 skip
= length
- (png_uint_32
)65535L;
2184 length
= (png_uint_32
)65535L;
2187 png_strcpy((png_charp
)png_ptr
->unknown_chunk
.name
,
2188 (png_charp
)png_ptr
->chunk_name
);
2189 png_ptr
->unknown_chunk
.data
= (png_bytep
)png_malloc(png_ptr
, length
);
2190 png_ptr
->unknown_chunk
.size
= (png_size_t
)length
;
2191 png_crc_read(png_ptr
, (png_bytep
)png_ptr
->unknown_chunk
.data
, length
);
2192 #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2193 if(png_ptr
->read_user_chunk_fn
!= NULL
)
2195 /* callback to user unknown chunk handler */
2197 ret
= (*(png_ptr
->read_user_chunk_fn
))
2198 (png_ptr
, &png_ptr
->unknown_chunk
);
2200 png_chunk_error(png_ptr
, "error in user chunk");
2203 if (!(png_ptr
->chunk_name
[0] & 0x20))
2204 if(png_handle_as_unknown(png_ptr
, png_ptr
->chunk_name
) !=
2205 PNG_HANDLE_CHUNK_ALWAYS
)
2206 png_chunk_error(png_ptr
, "unknown critical chunk");
2207 png_set_unknown_chunks(png_ptr
, info_ptr
,
2208 &png_ptr
->unknown_chunk
, 1);
2212 png_set_unknown_chunks(png_ptr
, info_ptr
, &png_ptr
->unknown_chunk
, 1);
2214 png_free(png_ptr
, png_ptr
->unknown_chunk
.data
);
2215 png_ptr
->unknown_chunk
.data
= NULL
;
2221 png_crc_finish(png_ptr
, skip
);
2223 #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
2224 if (&info_ptr
== NULL
) /* quiet compiler warnings about unused info_ptr */
2229 /* This function is called to verify that a chunk name is valid.
2230 This function can't have the "critical chunk check" incorporated
2231 into it, since in the future we will need to be able to call user
2232 functions to handle unknown critical chunks after we check that
2233 the chunk name itself is valid. */
2235 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2238 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
2240 png_debug(1, "in png_check_chunk_name\n");
2241 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
2242 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
2244 png_chunk_error(png_ptr
, "invalid chunk type");
2248 /* Combines the row recently read in with the existing pixels in the
2249 row. This routine takes care of alpha and transparency if requested.
2250 This routine also handles the two methods of progressive display
2251 of interlaced images, depending on the mask value.
2252 The mask value describes which pixels are to be combined with
2253 the row. The pattern always repeats every 8 pixels, so just 8
2254 bits are needed. A one indicates the pixel is to be combined,
2255 a zero indicates the pixel is to be skipped. This is in addition
2256 to any alpha or transparency value associated with the pixel. If
2257 you want all pixels to be combined, pass 0xff (255) in mask. */
2258 #ifndef PNG_HAVE_MMX_COMBINE_ROW
2260 png_combine_row(png_structp png_ptr
, png_bytep row
, int mask
)
2262 png_debug(1,"in png_combine_row\n");
2265 png_memcpy(row
, png_ptr
->row_buf
+ 1,
2266 PNG_ROWBYTES(png_ptr
->row_info
.pixel_depth
, png_ptr
->width
));
2270 switch (png_ptr
->row_info
.pixel_depth
)
2274 png_bytep sp
= png_ptr
->row_buf
+ 1;
2276 int s_inc
, s_start
, s_end
;
2280 png_uint_32 row_width
= png_ptr
->width
;
2282 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2283 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2299 for (i
= 0; i
< row_width
; i
++)
2305 value
= (*sp
>> shift
) & 0x01;
2306 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
2307 *dp
|= (png_byte
)(value
<< shift
);
2328 png_bytep sp
= png_ptr
->row_buf
+ 1;
2330 int s_start
, s_end
, s_inc
;
2334 png_uint_32 row_width
= png_ptr
->width
;
2337 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2338 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2354 for (i
= 0; i
< row_width
; i
++)
2358 value
= (*sp
>> shift
) & 0x03;
2359 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
2360 *dp
|= (png_byte
)(value
<< shift
);
2380 png_bytep sp
= png_ptr
->row_buf
+ 1;
2382 int s_start
, s_end
, s_inc
;
2386 png_uint_32 row_width
= png_ptr
->width
;
2389 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2390 if (png_ptr
->transformations
& PNG_PACKSWAP
)
2405 for (i
= 0; i
< row_width
; i
++)
2409 value
= (*sp
>> shift
) & 0xf;
2410 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
2411 *dp
|= (png_byte
)(value
<< shift
);
2431 png_bytep sp
= png_ptr
->row_buf
+ 1;
2433 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
2435 png_uint_32 row_width
= png_ptr
->width
;
2439 for (i
= 0; i
< row_width
; i
++)
2443 png_memcpy(dp
, sp
, pixel_bytes
);
2459 #endif /* !PNG_HAVE_MMX_COMBINE_ROW */
2461 #ifdef PNG_READ_INTERLACING_SUPPORTED
2462 #ifndef PNG_HAVE_MMX_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
2463 /* OLD pre-1.0.9 interface:
2464 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2465 png_uint_32 transformations)
2468 png_do_read_interlace(png_structp png_ptr
)
2470 png_row_infop row_info
= &(png_ptr
->row_info
);
2471 png_bytep row
= png_ptr
->row_buf
+ 1;
2472 int pass
= png_ptr
->pass
;
2473 png_uint_32 transformations
= png_ptr
->transformations
;
2474 #ifdef PNG_USE_LOCAL_ARRAYS
2475 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2476 /* offset to next interlace block */
2477 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2480 png_debug(1,"in png_do_read_interlace (stock C version)\n");
2481 if (row
!= NULL
&& row_info
!= NULL
)
2483 png_uint_32 final_width
;
2485 final_width
= row_info
->width
* png_pass_inc
[pass
];
2487 switch (row_info
->pixel_depth
)
2491 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
2492 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
2494 int s_start
, s_end
, s_inc
;
2495 int jstop
= png_pass_inc
[pass
];
2500 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2501 if (transformations
& PNG_PACKSWAP
)
2503 sshift
= (int)((row_info
->width
+ 7) & 0x07);
2504 dshift
= (int)((final_width
+ 7) & 0x07);
2512 sshift
= 7 - (int)((row_info
->width
+ 7) & 0x07);
2513 dshift
= 7 - (int)((final_width
+ 7) & 0x07);
2519 for (i
= 0; i
< row_info
->width
; i
++)
2521 v
= (png_byte
)((*sp
>> sshift
) & 0x01);
2522 for (j
= 0; j
< jstop
; j
++)
2524 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
2525 *dp
|= (png_byte
)(v
<< dshift
);
2526 if (dshift
== s_end
)
2534 if (sshift
== s_end
)
2546 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
2547 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
2549 int s_start
, s_end
, s_inc
;
2550 int jstop
= png_pass_inc
[pass
];
2553 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2554 if (transformations
& PNG_PACKSWAP
)
2556 sshift
= (int)(((row_info
->width
+ 3) & 0x03) << 1);
2557 dshift
= (int)(((final_width
+ 3) & 0x03) << 1);
2565 sshift
= (int)((3 - ((row_info
->width
+ 3) & 0x03)) << 1);
2566 dshift
= (int)((3 - ((final_width
+ 3) & 0x03)) << 1);
2572 for (i
= 0; i
< row_info
->width
; i
++)
2577 v
= (png_byte
)((*sp
>> sshift
) & 0x03);
2578 for (j
= 0; j
< jstop
; j
++)
2580 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
2581 *dp
|= (png_byte
)(v
<< dshift
);
2582 if (dshift
== s_end
)
2590 if (sshift
== s_end
)
2602 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
2603 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
2605 int s_start
, s_end
, s_inc
;
2607 int jstop
= png_pass_inc
[pass
];
2609 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
2610 if (transformations
& PNG_PACKSWAP
)
2612 sshift
= (int)(((row_info
->width
+ 1) & 0x01) << 2);
2613 dshift
= (int)(((final_width
+ 1) & 0x01) << 2);
2621 sshift
= (int)((1 - ((row_info
->width
+ 1) & 0x01)) << 2);
2622 dshift
= (int)((1 - ((final_width
+ 1) & 0x01)) << 2);
2628 for (i
= 0; i
< row_info
->width
; i
++)
2630 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
2633 for (j
= 0; j
< jstop
; j
++)
2635 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
2636 *dp
|= (png_byte
)(v
<< dshift
);
2637 if (dshift
== s_end
)
2645 if (sshift
== s_end
)
2657 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
2658 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
2659 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
2661 int jstop
= png_pass_inc
[pass
];
2664 for (i
= 0; i
< row_info
->width
; i
++)
2669 png_memcpy(v
, sp
, pixel_bytes
);
2670 for (j
= 0; j
< jstop
; j
++)
2672 png_memcpy(dp
, v
, pixel_bytes
);
2680 row_info
->width
= final_width
;
2681 row_info
->rowbytes
= PNG_ROWBYTES(row_info
->pixel_depth
,final_width
);
2683 #if !defined(PNG_READ_PACKSWAP_SUPPORTED)
2684 if (&transformations
== NULL
) /* silence compiler warning */
2688 #endif /* !PNG_HAVE_MMX_READ_INTERLACE */
2689 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2691 #ifndef PNG_HAVE_MMX_READ_FILTER_ROW
2693 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
2694 png_bytep prev_row
, int filter
)
2696 png_debug(1, "in png_read_filter_row\n");
2697 png_debug2(2,"row = %lu, filter = %d\n", png_ptr
->row_number
, filter
);
2700 case PNG_FILTER_VALUE_NONE
:
2702 case PNG_FILTER_VALUE_SUB
:
2705 png_uint_32 istop
= row_info
->rowbytes
;
2706 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2707 png_bytep rp
= row
+ bpp
;
2710 for (i
= bpp
; i
< istop
; i
++)
2712 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
2717 case PNG_FILTER_VALUE_UP
:
2720 png_uint_32 istop
= row_info
->rowbytes
;
2722 png_bytep pp
= prev_row
;
2724 for (i
= 0; i
< istop
; i
++)
2726 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2731 case PNG_FILTER_VALUE_AVG
:
2735 png_bytep pp
= prev_row
;
2737 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2738 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
2740 for (i
= 0; i
< bpp
; i
++)
2742 *rp
= (png_byte
)(((int)(*rp
) +
2743 ((int)(*pp
++) / 2 )) & 0xff);
2747 for (i
= 0; i
< istop
; i
++)
2749 *rp
= (png_byte
)(((int)(*rp
) +
2750 (int)(*pp
++ + *lp
++) / 2 ) & 0xff);
2755 case PNG_FILTER_VALUE_PAETH
:
2759 png_bytep pp
= prev_row
;
2761 png_bytep cp
= prev_row
;
2762 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) >> 3;
2763 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
2765 for (i
= 0; i
< bpp
; i
++)
2767 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
2771 for (i
= 0; i
< istop
; i
++) /* use leftover rp,pp */
2773 int a
, b
, c
, pa
, pb
, pc
, p
;
2787 pa
= p
< 0 ? -p
: p
;
2788 pb
= pc
< 0 ? -pc
: pc
;
2789 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
2793 if (pa <= pb && pa <= pc)
2801 p
= (pa
<= pb
&& pa
<=pc
) ? a
: (pb
<= pc
) ? b
: c
;
2803 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2809 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2814 #endif /* !PNG_HAVE_MMX_READ_FILTER_ROW */
2817 png_read_finish_row(png_structp png_ptr
)
2819 #ifdef PNG_USE_LOCAL_ARRAYS
2820 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2822 /* start of interlace block */
2823 const int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2825 /* offset to next interlace block */
2826 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2828 /* start of interlace block in the y direction */
2829 const int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2831 /* offset to next interlace block in the y direction */
2832 const int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2835 png_debug(1, "in png_read_finish_row\n");
2836 png_ptr
->row_number
++;
2837 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2840 if (png_ptr
->interlaced
)
2842 png_ptr
->row_number
= 0;
2843 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2847 if (png_ptr
->pass
>= 7)
2849 png_ptr
->iwidth
= (png_ptr
->width
+
2850 png_pass_inc
[png_ptr
->pass
] - 1 -
2851 png_pass_start
[png_ptr
->pass
]) /
2852 png_pass_inc
[png_ptr
->pass
];
2854 png_ptr
->irowbytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,
2855 png_ptr
->iwidth
) + 1;
2857 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2859 png_ptr
->num_rows
= (png_ptr
->height
+
2860 png_pass_yinc
[png_ptr
->pass
] - 1 -
2861 png_pass_ystart
[png_ptr
->pass
]) /
2862 png_pass_yinc
[png_ptr
->pass
];
2863 if (!(png_ptr
->num_rows
))
2866 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2868 } while (png_ptr
->iwidth
== 0);
2870 if (png_ptr
->pass
< 7)
2874 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2876 #ifdef PNG_USE_LOCAL_ARRAYS
2882 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2883 png_ptr
->zstream
.avail_out
= (uInt
)1;
2886 if (!(png_ptr
->zstream
.avail_in
))
2888 while (!png_ptr
->idat_size
)
2890 png_byte chunk_length
[4];
2892 png_crc_finish(png_ptr
, 0);
2894 png_read_data(png_ptr
, chunk_length
, 4);
2895 png_ptr
->idat_size
= png_get_uint_31(png_ptr
, chunk_length
);
2896 png_reset_crc(png_ptr
);
2897 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2898 if (png_memcmp(png_ptr
->chunk_name
, (png_bytep
)png_IDAT
, 4))
2899 png_error(png_ptr
, "Not enough image data");
2902 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2903 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2904 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2905 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2906 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2907 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2909 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2910 if (ret
== Z_STREAM_END
)
2912 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2914 png_warning(png_ptr
, "Extra compressed data");
2915 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2916 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2920 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2921 "Decompression Error");
2923 if (!(png_ptr
->zstream
.avail_out
))
2925 png_warning(png_ptr
, "Extra compressed data.");
2926 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2927 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2932 png_ptr
->zstream
.avail_out
= 0;
2935 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
2936 png_warning(png_ptr
, "Extra compression data");
2938 inflateReset(&png_ptr
->zstream
);
2940 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2944 png_read_start_row(png_structp png_ptr
)
2946 #ifdef PNG_USE_LOCAL_ARRAYS
2947 /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2949 /* start of interlace block */
2950 const int png_pass_start
[7] = {0, 4, 0, 2, 0, 1, 0};
2952 /* offset to next interlace block */
2953 const int png_pass_inc
[7] = {8, 8, 4, 4, 2, 2, 1};
2955 /* start of interlace block in the y direction */
2956 const int png_pass_ystart
[7] = {0, 0, 4, 0, 2, 0, 1};
2958 /* offset to next interlace block in the y direction */
2959 const int png_pass_yinc
[7] = {8, 8, 8, 4, 4, 2, 2};
2962 int max_pixel_depth
;
2963 png_uint_32 row_bytes
;
2965 png_debug(1, "in png_read_start_row\n");
2966 png_ptr
->zstream
.avail_in
= 0;
2967 png_init_read_transformations(png_ptr
);
2968 if (png_ptr
->interlaced
)
2970 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2971 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
2972 png_pass_ystart
[0]) / png_pass_yinc
[0];
2974 png_ptr
->num_rows
= png_ptr
->height
;
2976 png_ptr
->iwidth
= (png_ptr
->width
+
2977 png_pass_inc
[png_ptr
->pass
] - 1 -
2978 png_pass_start
[png_ptr
->pass
]) /
2979 png_pass_inc
[png_ptr
->pass
];
2981 row_bytes
= PNG_ROWBYTES(png_ptr
->pixel_depth
,png_ptr
->iwidth
) + 1;
2983 png_ptr
->irowbytes
= (png_size_t
)row_bytes
;
2984 if((png_uint_32
)png_ptr
->irowbytes
!= row_bytes
)
2985 png_error(png_ptr
, "Rowbytes overflow in png_read_start_row");
2989 png_ptr
->num_rows
= png_ptr
->height
;
2990 png_ptr
->iwidth
= png_ptr
->width
;
2991 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
2993 max_pixel_depth
= png_ptr
->pixel_depth
;
2995 #if defined(PNG_READ_PACK_SUPPORTED)
2996 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
2997 max_pixel_depth
= 8;
3000 #if defined(PNG_READ_EXPAND_SUPPORTED)
3001 if (png_ptr
->transformations
& PNG_EXPAND
)
3003 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3005 if (png_ptr
->num_trans
)
3006 max_pixel_depth
= 32;
3008 max_pixel_depth
= 24;
3010 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3012 if (max_pixel_depth
< 8)
3013 max_pixel_depth
= 8;
3014 if (png_ptr
->num_trans
)
3015 max_pixel_depth
*= 2;
3017 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3019 if (png_ptr
->num_trans
)
3021 max_pixel_depth
*= 4;
3022 max_pixel_depth
/= 3;
3028 #if defined(PNG_READ_FILLER_SUPPORTED)
3029 if (png_ptr
->transformations
& (PNG_FILLER
))
3031 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
3032 max_pixel_depth
= 32;
3033 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
3035 if (max_pixel_depth
<= 8)
3036 max_pixel_depth
= 16;
3038 max_pixel_depth
= 32;
3040 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
3042 if (max_pixel_depth
<= 32)
3043 max_pixel_depth
= 32;
3045 max_pixel_depth
= 64;
3050 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
3051 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
3054 #if defined(PNG_READ_EXPAND_SUPPORTED)
3055 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
3057 #if defined(PNG_READ_FILLER_SUPPORTED)
3058 (png_ptr
->transformations
& (PNG_FILLER
)) ||
3060 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
3062 if (max_pixel_depth
<= 16)
3063 max_pixel_depth
= 32;
3065 max_pixel_depth
= 64;
3069 if (max_pixel_depth
<= 8)
3071 if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3072 max_pixel_depth
= 32;
3074 max_pixel_depth
= 24;
3076 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
3077 max_pixel_depth
= 64;
3079 max_pixel_depth
= 48;
3084 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3085 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3086 if(png_ptr
->transformations
& PNG_USER_TRANSFORM
)
3088 int user_pixel_depth
=png_ptr
->user_transform_depth
*
3089 png_ptr
->user_transform_channels
;
3090 if(user_pixel_depth
> max_pixel_depth
)
3091 max_pixel_depth
=user_pixel_depth
;
3095 /* align the width on the next larger 8 pixels. Mainly used
3097 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
3098 /* calculate the maximum bytes needed, adding a byte and a pixel
3099 for safety's sake */
3100 row_bytes
= PNG_ROWBYTES(max_pixel_depth
,row_bytes
) +
3101 1 + ((max_pixel_depth
+ 7) >> 3);
3102 #ifdef PNG_MAX_MALLOC_64K
3103 if (row_bytes
> (png_uint_32
)65536L)
3104 png_error(png_ptr
, "This image requires a row greater than 64KB");
3106 png_ptr
->big_row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
+64);
3107 png_ptr
->row_buf
= png_ptr
->big_row_buf
+32;
3108 #if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
3109 png_ptr
->row_buf_size
= row_bytes
;
3112 #ifdef PNG_MAX_MALLOC_64K
3113 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
3114 png_error(png_ptr
, "This image requires a row greater than 64KB");
3116 if ((png_uint_32
)png_ptr
->rowbytes
> (png_uint_32
)(PNG_SIZE_MAX
- 1))
3117 png_error(png_ptr
, "Row has too many bytes to allocate in memory.");
3118 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
3119 png_ptr
->rowbytes
+ 1));
3121 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
3123 png_debug1(3, "width = %lu,\n", png_ptr
->width
);
3124 png_debug1(3, "height = %lu,\n", png_ptr
->height
);
3125 png_debug1(3, "iwidth = %lu,\n", png_ptr
->iwidth
);
3126 png_debug1(3, "num_rows = %lu\n", png_ptr
->num_rows
);
3127 png_debug1(3, "rowbytes = %lu,\n", png_ptr
->rowbytes
);
3128 png_debug1(3, "irowbytes = %lu,\n", png_ptr
->irowbytes
);
3130 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;
3132 #endif /* PNG_READ_SUPPORTED */