2 /* pngrutil.c - utilities to read a PNG file
5 * For conditions of distribution and use, see copyright notice in png.h
6 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
7 * Copyright (c) 1996, 1997 Andreas Dilger
8 * Copyright (c) 1998, Glenn Randers-Pehrson
11 * This file contains routines which are only called from within
12 * libpng itself during the course of reading an image.
18 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
19 /* Grab an unsigned 32-bit integer from a buffer in big endian format. */
21 png_get_uint_32(png_bytep buf
)
25 i
= ((png_uint_32
)(*buf
) << 24) +
26 ((png_uint_32
)(*(buf
+ 1)) << 16) +
27 ((png_uint_32
)(*(buf
+ 2)) << 8) +
28 (png_uint_32
)(*(buf
+ 3));
33 #if defined(PNG_READ_pCAL_SUPPORTED)
34 /* Grab a signed 32-bit integer from a buffer in big endian format. The
35 * data is stored in the PNG file in two's complement format, and it is
36 * assumed that the machine format for signed integers is the same. */
38 png_get_int_32(png_bytep buf
)
42 i
= ((png_int_32
)(*buf
) << 24) +
43 ((png_int_32
)(*(buf
+ 1)) << 16) +
44 ((png_int_32
)(*(buf
+ 2)) << 8) +
45 (png_int_32
)(*(buf
+ 3));
49 #endif /* PNG_READ_pCAL_SUPPORTED */
51 /* Grab an unsigned 16-bit integer from a buffer in big endian format. */
53 png_get_uint_16(png_bytep buf
)
57 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
58 (png_uint_16
)(*(buf
+ 1)));
62 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
64 /* Read data, and (optionally) run it through the CRC. */
66 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
68 png_read_data(png_ptr
, buf
, length
);
69 png_calculate_crc(png_ptr
, buf
, length
);
72 /* Optionally skip data and then check the CRC. Depending on whether we
73 are reading a ancillary or critical chunk, and how the program has set
74 things up, we may calculate the CRC on the data and print a message.
75 Returns '1' if there was a CRC error, '0' otherwise. */
77 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
81 for (i
= skip
; i
> (png_uint_32
)png_ptr
->zbuf_size
; i
-= png_ptr
->zbuf_size
)
83 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
87 png_crc_read(png_ptr
, png_ptr
->zbuf
, (png_size_t
)i
);
90 if (png_crc_error(png_ptr
))
92 if ((png_ptr
->chunk_name
[0] & 0x20 && /* Ancillary */
93 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
94 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
95 png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
))
97 png_chunk_warning(png_ptr
, "CRC error");
101 png_chunk_error(png_ptr
, "CRC error");
109 /* Compare the CRC stored in the PNG file with that calculated by libpng from
110 the data it has read thus far. */
112 png_crc_error(png_structp png_ptr
)
114 png_byte crc_bytes
[4];
118 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
120 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
121 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
126 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
130 png_read_data(png_ptr
, crc_bytes
, 4);
134 crc
= png_get_uint_32(crc_bytes
);
135 return ((int)(crc
!= png_ptr
->crc
));
142 /* read and check the IDHR chunk */
144 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
147 png_uint_32 width
, height
;
148 int bit_depth
, color_type
, compression_type
, filter_type
;
151 png_debug(1, "in png_handle_IHDR\n");
153 if (png_ptr
->mode
!= PNG_BEFORE_IHDR
)
154 png_error(png_ptr
, "Out of place IHDR");
156 /* check the length */
158 png_error(png_ptr
, "Invalid IHDR chunk");
160 png_ptr
->mode
|= PNG_HAVE_IHDR
;
162 png_crc_read(png_ptr
, buf
, 13);
163 png_crc_finish(png_ptr
, 0);
165 width
= png_get_uint_32(buf
);
166 height
= png_get_uint_32(buf
+ 4);
169 compression_type
= buf
[10];
170 filter_type
= buf
[11];
171 interlace_type
= buf
[12];
173 /* check for width and height valid values */
174 if (width
== 0 || width
> (png_uint_32
)2147483647L || height
== 0 ||
175 height
> (png_uint_32
)2147483647L)
176 png_error(png_ptr
, "Invalid image size in IHDR");
178 /* check other values */
179 if (bit_depth
!= 1 && bit_depth
!= 2 && bit_depth
!= 4 &&
180 bit_depth
!= 8 && bit_depth
!= 16)
181 png_error(png_ptr
, "Invalid bit depth in IHDR");
183 if (color_type
< 0 || color_type
== 1 ||
184 color_type
== 5 || color_type
> 6)
185 png_error(png_ptr
, "Invalid color type in IHDR");
187 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& bit_depth
) > 8 ||
188 ((color_type
== PNG_COLOR_TYPE_RGB
||
189 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
||
190 color_type
== PNG_COLOR_TYPE_RGB_ALPHA
) && bit_depth
< 8))
191 png_error(png_ptr
, "Invalid color type/bit depth combination in IHDR");
193 if (interlace_type
>= PNG_INTERLACE_LAST
)
194 png_error(png_ptr
, "Unknown interlace method in IHDR");
196 if (compression_type
!= PNG_COMPRESSION_TYPE_BASE
)
197 png_error(png_ptr
, "Unknown compression method in IHDR");
199 if (filter_type
!= PNG_FILTER_TYPE_BASE
)
200 png_error(png_ptr
, "Unknown filter method in IHDR");
202 /* set internal variables */
203 png_ptr
->width
= width
;
204 png_ptr
->height
= height
;
205 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
206 png_ptr
->interlaced
= (png_byte
)interlace_type
;
207 png_ptr
->color_type
= (png_byte
)color_type
;
209 /* find number of channels */
210 switch (png_ptr
->color_type
)
212 case PNG_COLOR_TYPE_GRAY
:
213 case PNG_COLOR_TYPE_PALETTE
:
214 png_ptr
->channels
= 1;
216 case PNG_COLOR_TYPE_RGB
:
217 png_ptr
->channels
= 3;
219 case PNG_COLOR_TYPE_GRAY_ALPHA
:
220 png_ptr
->channels
= 2;
222 case PNG_COLOR_TYPE_RGB_ALPHA
:
223 png_ptr
->channels
= 4;
227 /* set up other useful info */
228 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
230 png_ptr
->rowbytes
= ((png_ptr
->width
*
231 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3);
232 png_debug1(3,"bit_depth = %d\n", png_ptr
->bit_depth
);
233 png_debug1(3,"channels = %d\n", png_ptr
->channels
);
234 png_debug1(3,"rowbytes = %d\n", png_ptr
->rowbytes
);
235 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
236 color_type
, interlace_type
, compression_type
, filter_type
);
239 /* read and check the palette */
241 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
246 png_debug(1, "in png_handle_PLTE\n");
248 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
249 png_error(png_ptr
, "Missing IHDR before PLTE");
250 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
252 png_warning(png_ptr
, "Invalid PLTE after IDAT");
253 png_crc_finish(png_ptr
, length
);
256 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
257 png_error(png_ptr
, "Duplicate PLTE chunk");
259 png_ptr
->mode
|= PNG_HAVE_PLTE
;
261 #if defined (PNG_READ_tRNS_SUPPORTED)
262 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
264 if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tRNS
)
266 if (png_ptr
->num_trans
> png_ptr
->num_palette
)
268 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
269 png_ptr
->num_trans
= png_ptr
->num_palette
;
275 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
276 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
278 png_crc_finish(png_ptr
, length
);
285 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
287 png_warning(png_ptr
, "Invalid palette chunk");
288 png_crc_finish(png_ptr
, length
);
293 png_error(png_ptr
, "Invalid palette chunk");
297 num
= (int)length
/ 3;
298 palette
= (png_colorp
)png_zalloc(png_ptr
, (uInt
)num
, sizeof (png_color
));
299 png_ptr
->flags
|= PNG_FLAG_FREE_PALETTE
;
300 for (i
= 0; i
< num
; i
++)
304 png_crc_read(png_ptr
, buf
, 3);
305 /* don't depend upon png_color being any order */
306 palette
[i
].red
= buf
[0];
307 palette
[i
].green
= buf
[1];
308 palette
[i
].blue
= buf
[2];
311 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
312 whatever the normal CRC configuration tells us. However, if we
313 have an RGB image, the PLTE can be considered ancillary, so
314 we will act as though it is. */
315 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
316 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
319 png_crc_finish(png_ptr
, 0);
321 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
322 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
324 /* If we don't want to use the data from an ancillary chunk,
325 we have two options: an error abort, or a warning and we
326 ignore the data in this chunk (which should be OK, since
327 it's considered ancillary for a RGB or RGBA image). */
328 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
330 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
332 png_chunk_error(png_ptr
, "CRC error");
336 png_chunk_warning(png_ptr
, "CRC error");
337 png_ptr
->flags
&= ~PNG_FLAG_FREE_PALETTE
;
338 png_zfree(png_ptr
, palette
);
342 /* Otherwise, we (optionally) emit a warning and use the chunk. */
343 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
345 png_chunk_warning(png_ptr
, "CRC error");
349 png_ptr
->palette
= palette
;
350 png_ptr
->num_palette
= (png_uint_16
)num
;
351 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
355 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
357 png_debug(1, "in png_handle_IEND\n");
359 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
361 png_error(png_ptr
, "No image in file");
363 /* to quiet compiler warnings about unused info_ptr */
364 if (info_ptr
== NULL
)
368 png_ptr
->mode
|= PNG_AFTER_IDAT
| PNG_HAVE_IEND
;
372 png_warning(png_ptr
, "Incorrect IEND chunk length");
374 png_crc_finish(png_ptr
, length
);
377 #if defined(PNG_READ_gAMA_SUPPORTED)
379 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
385 png_debug(1, "in png_handle_gAMA\n");
387 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
388 png_error(png_ptr
, "Missing IHDR before gAMA");
389 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
391 png_warning(png_ptr
, "Invalid gAMA after IDAT");
392 png_crc_finish(png_ptr
, length
);
395 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
396 /* Should be an error, but we can cope with it */
397 png_warning(png_ptr
, "Out of place gAMA chunk");
399 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_gAMA
400 #if defined(PNG_READ_sRGB_SUPPORTED)
401 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
405 png_warning(png_ptr
, "Duplicate gAMA chunk");
406 png_crc_finish(png_ptr
, length
);
412 png_warning(png_ptr
, "Incorrect gAMA chunk length");
413 png_crc_finish(png_ptr
, length
);
417 png_crc_read(png_ptr
, buf
, 4);
418 if (png_crc_finish(png_ptr
, 0))
421 igamma
= png_get_uint_32(buf
);
422 /* check for zero gamma */
426 #if defined(PNG_READ_sRGB_SUPPORTED)
427 if (info_ptr
->valid
& PNG_INFO_sRGB
)
428 if(igamma
!= (png_uint_32
)45000L)
431 "Ignoring incorrect gAMA value when sRGB is also present");
433 fprintf(stderr
, "igamma = %lu\n", igamma
);
437 #endif /* PNG_READ_sRGB_SUPPORTED */
439 file_gamma
= (float)igamma
/ (float)100000.0;
440 #ifdef PNG_READ_GAMMA_SUPPORTED
441 png_ptr
->gamma
= file_gamma
;
443 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
447 #if defined(PNG_READ_sBIT_SUPPORTED)
449 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
454 png_debug(1, "in png_handle_sBIT\n");
456 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
458 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
459 png_error(png_ptr
, "Missing IHDR before sBIT");
460 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
462 png_warning(png_ptr
, "Invalid sBIT after IDAT");
463 png_crc_finish(png_ptr
, length
);
466 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
468 /* Should be an error, but we can cope with it */
469 png_warning(png_ptr
, "Out of place sBIT chunk");
471 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_sBIT
)
473 png_warning(png_ptr
, "Duplicate sBIT chunk");
474 png_crc_finish(png_ptr
, length
);
478 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
481 truelen
= (png_size_t
)png_ptr
->channels
;
483 if (length
!= truelen
)
485 png_warning(png_ptr
, "Incorrect sBIT chunk length");
486 png_crc_finish(png_ptr
, length
);
490 png_crc_read(png_ptr
, buf
, truelen
);
491 if (png_crc_finish(png_ptr
, 0))
494 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
496 png_ptr
->sig_bit
.red
= buf
[0];
497 png_ptr
->sig_bit
.green
= buf
[1];
498 png_ptr
->sig_bit
.blue
= buf
[2];
499 png_ptr
->sig_bit
.alpha
= buf
[3];
503 png_ptr
->sig_bit
.gray
= buf
[0];
504 png_ptr
->sig_bit
.alpha
= buf
[1];
506 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
510 #if defined(PNG_READ_cHRM_SUPPORTED)
512 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
516 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
518 png_debug(1, "in png_handle_cHRM\n");
520 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
521 png_error(png_ptr
, "Missing IHDR before sBIT");
522 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
524 png_warning(png_ptr
, "Invalid cHRM after IDAT");
525 png_crc_finish(png_ptr
, length
);
528 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
529 /* Should be an error, but we can cope with it */
530 png_warning(png_ptr
, "Missing PLTE before cHRM");
532 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_cHRM
533 #if defined(PNG_READ_sRGB_SUPPORTED)
534 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
538 png_warning(png_ptr
, "Duplicate cHRM chunk");
539 png_crc_finish(png_ptr
, length
);
545 png_warning(png_ptr
, "Incorrect cHRM chunk length");
546 png_crc_finish(png_ptr
, length
);
550 png_crc_read(png_ptr
, buf
, 4);
551 val
= png_get_uint_32(buf
);
552 white_x
= (float)val
/ (float)100000.0;
554 png_crc_read(png_ptr
, buf
, 4);
555 val
= png_get_uint_32(buf
);
556 white_y
= (float)val
/ (float)100000.0;
558 if (white_x
< 0 || white_x
> 0.8 || white_y
< 0 || white_y
> 0.8 ||
559 white_x
+ white_y
> 1.0)
561 png_warning(png_ptr
, "Invalid cHRM white point");
562 png_crc_finish(png_ptr
, 24);
566 png_crc_read(png_ptr
, buf
, 4);
567 val
= png_get_uint_32(buf
);
568 red_x
= (float)val
/ (float)100000.0;
570 png_crc_read(png_ptr
, buf
, 4);
571 val
= png_get_uint_32(buf
);
572 red_y
= (float)val
/ (float)100000.0;
574 if (red_x
< 0 || red_x
> 0.8 || red_y
< 0 || red_y
> 0.8 ||
577 png_warning(png_ptr
, "Invalid cHRM red point");
578 png_crc_finish(png_ptr
, 16);
582 png_crc_read(png_ptr
, buf
, 4);
583 val
= png_get_uint_32(buf
);
584 green_x
= (float)val
/ (float)100000.0;
586 png_crc_read(png_ptr
, buf
, 4);
587 val
= png_get_uint_32(buf
);
588 green_y
= (float)val
/ (float)100000.0;
590 if (green_x
< 0 || green_x
> 0.8 || green_y
< 0 || green_y
> 0.8 ||
591 green_x
+ green_y
> 1.0)
593 png_warning(png_ptr
, "Invalid cHRM green point");
594 png_crc_finish(png_ptr
, 8);
598 png_crc_read(png_ptr
, buf
, 4);
599 val
= png_get_uint_32(buf
);
600 blue_x
= (float)val
/ (float)100000.0;
602 png_crc_read(png_ptr
, buf
, 4);
603 val
= png_get_uint_32(buf
);
604 blue_y
= (float)val
/ (float)100000.0;
606 if (blue_x
< (float)0 || blue_x
> (float)0.8 || blue_y
< (float)0 ||
607 blue_y
> (float)0.8 || blue_x
+ blue_y
> (float)1.0)
609 png_warning(png_ptr
, "Invalid cHRM blue point");
610 png_crc_finish(png_ptr
, 0);
614 if (png_crc_finish(png_ptr
, 0))
617 #if defined(PNG_READ_sRGB_SUPPORTED)
618 if (info_ptr
->valid
& PNG_INFO_sRGB
)
620 if (fabs(white_x
- (float).3127) > (float).001 ||
621 fabs(white_y
- (float).3290) > (float).001 ||
622 fabs( red_x
- (float).6400) > (float).001 ||
623 fabs( red_y
- (float).3300) > (float).001 ||
624 fabs(green_x
- (float).3000) > (float).001 ||
625 fabs(green_y
- (float).6000) > (float).001 ||
626 fabs( blue_x
- (float).1500) > (float).001 ||
627 fabs( blue_y
- (float).0600) > (float).001)
631 "Ignoring incorrect cHRM value when sRGB is also present");
633 fprintf(stderr
,"wx=%f, wy=%f, rx=%f, ry=%f\n",
634 white_x
, white_y
, red_x
, red_y
);
635 fprintf(stderr
,"gx=%f, gy=%f, bx=%f, by=%f\n",
636 green_x
, green_y
, blue_x
, blue_y
);
641 #endif /* PNG_READ_sRGB_SUPPORTED */
643 png_set_cHRM(png_ptr
, info_ptr
,
644 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
648 #if defined(PNG_READ_sRGB_SUPPORTED)
650 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
655 png_debug(1, "in png_handle_sRGB\n");
657 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
658 png_error(png_ptr
, "Missing IHDR before sRGB");
659 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
661 png_warning(png_ptr
, "Invalid sRGB after IDAT");
662 png_crc_finish(png_ptr
, length
);
665 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
666 /* Should be an error, but we can cope with it */
667 png_warning(png_ptr
, "Out of place sRGB chunk");
669 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_sRGB
)
671 png_warning(png_ptr
, "Duplicate sRGB chunk");
672 png_crc_finish(png_ptr
, length
);
678 png_warning(png_ptr
, "Incorrect sRGB chunk length");
679 png_crc_finish(png_ptr
, length
);
683 png_crc_read(png_ptr
, buf
, 1);
684 if (png_crc_finish(png_ptr
, 0))
688 /* check for bad intent */
689 if (intent
>= PNG_sRGB_INTENT_LAST
)
691 png_warning(png_ptr
, "Unknown sRGB intent");
695 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
696 if ((info_ptr
->valid
& PNG_INFO_gAMA
))
697 if((png_uint_32
)(png_ptr
->gamma
*(float)100000.+.5) != (png_uint_32
)45000L)
700 "Ignoring incorrect gAMA value when sRGB is also present");
702 fprintf(stderr
,"gamma=%f\n",png_ptr
->gamma
);
705 #endif /* PNG_READ_gAMA_SUPPORTED */
707 #ifdef PNG_READ_cHRM_SUPPORTED
708 if (info_ptr
->valid
& PNG_INFO_cHRM
)
709 if (fabs(info_ptr
->x_white
- (float).3127) > (float).001 ||
710 fabs(info_ptr
->y_white
- (float).3290) > (float).001 ||
711 fabs( info_ptr
->x_red
- (float).6400) > (float).001 ||
712 fabs( info_ptr
->y_red
- (float).3300) > (float).001 ||
713 fabs(info_ptr
->x_green
- (float).3000) > (float).001 ||
714 fabs(info_ptr
->y_green
- (float).6000) > (float).001 ||
715 fabs( info_ptr
->x_blue
- (float).1500) > (float).001 ||
716 fabs( info_ptr
->y_blue
- (float).0600) > (float).001)
719 "Ignoring incorrect cHRM value when sRGB is also present");
721 #endif /* PNG_READ_cHRM_SUPPORTED */
723 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
725 #endif /* PNG_READ_sRGB_SUPPORTED */
727 #if defined(PNG_READ_tRNS_SUPPORTED)
729 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
731 png_debug(1, "in png_handle_tRNS\n");
733 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
734 png_error(png_ptr
, "Missing IHDR before tRNS");
735 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
737 png_warning(png_ptr
, "Invalid tRNS after IDAT");
738 png_crc_finish(png_ptr
, length
);
741 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tRNS
)
743 png_warning(png_ptr
, "Duplicate tRNS chunk");
744 png_crc_finish(png_ptr
, length
);
748 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
750 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
752 /* Should be an error, but we can cope with it */
753 png_warning(png_ptr
, "Missing PLTE before tRNS");
755 else if (length
> png_ptr
->num_palette
)
757 png_warning(png_ptr
, "Incorrect tRNS chunk length");
758 png_crc_finish(png_ptr
, length
);
762 png_ptr
->trans
= (png_bytep
)png_malloc(png_ptr
, length
);
763 png_ptr
->flags
|= PNG_FLAG_FREE_TRANS
;
764 png_crc_read(png_ptr
, png_ptr
->trans
, (png_size_t
)length
);
765 png_ptr
->num_trans
= (png_uint_16
)length
;
767 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
773 png_warning(png_ptr
, "Incorrect tRNS chunk length");
774 png_crc_finish(png_ptr
, length
);
778 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
779 png_ptr
->num_trans
= 1;
780 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
781 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
782 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
784 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
790 png_warning(png_ptr
, "Incorrect tRNS chunk length");
791 png_crc_finish(png_ptr
, length
);
795 png_crc_read(png_ptr
, buf
, 2);
796 png_ptr
->num_trans
= 1;
797 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
801 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
802 png_crc_finish(png_ptr
, length
);
806 if (png_crc_finish(png_ptr
, 0))
809 png_set_tRNS(png_ptr
, info_ptr
, png_ptr
->trans
, png_ptr
->num_trans
,
810 &(png_ptr
->trans_values
));
814 #if defined(PNG_READ_bKGD_SUPPORTED)
816 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
821 png_debug(1, "in png_handle_bKGD\n");
823 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
824 png_error(png_ptr
, "Missing IHDR before bKGD");
825 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
827 png_warning(png_ptr
, "Invalid bKGD after IDAT");
828 png_crc_finish(png_ptr
, length
);
831 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
832 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
834 png_warning(png_ptr
, "Missing PLTE before bKGD");
835 png_crc_finish(png_ptr
, length
);
838 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_bKGD
)
840 png_warning(png_ptr
, "Duplicate bKGD chunk");
841 png_crc_finish(png_ptr
, length
);
845 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
847 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
852 if (length
!= truelen
)
854 png_warning(png_ptr
, "Incorrect bKGD chunk length");
855 png_crc_finish(png_ptr
, length
);
859 png_crc_read(png_ptr
, buf
, truelen
);
860 if (png_crc_finish(png_ptr
, 0))
863 /* We convert the index value into RGB components so that we can allow
864 * arbitrary RGB values for background when we have transparency, and
865 * so it is easy to determine the RGB values of the background color
866 * from the info_ptr struct. */
867 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
869 png_ptr
->background
.index
= buf
[0];
870 png_ptr
->background
.red
= (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
871 png_ptr
->background
.green
= (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
872 png_ptr
->background
.blue
= (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
874 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
876 png_ptr
->background
.red
=
877 png_ptr
->background
.green
=
878 png_ptr
->background
.blue
=
879 png_ptr
->background
.gray
= png_get_uint_16(buf
);
883 png_ptr
->background
.red
= png_get_uint_16(buf
);
884 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
885 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
888 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
892 #if defined(PNG_READ_hIST_SUPPORTED)
894 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
898 png_debug(1, "in png_handle_hIST\n");
900 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
901 png_error(png_ptr
, "Missing IHDR before hIST");
902 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
904 png_warning(png_ptr
, "Invalid hIST after IDAT");
905 png_crc_finish(png_ptr
, length
);
908 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
910 png_warning(png_ptr
, "Missing PLTE before hIST");
911 png_crc_finish(png_ptr
, length
);
914 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_hIST
)
916 png_warning(png_ptr
, "Duplicate hIST chunk");
917 png_crc_finish(png_ptr
, length
);
921 if (length
!= (png_uint_32
)(2 * png_ptr
->num_palette
))
923 png_warning(png_ptr
, "Incorrect hIST chunk length");
924 png_crc_finish(png_ptr
, length
);
928 num
= (int)length
/ 2;
929 png_ptr
->hist
= (png_uint_16p
)png_malloc(png_ptr
,
930 (png_uint_32
)(num
* sizeof (png_uint_16
)));
931 png_ptr
->flags
|= PNG_FLAG_FREE_HIST
;
932 for (i
= 0; i
< num
; i
++)
936 png_crc_read(png_ptr
, buf
, 2);
937 png_ptr
->hist
[i
] = png_get_uint_16(buf
);
940 if (png_crc_finish(png_ptr
, 0))
943 png_set_hIST(png_ptr
, info_ptr
, png_ptr
->hist
);
947 #if defined(PNG_READ_pHYs_SUPPORTED)
949 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
952 png_uint_32 res_x
, res_y
;
955 png_debug(1, "in png_handle_pHYs\n");
957 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
958 png_error(png_ptr
, "Missing IHDR before pHYS");
959 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
961 png_warning(png_ptr
, "Invalid pHYS after IDAT");
962 png_crc_finish(png_ptr
, length
);
965 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_pHYs
)
967 png_warning(png_ptr
, "Duplicate pHYS chunk");
968 png_crc_finish(png_ptr
, length
);
974 png_warning(png_ptr
, "Incorrect pHYs chunk length");
975 png_crc_finish(png_ptr
, length
);
979 png_crc_read(png_ptr
, buf
, 9);
980 if (png_crc_finish(png_ptr
, 0))
983 res_x
= png_get_uint_32(buf
);
984 res_y
= png_get_uint_32(buf
+ 4);
986 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
990 #if defined(PNG_READ_oFFs_SUPPORTED)
992 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
995 png_uint_32 offset_x
, offset_y
;
998 png_debug(1, "in png_handle_oFFs\n");
1000 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1001 png_error(png_ptr
, "Missing IHDR before oFFs");
1002 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1004 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1005 png_crc_finish(png_ptr
, length
);
1008 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_oFFs
)
1010 png_warning(png_ptr
, "Duplicate oFFs chunk");
1011 png_crc_finish(png_ptr
, length
);
1017 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1018 png_crc_finish(png_ptr
, length
);
1022 png_crc_read(png_ptr
, buf
, 9);
1023 if (png_crc_finish(png_ptr
, 0))
1026 offset_x
= png_get_uint_32(buf
);
1027 offset_y
= png_get_uint_32(buf
+ 4);
1029 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1033 #if defined(PNG_READ_pCAL_SUPPORTED)
1034 /* read the pCAL chunk (png-scivis-19970203) */
1036 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1040 png_byte type
, nparams
;
1041 png_charp buf
, units
, endptr
;
1046 png_debug(1, "in png_handle_pCAL\n");
1048 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1049 png_error(png_ptr
, "Missing IHDR before pCAL");
1050 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1052 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1053 png_crc_finish(png_ptr
, length
);
1056 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_pCAL
)
1058 png_warning(png_ptr
, "Duplicate pCAL chunk");
1059 png_crc_finish(png_ptr
, length
);
1063 png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
1065 purpose
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1066 slength
= (png_size_t
)length
;
1067 png_crc_read(png_ptr
, (png_bytep
)purpose
, slength
);
1069 if (png_crc_finish(png_ptr
, 0))
1071 png_free(png_ptr
, purpose
);
1075 purpose
[slength
] = 0x00; /* null terminate the last string */
1077 png_debug(3, "Finding end of pCAL purpose string\n");
1078 for (buf
= purpose
; *buf
!= '\0'; buf
++)
1081 endptr
= purpose
+ slength
;
1083 /* We need to have at least 12 bytes after the purpose string
1084 in order to get the parameter information. */
1085 if (endptr
<= buf
+ 12)
1087 png_warning(png_ptr
, "Invalid pCAL data");
1088 png_free(png_ptr
, purpose
);
1092 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1093 X0
= png_get_int_32((png_bytep
)buf
+1);
1094 X1
= png_get_int_32((png_bytep
)buf
+5);
1099 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1100 /* Check that we have the right number of parameters for known
1102 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1103 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1104 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1105 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1107 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1108 png_free(png_ptr
, purpose
);
1111 else if (type
>= PNG_EQUATION_LAST
)
1113 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1116 for (buf
= units
; *buf
!= 0x00; buf
++)
1117 /* Empty loop to move past the units string. */ ;
1119 png_debug(3, "Allocating pCAL parameters array\n");
1120 params
= (png_charpp
)png_malloc(png_ptr
, (png_uint_32
)(nparams
1121 *sizeof(png_charp
))) ;
1123 /* Get pointers to the start of each parameter string. */
1124 for (i
= 0; i
< (int)nparams
; i
++)
1126 buf
++; /* Skip the null string terminator from previous parameter. */
1128 png_debug1(3, "Reading pCAL parameter %d\n", i
);
1129 for (params
[i
] = buf
; *buf
!= 0x00 && buf
<= endptr
; buf
++)
1130 /* Empty loop to move past each parameter string */ ;
1132 /* Make sure we haven't run out of data yet */
1135 png_warning(png_ptr
, "Invalid pCAL data");
1136 png_free(png_ptr
, purpose
);
1137 png_free(png_ptr
, params
);
1142 png_set_pCAL(png_ptr
, info_ptr
, purpose
, X0
, X1
, type
, nparams
,
1145 png_free(png_ptr
, purpose
);
1146 png_free(png_ptr
, params
);
1150 #if defined(PNG_READ_tIME_SUPPORTED)
1152 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1157 png_debug(1, "in png_handle_tIME\n");
1159 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1160 png_error(png_ptr
, "Out of place tIME chunk");
1161 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tIME
)
1163 png_warning(png_ptr
, "Duplicate tIME chunk");
1164 png_crc_finish(png_ptr
, length
);
1168 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1169 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1173 png_warning(png_ptr
, "Incorrect tIME chunk length");
1174 png_crc_finish(png_ptr
, length
);
1178 png_crc_read(png_ptr
, buf
, 7);
1179 if (png_crc_finish(png_ptr
, 0))
1182 mod_time
.second
= buf
[6];
1183 mod_time
.minute
= buf
[5];
1184 mod_time
.hour
= buf
[4];
1185 mod_time
.day
= buf
[3];
1186 mod_time
.month
= buf
[2];
1187 mod_time
.year
= png_get_uint_16(buf
);
1189 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1193 #if defined(PNG_READ_tEXt_SUPPORTED)
1194 /* Note: this does not properly handle chunks that are > 64K under DOS */
1196 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1201 png_uint_32 skip
= 0;
1204 png_debug(1, "in png_handle_tEXt\n");
1206 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1207 png_error(png_ptr
, "Missing IHDR before tEXt");
1209 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1210 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1212 #ifdef PNG_MAX_MALLOC_64K
1213 if (length
> (png_uint_32
)65535L)
1215 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1216 skip
= length
- (png_uint_32
)65535L;
1217 length
= (png_uint_32
)65535L;
1221 key
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1222 slength
= (png_size_t
)length
;
1223 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1225 if (png_crc_finish(png_ptr
, skip
))
1227 png_free(png_ptr
, key
);
1231 key
[slength
] = 0x00;
1233 for (text
= key
; *text
; text
++)
1234 /* empty loop to find end of key */ ;
1236 if (text
!= key
+ slength
)
1239 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1240 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1241 text_ptr
->key
= key
;
1242 text_ptr
->text
= text
;
1244 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1246 png_free(png_ptr
, text_ptr
);
1250 #if defined(PNG_READ_zTXt_SUPPORTED)
1251 /* note: this does not correctly handle chunks that are > 64K under DOS */
1253 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1255 static char msg
[] = "Error decoding zTXt chunk";
1259 int comp_type
= PNG_TEXT_COMPRESSION_NONE
;
1262 png_debug(1, "in png_handle_zTXt\n");
1264 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1265 png_error(png_ptr
, "Missing IHDR before zTXt");
1267 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1268 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1270 #ifdef PNG_MAX_MALLOC_64K
1271 /* We will no doubt have problems with chunks even half this size, but
1272 there is no hard and fast rule to tell us where to stop. */
1273 if (length
> (png_uint_32
)65535L)
1275 png_warning(png_ptr
,"zTXt chunk too large to fit in memory");
1276 png_crc_finish(png_ptr
, length
);
1281 key
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1282 slength
= (png_size_t
)length
;
1283 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1284 if (png_crc_finish(png_ptr
, 0))
1286 png_free(png_ptr
, key
);
1290 key
[slength
] = 0x00;
1292 for (text
= key
; *text
; text
++)
1295 /* zTXt must have some text after the keyword */
1296 if (text
== key
+ slength
)
1298 png_warning(png_ptr
, "Zero length zTXt chunk");
1300 else if ((comp_type
= *(++text
)) == PNG_TEXT_COMPRESSION_zTXt
)
1302 png_size_t text_size
, key_size
;
1305 png_ptr
->zstream
.next_in
= (png_bytep
)text
;
1306 png_ptr
->zstream
.avail_in
= (uInt
)(length
- (text
- key
));
1307 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
1308 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
1310 key_size
= (png_size_t
)(text
- key
);
1314 while (png_ptr
->zstream
.avail_in
)
1318 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
1319 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
1321 if (png_ptr
->zstream
.msg
!= NULL
)
1322 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
1324 png_warning(png_ptr
, msg
);
1325 inflateReset(&png_ptr
->zstream
);
1326 png_ptr
->zstream
.avail_in
= 0;
1330 text_size
= key_size
+ sizeof(msg
) + 1;
1331 text
= (png_charp
)png_malloc(png_ptr
, (png_uint_32
)text_size
);
1332 png_memcpy(text
, key
, key_size
);
1335 text
[text_size
- 1] = 0x00;
1337 /* Copy what we can of the error message into the text chunk */
1338 text_size
= (png_size_t
)(slength
- (text
- key
) - 1);
1339 text_size
= sizeof(msg
) > text_size
? text_size
: sizeof(msg
);
1340 png_memcpy(text
+ key_size
, msg
, text_size
+ 1);
1343 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
1347 text
= (png_charp
)png_malloc(png_ptr
,
1348 (png_uint_32
)(png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
1350 png_memcpy(text
+ key_size
, png_ptr
->zbuf
,
1351 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
);
1352 png_memcpy(text
, key
, key_size
);
1353 text_size
= key_size
+ png_ptr
->zbuf_size
-
1354 png_ptr
->zstream
.avail_out
;
1355 *(text
+ text_size
) = 0x00;
1362 text
= (png_charp
)png_malloc(png_ptr
, (png_uint_32
)(text_size
+
1363 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
1364 png_memcpy(text
, tmp
, text_size
);
1365 png_free(png_ptr
, tmp
);
1366 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
1367 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
1368 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
1369 *(text
+ text_size
) = 0x00;
1371 if (ret
!= Z_STREAM_END
)
1373 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
1374 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
1383 inflateReset(&png_ptr
->zstream
);
1384 png_ptr
->zstream
.avail_in
= 0;
1386 png_free(png_ptr
, key
);
1390 else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
1392 png_size_t text_size
;
1393 #if !defined(PNG_NO_STDIO)
1396 sprintf(umsg
, "Unknown zTXt compression type %d", comp_type
);
1397 png_warning(png_ptr
, umsg
);
1399 png_warning(png_ptr
, "Unknown zTXt compression type");
1402 /* Copy what we can of the error message into the text chunk */
1403 text_size
= (png_size_t
)(slength
- (text
- key
) - 1);
1404 text_size
= sizeof(msg
) > text_size
? text_size
: sizeof(msg
);
1405 png_memcpy(text
, msg
, text_size
+ 1);
1408 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1409 text_ptr
->compression
= comp_type
;
1410 text_ptr
->key
= key
;
1411 text_ptr
->text
= text
;
1413 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1415 png_free(png_ptr
, text_ptr
);
1419 /* This function is called when we haven't found a handler for a
1420 chunk. If there isn't a problem with the chunk itself (ie bad
1421 chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
1423 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1425 png_debug(1, "in png_handle_unknown\n");
1427 /* In the future we can have code here that calls user-supplied
1428 * callback functions for unknown chunks before they are ignored or
1431 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
1433 if (!(png_ptr
->chunk_name
[0] & 0x20))
1435 png_chunk_error(png_ptr
, "unknown critical chunk");
1437 /* to quiet compiler warnings about unused info_ptr */
1438 if (info_ptr
== NULL
)
1442 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1443 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1445 png_crc_finish(png_ptr
, length
);
1449 /* This function is called to verify that a chunk name is valid.
1450 This function can't have the "critical chunk check" incorporated
1451 into it, since in the future we will need to be able to call user
1452 functions to handle unknown critical chunks after we check that
1453 the chunk name itself is valid. */
1455 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
1458 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
1460 png_debug(1, "in png_check_chunk_name\n");
1461 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
1462 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
1464 png_chunk_error(png_ptr
, "invalid chunk type");
1468 /* Combines the row recently read in with the previous row.
1469 This routine takes care of alpha and transparency if requested.
1470 This routine also handles the two methods of progressive display
1471 of interlaced images, depending on the mask value.
1472 The mask value describes which pixels are to be combined with
1473 the row. The pattern always repeats every 8 pixels, so just 8
1474 bits are needed. A one indicates the pixels is to be combined,
1475 a zero indicates the pixel is to be skipped. This is in addition
1476 to any alpha or transparency value associated with the pixel. If
1477 you want all pixels to be combined, pass 0xff (255) in mask. */
1479 png_combine_row(png_structp png_ptr
, png_bytep row
,
1482 png_debug(1,"in png_combine_row\n");
1485 png_memcpy(row
, png_ptr
->row_buf
+ 1,
1486 (png_size_t
)((png_ptr
->width
*
1487 png_ptr
->row_info
.pixel_depth
+ 7) >> 3));
1491 switch (png_ptr
->row_info
.pixel_depth
)
1497 int s_inc
, s_start
, s_end
;
1502 sp
= png_ptr
->row_buf
+ 1;
1505 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1506 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1522 for (i
= 0; i
< png_ptr
->width
; i
++)
1528 value
= (*sp
>> shift
) & 0x1;
1529 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
1530 *dp
|= (png_byte
)(value
<< shift
);
1553 int s_start
, s_end
, s_inc
;
1559 sp
= png_ptr
->row_buf
+ 1;
1562 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1563 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1579 for (i
= 0; i
< png_ptr
->width
; i
++)
1583 value
= (*sp
>> shift
) & 0x3;
1584 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
1585 *dp
|= (png_byte
)(value
<< shift
);
1607 int s_start
, s_end
, s_inc
;
1613 sp
= png_ptr
->row_buf
+ 1;
1616 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1617 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1632 for (i
= 0; i
< png_ptr
->width
; i
++)
1636 value
= (*sp
>> shift
) & 0xf;
1637 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
1638 *dp
|= (png_byte
)(value
<< shift
);
1660 png_size_t pixel_bytes
;
1664 pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
1666 sp
= png_ptr
->row_buf
+ 1;
1669 for (i
= 0; i
< png_ptr
->width
; i
++)
1673 png_memcpy(dp
, sp
, pixel_bytes
);
1690 #if defined(PNG_READ_INTERLACING_SUPPORTED)
1692 png_do_read_interlace(png_row_infop row_info
, png_bytep row
, int pass
,
1693 png_uint_32 transformations
)
1695 png_debug(1,"in png_do_read_interlace\n");
1696 if (row
!= NULL
&& row_info
!= NULL
)
1698 png_uint_32 final_width
;
1700 final_width
= row_info
->width
* png_pass_inc
[pass
];
1702 switch (row_info
->pixel_depth
)
1708 int s_start
, s_end
, s_inc
;
1713 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
1714 dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
1715 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1716 if (transformations
& PNG_PACKSWAP
)
1718 sshift
= (int)((row_info
->width
+ 7) & 7);
1719 dshift
= (int)((final_width
+ 7) & 7);
1727 sshift
= 7 - (int)((row_info
->width
+ 7) & 7);
1728 dshift
= 7 - (int)((final_width
+ 7) & 7);
1734 for (i
= row_info
->width
; i
; i
--)
1736 v
= (png_byte
)((*sp
>> sshift
) & 0x1);
1737 for (j
= 0; j
< png_pass_inc
[pass
]; j
++)
1739 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
1740 *dp
|= (png_byte
)(v
<< dshift
);
1741 if (dshift
== s_end
)
1749 if (sshift
== s_end
)
1763 int s_start
, s_end
, s_inc
;
1766 sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
1767 dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
1768 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1769 if (transformations
& PNG_PACKSWAP
)
1771 sshift
= (int)(((row_info
->width
+ 3) & 3) << 1);
1772 dshift
= (int)(((final_width
+ 3) & 3) << 1);
1780 sshift
= (int)((3 - ((row_info
->width
+ 3) & 3)) << 1);
1781 dshift
= (int)((3 - ((final_width
+ 3) & 3)) << 1);
1787 for (i
= row_info
->width
; i
; i
--)
1792 v
= (png_byte
)((*sp
>> sshift
) & 0x3);
1793 for (j
= 0; j
< png_pass_inc
[pass
]; j
++)
1795 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
1796 *dp
|= (png_byte
)(v
<< dshift
);
1797 if (dshift
== s_end
)
1805 if (sshift
== s_end
)
1819 int s_start
, s_end
, s_inc
;
1822 sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
1823 dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
1824 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1825 if (transformations
& PNG_PACKSWAP
)
1827 sshift
= (int)(((row_info
->width
+ 1) & 1) << 2);
1828 dshift
= (int)(((final_width
+ 1) & 1) << 2);
1836 sshift
= (int)((1 - ((row_info
->width
+ 1) & 1)) << 2);
1837 dshift
= (int)((1 - ((final_width
+ 1) & 1)) << 2);
1843 for (i
= row_info
->width
; i
; i
--)
1848 v
= (png_byte
)((*sp
>> sshift
) & 0xf);
1849 for (j
= 0; j
< png_pass_inc
[pass
]; j
++)
1851 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
1852 *dp
|= (png_byte
)(v
<< dshift
);
1853 if (dshift
== s_end
)
1861 if (sshift
== s_end
)
1875 png_size_t pixel_bytes
;
1877 pixel_bytes
= (row_info
->pixel_depth
>> 3);
1879 sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
1880 dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
1881 for (i
= row_info
->width
; i
; i
--)
1886 png_memcpy(v
, sp
, pixel_bytes
);
1887 for (j
= 0; j
< png_pass_inc
[pass
]; j
++)
1889 png_memcpy(dp
, v
, pixel_bytes
);
1897 row_info
->width
= final_width
;
1898 row_info
->rowbytes
= ((final_width
*
1899 (png_uint_32
)row_info
->pixel_depth
+ 7) >> 3);
1905 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
1906 png_bytep prev_row
, int filter
)
1908 png_debug(1, "in png_read_filter_row\n");
1909 png_debug2(2,"row = %d, filter = %d\n", png_ptr
->row_number
, filter
);
1914 case PNG_FILTER_VALUE_NONE
:
1916 case PNG_FILTER_VALUE_SUB
:
1923 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1924 for (i
= (png_uint_32
)bpp
, rp
= row
+ bpp
, lp
= row
;
1925 i
< row_info
->rowbytes
; i
++, rp
++, lp
++)
1927 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
)) & 0xff);
1931 case PNG_FILTER_VALUE_UP
:
1937 for (i
= 0, rp
= row
, pp
= prev_row
;
1938 i
< row_info
->rowbytes
; i
++, rp
++, pp
++)
1940 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
)) & 0xff);
1944 case PNG_FILTER_VALUE_AVG
:
1952 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1953 for (i
= 0, rp
= row
, pp
= prev_row
;
1954 i
< (png_uint_32
)bpp
; i
++, rp
++, pp
++)
1956 *rp
= (png_byte
)(((int)(*rp
) +
1957 ((int)(*pp
) / 2)) & 0xff);
1959 for (lp
= row
; i
< row_info
->rowbytes
; i
++, rp
++, lp
++, pp
++)
1961 *rp
= (png_byte
)(((int)(*rp
) +
1962 (int)(*pp
+ *lp
) / 2) & 0xff);
1966 case PNG_FILTER_VALUE_PAETH
:
1975 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1976 for (i
= 0, rp
= row
, pp
= prev_row
,
1977 lp
= row
- bpp
, cp
= prev_row
- bpp
;
1978 i
< row_info
->rowbytes
; i
++, rp
++, pp
++, lp
++, cp
++)
1980 int a
, b
, c
, pa
, pb
, pc
, p
;
1983 if (i
>= (png_uint_32
)bpp
)
1997 if (pa
<= pb
&& pa
<= pc
)
2004 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2009 png_error(png_ptr
, "Bad adaptive filter type");
2015 png_read_finish_row(png_structp png_ptr
)
2017 png_debug(1, "in png_read_finish_row\n");
2018 png_ptr
->row_number
++;
2019 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2022 if (png_ptr
->interlaced
)
2024 png_ptr
->row_number
= 0;
2025 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2029 if (png_ptr
->pass
>= 7)
2031 png_ptr
->iwidth
= (png_ptr
->width
+
2032 png_pass_inc
[png_ptr
->pass
] - 1 -
2033 png_pass_start
[png_ptr
->pass
]) /
2034 png_pass_inc
[png_ptr
->pass
];
2035 png_ptr
->irowbytes
= ((png_ptr
->iwidth
*
2036 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2038 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2040 png_ptr
->num_rows
= (png_ptr
->height
+
2041 png_pass_yinc
[png_ptr
->pass
] - 1 -
2042 png_pass_ystart
[png_ptr
->pass
]) /
2043 png_pass_yinc
[png_ptr
->pass
];
2044 if (!(png_ptr
->num_rows
))
2047 if (png_ptr
->transformations
& PNG_INTERLACE
)
2049 } while (png_ptr
->iwidth
== 0);
2051 if (png_ptr
->pass
< 7)
2055 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2060 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2061 png_ptr
->zstream
.avail_out
= (uInt
)1;
2064 if (!(png_ptr
->zstream
.avail_in
))
2066 while (!png_ptr
->idat_size
)
2068 png_byte chunk_length
[4];
2070 png_crc_finish(png_ptr
, 0);
2072 png_read_data(png_ptr
, chunk_length
, 4);
2073 png_ptr
->idat_size
= png_get_uint_32(chunk_length
);
2075 png_reset_crc(png_ptr
);
2076 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2077 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4))
2078 png_error(png_ptr
, "Not enough image data");
2081 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2082 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2083 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2084 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2085 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2086 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2088 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2089 if (ret
== Z_STREAM_END
)
2091 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2093 png_error(png_ptr
, "Extra compressed data");
2094 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2095 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2099 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2100 "Decompression Error");
2102 if (!(png_ptr
->zstream
.avail_out
))
2103 png_error(png_ptr
, "Extra compressed data");
2106 png_ptr
->zstream
.avail_out
= 0;
2109 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
2110 png_error(png_ptr
, "Extra compression data");
2112 inflateReset(&png_ptr
->zstream
);
2114 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2118 png_read_start_row(png_structp png_ptr
)
2120 int max_pixel_depth
;
2121 png_uint_32 rowbytes
;
2123 png_debug(1, "in png_read_start_row\n");
2124 png_ptr
->zstream
.avail_in
= 0;
2125 png_init_read_transformations(png_ptr
);
2126 if (png_ptr
->interlaced
)
2128 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2129 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
2130 png_pass_ystart
[0]) / png_pass_yinc
[0];
2132 png_ptr
->num_rows
= png_ptr
->height
;
2134 png_ptr
->iwidth
= (png_ptr
->width
+
2135 png_pass_inc
[png_ptr
->pass
] - 1 -
2136 png_pass_start
[png_ptr
->pass
]) /
2137 png_pass_inc
[png_ptr
->pass
];
2139 rowbytes
= ((png_ptr
->iwidth
*
2140 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2141 png_ptr
->irowbytes
= (png_size_t
)rowbytes
;
2142 if((png_uint_32
)png_ptr
->irowbytes
!= rowbytes
)
2143 png_error(png_ptr
, "Rowbytes overflow in png_read_start_row");
2147 png_ptr
->num_rows
= png_ptr
->height
;
2148 png_ptr
->iwidth
= png_ptr
->width
;
2149 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
2151 max_pixel_depth
= png_ptr
->pixel_depth
;
2153 #if defined(PNG_READ_PACK_SUPPORTED)
2154 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
2155 max_pixel_depth
= 8;
2158 #if defined(PNG_READ_EXPAND_SUPPORTED)
2159 if (png_ptr
->transformations
& PNG_EXPAND
)
2161 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2163 if (png_ptr
->num_trans
)
2164 max_pixel_depth
= 32;
2166 max_pixel_depth
= 24;
2168 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
2170 if (max_pixel_depth
< 8)
2171 max_pixel_depth
= 8;
2172 if (png_ptr
->num_trans
)
2173 max_pixel_depth
*= 2;
2175 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
2177 if (png_ptr
->num_trans
)
2179 max_pixel_depth
*= 4;
2180 max_pixel_depth
/= 3;
2186 #if defined(PNG_READ_FILLER_SUPPORTED)
2187 if (png_ptr
->transformations
& (PNG_FILLER
))
2189 if (max_pixel_depth
< 32)
2190 max_pixel_depth
= 32;
2194 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2195 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
2197 if ((png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
2198 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2200 if (max_pixel_depth
<= 16)
2201 max_pixel_depth
= 32;
2202 else if (max_pixel_depth
<= 32)
2203 max_pixel_depth
= 64;
2207 if (max_pixel_depth
<= 8)
2208 max_pixel_depth
= 24;
2209 else if (max_pixel_depth
<= 16)
2210 max_pixel_depth
= 48;
2215 /* align the width on the next larger 8 pixels. Mainly used
2217 rowbytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
2218 /* calculate the maximum bytes needed, adding a byte and a pixel
2220 rowbytes
= ((rowbytes
* (png_uint_32
)max_pixel_depth
+ 7) >> 3) +
2221 1 + ((max_pixel_depth
+ 7) >> 3);
2222 #ifdef PNG_MAX_MALLOC_64K
2223 if (rowbytes
> (png_uint_32
)65536L)
2224 png_error(png_ptr
, "This image requires a row greater than 64KB");
2226 png_ptr
->row_buf
= (png_bytep
)png_malloc(png_ptr
, rowbytes
);
2228 #ifdef PNG_MAX_MALLOC_64K
2229 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
2230 png_error(png_ptr
, "This image requires a row greater than 64KB");
2232 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
2233 png_ptr
->rowbytes
+ 1));
2235 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2237 png_debug1(3, "width = %d,\n", png_ptr
->width
);
2238 png_debug1(3, "height = %d,\n", png_ptr
->height
);
2239 png_debug1(3, "iwidth = %d,\n", png_ptr
->iwidth
);
2240 png_debug1(3, "num_rows = %d\n", png_ptr
->num_rows
);
2241 png_debug1(3, "rowbytes = %d,\n", png_ptr
->rowbytes
);
2242 png_debug1(3, "irowbytes = %d,\n", png_ptr
->irowbytes
);
2244 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;