2 /* pngrutil.c - utilities to read a PNG file
4 * libpng 1.0.3 - January 14, 1999
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, 1999 Glenn Randers-Pehrson
10 * This file contains routines that are only called from within
11 * libpng itself during the course of reading an image.
17 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
18 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
20 png_get_uint_32(png_bytep buf
)
22 png_uint_32 i
= ((png_uint_32
)(*buf
) << 24) +
23 ((png_uint_32
)(*(buf
+ 1)) << 16) +
24 ((png_uint_32
)(*(buf
+ 2)) << 8) +
25 (png_uint_32
)(*(buf
+ 3));
30 #if defined(PNG_READ_pCAL_SUPPORTED)
31 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
32 * data is stored in the PNG file in two's complement format, and it is
33 * assumed that the machine format for signed integers is the same. */
35 png_get_int_32(png_bytep buf
)
37 png_int_32 i
= ((png_int_32
)(*buf
) << 24) +
38 ((png_int_32
)(*(buf
+ 1)) << 16) +
39 ((png_int_32
)(*(buf
+ 2)) << 8) +
40 (png_int_32
)(*(buf
+ 3));
44 #endif /* PNG_READ_pCAL_SUPPORTED */
46 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
48 png_get_uint_16(png_bytep buf
)
50 png_uint_16 i
= (png_uint_16
)(((png_uint_16
)(*buf
) << 8) +
51 (png_uint_16
)(*(buf
+ 1)));
55 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
57 /* Read data, and (optionally) run it through the CRC. */
59 png_crc_read(png_structp png_ptr
, png_bytep buf
, png_size_t length
)
61 png_read_data(png_ptr
, buf
, length
);
62 png_calculate_crc(png_ptr
, buf
, length
);
65 /* Optionally skip data and then check the CRC. Depending on whether we
66 are reading a ancillary or critical chunk, and how the program has set
67 things up, we may calculate the CRC on the data and print a message.
68 Returns '1' if there was a CRC error, '0' otherwise. */
70 png_crc_finish(png_structp png_ptr
, png_uint_32 skip
)
73 png_size_t istop
= png_ptr
->zbuf_size
;
75 for (i
= (png_size_t
)skip
; i
> istop
; i
-= istop
)
77 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zbuf_size
);
81 png_crc_read(png_ptr
, png_ptr
->zbuf
, i
);
84 if (png_crc_error(png_ptr
))
86 if ((png_ptr
->chunk_name
[0] & 0x20 && /* Ancillary */
87 !(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)) ||
88 (!(png_ptr
->chunk_name
[0] & 0x20) && /* Critical */
89 png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_USE
))
91 png_chunk_warning(png_ptr
, "CRC error");
95 png_chunk_error(png_ptr
, "CRC error");
103 /* Compare the CRC stored in the PNG file with that calculated by libpng from
104 the data it has read thus far. */
106 png_crc_error(png_structp png_ptr
)
108 png_byte crc_bytes
[4];
112 if (png_ptr
->chunk_name
[0] & 0x20) /* ancillary */
114 if ((png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_MASK
) ==
115 (PNG_FLAG_CRC_ANCILLARY_USE
| PNG_FLAG_CRC_ANCILLARY_NOWARN
))
120 if (png_ptr
->flags
& PNG_FLAG_CRC_CRITICAL_IGNORE
)
124 png_read_data(png_ptr
, crc_bytes
, 4);
128 crc
= png_get_uint_32(crc_bytes
);
129 return ((int)(crc
!= png_ptr
->crc
));
136 /* read and check the IDHR chunk */
138 png_handle_IHDR(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
141 png_uint_32 width
, height
;
142 int bit_depth
, color_type
, compression_type
, filter_type
;
145 png_debug(1, "in png_handle_IHDR\n");
147 if (png_ptr
->mode
!= PNG_BEFORE_IHDR
)
148 png_error(png_ptr
, "Out of place IHDR");
150 /* check the length */
152 png_error(png_ptr
, "Invalid IHDR chunk");
154 png_ptr
->mode
|= PNG_HAVE_IHDR
;
156 png_crc_read(png_ptr
, buf
, 13);
157 png_crc_finish(png_ptr
, 0);
159 width
= png_get_uint_32(buf
);
160 height
= png_get_uint_32(buf
+ 4);
163 compression_type
= buf
[10];
164 filter_type
= buf
[11];
165 interlace_type
= buf
[12];
167 /* check for width and height valid values */
168 if (width
== 0 || width
> (png_uint_32
)2147483647L || height
== 0 ||
169 height
> (png_uint_32
)2147483647L)
170 png_error(png_ptr
, "Invalid image size in IHDR");
172 /* check other values */
173 if (bit_depth
!= 1 && bit_depth
!= 2 && bit_depth
!= 4 &&
174 bit_depth
!= 8 && bit_depth
!= 16)
175 png_error(png_ptr
, "Invalid bit depth in IHDR");
177 if (color_type
< 0 || color_type
== 1 ||
178 color_type
== 5 || color_type
> 6)
179 png_error(png_ptr
, "Invalid color type in IHDR");
181 if ((color_type
== PNG_COLOR_TYPE_PALETTE
&& bit_depth
) > 8 ||
182 ((color_type
== PNG_COLOR_TYPE_RGB
||
183 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
||
184 color_type
== PNG_COLOR_TYPE_RGB_ALPHA
) && bit_depth
< 8))
185 png_error(png_ptr
, "Invalid color type/bit depth combination in IHDR");
187 if (interlace_type
>= PNG_INTERLACE_LAST
)
188 png_error(png_ptr
, "Unknown interlace method in IHDR");
190 if (compression_type
!= PNG_COMPRESSION_TYPE_BASE
)
191 png_error(png_ptr
, "Unknown compression method in IHDR");
193 if (filter_type
!= PNG_FILTER_TYPE_BASE
)
194 png_error(png_ptr
, "Unknown filter method in IHDR");
196 /* set internal variables */
197 png_ptr
->width
= width
;
198 png_ptr
->height
= height
;
199 png_ptr
->bit_depth
= (png_byte
)bit_depth
;
200 png_ptr
->interlaced
= (png_byte
)interlace_type
;
201 png_ptr
->color_type
= (png_byte
)color_type
;
203 /* find number of channels */
204 switch (png_ptr
->color_type
)
206 case PNG_COLOR_TYPE_GRAY
:
207 case PNG_COLOR_TYPE_PALETTE
:
208 png_ptr
->channels
= 1;
210 case PNG_COLOR_TYPE_RGB
:
211 png_ptr
->channels
= 3;
213 case PNG_COLOR_TYPE_GRAY_ALPHA
:
214 png_ptr
->channels
= 2;
216 case PNG_COLOR_TYPE_RGB_ALPHA
:
217 png_ptr
->channels
= 4;
221 /* set up other useful info */
222 png_ptr
->pixel_depth
= (png_byte
)(png_ptr
->bit_depth
*
224 png_ptr
->rowbytes
= ((png_ptr
->width
*
225 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3);
226 png_debug1(3,"bit_depth = %d\n", png_ptr
->bit_depth
);
227 png_debug1(3,"channels = %d\n", png_ptr
->channels
);
228 png_debug1(3,"rowbytes = %d\n", png_ptr
->rowbytes
);
229 png_set_IHDR(png_ptr
, info_ptr
, width
, height
, bit_depth
,
230 color_type
, interlace_type
, compression_type
, filter_type
);
233 /* read and check the palette */
235 png_handle_PLTE(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
240 png_debug(1, "in png_handle_PLTE\n");
242 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
243 png_error(png_ptr
, "Missing IHDR before PLTE");
244 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
246 png_warning(png_ptr
, "Invalid PLTE after IDAT");
247 png_crc_finish(png_ptr
, length
);
250 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
251 png_error(png_ptr
, "Duplicate PLTE chunk");
253 png_ptr
->mode
|= PNG_HAVE_PLTE
;
255 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
256 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
258 png_crc_finish(png_ptr
, length
);
265 if (png_ptr
->color_type
!= PNG_COLOR_TYPE_PALETTE
)
267 png_warning(png_ptr
, "Invalid palette chunk");
268 png_crc_finish(png_ptr
, length
);
273 png_error(png_ptr
, "Invalid palette chunk");
277 num
= (int)length
/ 3;
278 palette
= (png_colorp
)png_zalloc(png_ptr
, (uInt
)num
, sizeof (png_color
));
279 png_ptr
->flags
|= PNG_FLAG_FREE_PALETTE
;
280 for (i
= 0; i
< num
; i
++)
284 png_crc_read(png_ptr
, buf
, 3);
285 /* don't depend upon png_color being any order */
286 palette
[i
].red
= buf
[0];
287 palette
[i
].green
= buf
[1];
288 palette
[i
].blue
= buf
[2];
291 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
292 whatever the normal CRC configuration tells us. However, if we
293 have an RGB image, the PLTE can be considered ancillary, so
294 we will act as though it is. */
295 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
296 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
299 png_crc_finish(png_ptr
, 0);
301 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
302 else if (png_crc_error(png_ptr
)) /* Only if we have a CRC error */
304 /* If we don't want to use the data from an ancillary chunk,
305 we have two options: an error abort, or a warning and we
306 ignore the data in this chunk (which should be OK, since
307 it's considered ancillary for a RGB or RGBA image). */
308 if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_USE
))
310 if (png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
)
312 png_chunk_error(png_ptr
, "CRC error");
316 png_chunk_warning(png_ptr
, "CRC error");
317 png_ptr
->flags
&= ~PNG_FLAG_FREE_PALETTE
;
318 png_zfree(png_ptr
, palette
);
322 /* Otherwise, we (optionally) emit a warning and use the chunk. */
323 else if (!(png_ptr
->flags
& PNG_FLAG_CRC_ANCILLARY_NOWARN
))
325 png_chunk_warning(png_ptr
, "CRC error");
329 png_ptr
->palette
= palette
;
330 png_ptr
->num_palette
= (png_uint_16
)num
;
331 png_set_PLTE(png_ptr
, info_ptr
, palette
, num
);
333 #if defined (PNG_READ_tRNS_SUPPORTED)
334 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
336 if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tRNS
)
338 if (png_ptr
->num_trans
> png_ptr
->num_palette
)
340 png_warning(png_ptr
, "Truncating incorrect tRNS chunk length");
341 png_ptr
->num_trans
= png_ptr
->num_palette
;
350 png_handle_IEND(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
352 png_debug(1, "in png_handle_IEND\n");
354 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
) || !(png_ptr
->mode
& PNG_HAVE_IDAT
))
356 png_error(png_ptr
, "No image in file");
358 /* to quiet compiler warnings about unused info_ptr */
359 if (info_ptr
== NULL
)
363 png_ptr
->mode
|= PNG_AFTER_IDAT
| PNG_HAVE_IEND
;
367 png_warning(png_ptr
, "Incorrect IEND chunk length");
369 png_crc_finish(png_ptr
, length
);
372 #if defined(PNG_READ_gAMA_SUPPORTED)
374 png_handle_gAMA(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
380 png_debug(1, "in png_handle_gAMA\n");
382 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
383 png_error(png_ptr
, "Missing IHDR before gAMA");
384 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
386 png_warning(png_ptr
, "Invalid gAMA after IDAT");
387 png_crc_finish(png_ptr
, length
);
390 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
391 /* Should be an error, but we can cope with it */
392 png_warning(png_ptr
, "Out of place gAMA chunk");
394 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_gAMA
395 #if defined(PNG_READ_sRGB_SUPPORTED)
396 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
400 png_warning(png_ptr
, "Duplicate gAMA chunk");
401 png_crc_finish(png_ptr
, length
);
407 png_warning(png_ptr
, "Incorrect gAMA chunk length");
408 png_crc_finish(png_ptr
, length
);
412 png_crc_read(png_ptr
, buf
, 4);
413 if (png_crc_finish(png_ptr
, 0))
416 igamma
= png_get_uint_32(buf
);
417 /* check for zero gamma */
421 #if defined(PNG_READ_sRGB_SUPPORTED)
422 if (info_ptr
->valid
& PNG_INFO_sRGB
)
423 if(igamma
!= (png_uint_32
)45000L)
426 "Ignoring incorrect gAMA value when sRGB is also present");
427 #ifndef PNG_NO_CONSOLE_IO
428 fprintf(stderr
, "igamma = %lu\n", igamma
);
432 #endif /* PNG_READ_sRGB_SUPPORTED */
434 file_gamma
= (float)igamma
/ (float)100000.0;
435 #ifdef PNG_READ_GAMMA_SUPPORTED
436 png_ptr
->gamma
= file_gamma
;
438 png_set_gAMA(png_ptr
, info_ptr
, file_gamma
);
442 #if defined(PNG_READ_sBIT_SUPPORTED)
444 png_handle_sBIT(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
449 png_debug(1, "in png_handle_sBIT\n");
451 buf
[0] = buf
[1] = buf
[2] = buf
[3] = 0;
453 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
454 png_error(png_ptr
, "Missing IHDR before sBIT");
455 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
457 png_warning(png_ptr
, "Invalid sBIT after IDAT");
458 png_crc_finish(png_ptr
, length
);
461 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
463 /* Should be an error, but we can cope with it */
464 png_warning(png_ptr
, "Out of place sBIT chunk");
466 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_sBIT
)
468 png_warning(png_ptr
, "Duplicate sBIT chunk");
469 png_crc_finish(png_ptr
, length
);
473 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
476 truelen
= (png_size_t
)png_ptr
->channels
;
478 if (length
!= truelen
)
480 png_warning(png_ptr
, "Incorrect sBIT chunk length");
481 png_crc_finish(png_ptr
, length
);
485 png_crc_read(png_ptr
, buf
, truelen
);
486 if (png_crc_finish(png_ptr
, 0))
489 if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
491 png_ptr
->sig_bit
.red
= buf
[0];
492 png_ptr
->sig_bit
.green
= buf
[1];
493 png_ptr
->sig_bit
.blue
= buf
[2];
494 png_ptr
->sig_bit
.alpha
= buf
[3];
498 png_ptr
->sig_bit
.gray
= buf
[0];
499 png_ptr
->sig_bit
.red
= buf
[0];
500 png_ptr
->sig_bit
.green
= buf
[0];
501 png_ptr
->sig_bit
.blue
= buf
[0];
502 png_ptr
->sig_bit
.alpha
= buf
[1];
504 png_set_sBIT(png_ptr
, info_ptr
, &(png_ptr
->sig_bit
));
508 #if defined(PNG_READ_cHRM_SUPPORTED)
510 png_handle_cHRM(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
514 float white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
;
516 png_debug(1, "in png_handle_cHRM\n");
518 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
519 png_error(png_ptr
, "Missing IHDR before sBIT");
520 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
522 png_warning(png_ptr
, "Invalid cHRM after IDAT");
523 png_crc_finish(png_ptr
, length
);
526 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
527 /* Should be an error, but we can cope with it */
528 png_warning(png_ptr
, "Missing PLTE before cHRM");
530 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_cHRM
531 #if defined(PNG_READ_sRGB_SUPPORTED)
532 && !(info_ptr
->valid
& PNG_INFO_sRGB
)
536 png_warning(png_ptr
, "Duplicate cHRM chunk");
537 png_crc_finish(png_ptr
, length
);
543 png_warning(png_ptr
, "Incorrect cHRM chunk length");
544 png_crc_finish(png_ptr
, length
);
548 png_crc_read(png_ptr
, buf
, 4);
549 val
= png_get_uint_32(buf
);
550 white_x
= (float)val
/ (float)100000.0;
552 png_crc_read(png_ptr
, buf
, 4);
553 val
= png_get_uint_32(buf
);
554 white_y
= (float)val
/ (float)100000.0;
556 if (white_x
< 0 || white_x
> 0.8 || white_y
< 0 || white_y
> 0.8 ||
557 white_x
+ white_y
> 1.0)
559 png_warning(png_ptr
, "Invalid cHRM white point");
560 png_crc_finish(png_ptr
, 24);
564 png_crc_read(png_ptr
, buf
, 4);
565 val
= png_get_uint_32(buf
);
566 red_x
= (float)val
/ (float)100000.0;
568 png_crc_read(png_ptr
, buf
, 4);
569 val
= png_get_uint_32(buf
);
570 red_y
= (float)val
/ (float)100000.0;
572 if (red_x
< 0 || red_x
> 0.8 || red_y
< 0 || red_y
> 0.8 ||
575 png_warning(png_ptr
, "Invalid cHRM red point");
576 png_crc_finish(png_ptr
, 16);
580 png_crc_read(png_ptr
, buf
, 4);
581 val
= png_get_uint_32(buf
);
582 green_x
= (float)val
/ (float)100000.0;
584 png_crc_read(png_ptr
, buf
, 4);
585 val
= png_get_uint_32(buf
);
586 green_y
= (float)val
/ (float)100000.0;
588 if (green_x
< 0 || green_x
> 0.8 || green_y
< 0 || green_y
> 0.8 ||
589 green_x
+ green_y
> 1.0)
591 png_warning(png_ptr
, "Invalid cHRM green point");
592 png_crc_finish(png_ptr
, 8);
596 png_crc_read(png_ptr
, buf
, 4);
597 val
= png_get_uint_32(buf
);
598 blue_x
= (float)val
/ (float)100000.0;
600 png_crc_read(png_ptr
, buf
, 4);
601 val
= png_get_uint_32(buf
);
602 blue_y
= (float)val
/ (float)100000.0;
604 if (blue_x
< (float)0 || blue_x
> (float)0.8 || blue_y
< (float)0 ||
605 blue_y
> (float)0.8 || blue_x
+ blue_y
> (float)1.0)
607 png_warning(png_ptr
, "Invalid cHRM blue point");
608 png_crc_finish(png_ptr
, 0);
612 if (png_crc_finish(png_ptr
, 0))
615 #if defined(PNG_READ_sRGB_SUPPORTED)
616 if (info_ptr
->valid
& PNG_INFO_sRGB
)
618 if (fabs(white_x
- (float).3127) > (float).001 ||
619 fabs(white_y
- (float).3290) > (float).001 ||
620 fabs( red_x
- (float).6400) > (float).001 ||
621 fabs( red_y
- (float).3300) > (float).001 ||
622 fabs(green_x
- (float).3000) > (float).001 ||
623 fabs(green_y
- (float).6000) > (float).001 ||
624 fabs( blue_x
- (float).1500) > (float).001 ||
625 fabs( blue_y
- (float).0600) > (float).001)
629 "Ignoring incorrect cHRM value when sRGB is also present");
630 #ifndef PNG_NO_CONSOLE_IO
631 fprintf(stderr
,"wx=%f, wy=%f, rx=%f, ry=%f\n",
632 white_x
, white_y
, red_x
, red_y
);
633 fprintf(stderr
,"gx=%f, gy=%f, bx=%f, by=%f\n",
634 green_x
, green_y
, blue_x
, blue_y
);
639 #endif /* PNG_READ_sRGB_SUPPORTED */
641 png_set_cHRM(png_ptr
, info_ptr
,
642 white_x
, white_y
, red_x
, red_y
, green_x
, green_y
, blue_x
, blue_y
);
646 #if defined(PNG_READ_sRGB_SUPPORTED)
648 png_handle_sRGB(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
653 png_debug(1, "in png_handle_sRGB\n");
655 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
656 png_error(png_ptr
, "Missing IHDR before sRGB");
657 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
659 png_warning(png_ptr
, "Invalid sRGB after IDAT");
660 png_crc_finish(png_ptr
, length
);
663 else if (png_ptr
->mode
& PNG_HAVE_PLTE
)
664 /* Should be an error, but we can cope with it */
665 png_warning(png_ptr
, "Out of place sRGB chunk");
667 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_sRGB
)
669 png_warning(png_ptr
, "Duplicate sRGB chunk");
670 png_crc_finish(png_ptr
, length
);
676 png_warning(png_ptr
, "Incorrect sRGB chunk length");
677 png_crc_finish(png_ptr
, length
);
681 png_crc_read(png_ptr
, buf
, 1);
682 if (png_crc_finish(png_ptr
, 0))
686 /* check for bad intent */
687 if (intent
>= PNG_sRGB_INTENT_LAST
)
689 png_warning(png_ptr
, "Unknown sRGB intent");
693 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
694 if ((info_ptr
->valid
& PNG_INFO_gAMA
))
695 if((png_uint_32
)(png_ptr
->gamma
*(float)100000.+.5) != (png_uint_32
)45000L)
698 "Ignoring incorrect gAMA value when sRGB is also present");
699 #ifndef PNG_NO_CONSOLE_IO
700 fprintf(stderr
,"gamma=%f\n",png_ptr
->gamma
);
703 #endif /* PNG_READ_gAMA_SUPPORTED */
705 #ifdef PNG_READ_cHRM_SUPPORTED
706 if (info_ptr
->valid
& PNG_INFO_cHRM
)
707 if (fabs(info_ptr
->x_white
- (float).3127) > (float).001 ||
708 fabs(info_ptr
->y_white
- (float).3290) > (float).001 ||
709 fabs( info_ptr
->x_red
- (float).6400) > (float).001 ||
710 fabs( info_ptr
->y_red
- (float).3300) > (float).001 ||
711 fabs(info_ptr
->x_green
- (float).3000) > (float).001 ||
712 fabs(info_ptr
->y_green
- (float).6000) > (float).001 ||
713 fabs( info_ptr
->x_blue
- (float).1500) > (float).001 ||
714 fabs( info_ptr
->y_blue
- (float).0600) > (float).001)
717 "Ignoring incorrect cHRM value when sRGB is also present");
719 #endif /* PNG_READ_cHRM_SUPPORTED */
721 png_set_sRGB_gAMA_and_cHRM(png_ptr
, info_ptr
, intent
);
723 #endif /* PNG_READ_sRGB_SUPPORTED */
725 #if defined(PNG_READ_tRNS_SUPPORTED)
727 png_handle_tRNS(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
729 png_debug(1, "in png_handle_tRNS\n");
731 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
732 png_error(png_ptr
, "Missing IHDR before tRNS");
733 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
735 png_warning(png_ptr
, "Invalid tRNS after IDAT");
736 png_crc_finish(png_ptr
, length
);
739 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tRNS
)
741 png_warning(png_ptr
, "Duplicate tRNS chunk");
742 png_crc_finish(png_ptr
, length
);
746 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
748 if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
750 /* Should be an error, but we can cope with it */
751 png_warning(png_ptr
, "Missing PLTE before tRNS");
753 else if (length
> png_ptr
->num_palette
)
755 png_warning(png_ptr
, "Incorrect tRNS chunk length");
756 png_crc_finish(png_ptr
, length
);
761 png_warning(png_ptr
, "Zero length tRNS chunk");
762 png_crc_finish(png_ptr
, length
);
766 png_ptr
->trans
= (png_bytep
)png_malloc(png_ptr
, length
);
767 png_ptr
->flags
|= PNG_FLAG_FREE_TRANS
;
768 png_crc_read(png_ptr
, png_ptr
->trans
, (png_size_t
)length
);
769 png_ptr
->num_trans
= (png_uint_16
)length
;
771 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
777 png_warning(png_ptr
, "Incorrect tRNS chunk length");
778 png_crc_finish(png_ptr
, length
);
782 png_crc_read(png_ptr
, buf
, (png_size_t
)length
);
783 png_ptr
->num_trans
= 1;
784 png_ptr
->trans_values
.red
= png_get_uint_16(buf
);
785 png_ptr
->trans_values
.green
= png_get_uint_16(buf
+ 2);
786 png_ptr
->trans_values
.blue
= png_get_uint_16(buf
+ 4);
788 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
794 png_warning(png_ptr
, "Incorrect tRNS chunk length");
795 png_crc_finish(png_ptr
, length
);
799 png_crc_read(png_ptr
, buf
, 2);
800 png_ptr
->num_trans
= 1;
801 png_ptr
->trans_values
.gray
= png_get_uint_16(buf
);
805 png_warning(png_ptr
, "tRNS chunk not allowed with alpha channel");
806 png_crc_finish(png_ptr
, length
);
810 if (png_crc_finish(png_ptr
, 0))
813 png_set_tRNS(png_ptr
, info_ptr
, png_ptr
->trans
, png_ptr
->num_trans
,
814 &(png_ptr
->trans_values
));
818 #if defined(PNG_READ_bKGD_SUPPORTED)
820 png_handle_bKGD(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
825 png_debug(1, "in png_handle_bKGD\n");
827 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
828 png_error(png_ptr
, "Missing IHDR before bKGD");
829 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
831 png_warning(png_ptr
, "Invalid bKGD after IDAT");
832 png_crc_finish(png_ptr
, length
);
835 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
&&
836 !(png_ptr
->mode
& PNG_HAVE_PLTE
))
838 png_warning(png_ptr
, "Missing PLTE before bKGD");
839 png_crc_finish(png_ptr
, length
);
842 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_bKGD
)
844 png_warning(png_ptr
, "Duplicate bKGD chunk");
845 png_crc_finish(png_ptr
, length
);
849 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
851 else if (png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)
856 if (length
!= truelen
)
858 png_warning(png_ptr
, "Incorrect bKGD chunk length");
859 png_crc_finish(png_ptr
, length
);
863 png_crc_read(png_ptr
, buf
, truelen
);
864 if (png_crc_finish(png_ptr
, 0))
867 /* We convert the index value into RGB components so that we can allow
868 * arbitrary RGB values for background when we have transparency, and
869 * so it is easy to determine the RGB values of the background color
870 * from the info_ptr struct. */
871 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
873 png_ptr
->background
.index
= buf
[0];
874 png_ptr
->background
.red
= (png_uint_16
)png_ptr
->palette
[buf
[0]].red
;
875 png_ptr
->background
.green
= (png_uint_16
)png_ptr
->palette
[buf
[0]].green
;
876 png_ptr
->background
.blue
= (png_uint_16
)png_ptr
->palette
[buf
[0]].blue
;
878 else if (!(png_ptr
->color_type
& PNG_COLOR_MASK_COLOR
)) /* GRAY */
880 png_ptr
->background
.red
=
881 png_ptr
->background
.green
=
882 png_ptr
->background
.blue
=
883 png_ptr
->background
.gray
= png_get_uint_16(buf
);
887 png_ptr
->background
.red
= png_get_uint_16(buf
);
888 png_ptr
->background
.green
= png_get_uint_16(buf
+ 2);
889 png_ptr
->background
.blue
= png_get_uint_16(buf
+ 4);
892 png_set_bKGD(png_ptr
, info_ptr
, &(png_ptr
->background
));
896 #if defined(PNG_READ_hIST_SUPPORTED)
898 png_handle_hIST(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
902 png_debug(1, "in png_handle_hIST\n");
904 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
905 png_error(png_ptr
, "Missing IHDR before hIST");
906 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
908 png_warning(png_ptr
, "Invalid hIST after IDAT");
909 png_crc_finish(png_ptr
, length
);
912 else if (!(png_ptr
->mode
& PNG_HAVE_PLTE
))
914 png_warning(png_ptr
, "Missing PLTE before hIST");
915 png_crc_finish(png_ptr
, length
);
918 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_hIST
)
920 png_warning(png_ptr
, "Duplicate hIST chunk");
921 png_crc_finish(png_ptr
, length
);
925 if (length
!= (png_uint_32
)(2 * png_ptr
->num_palette
))
927 png_warning(png_ptr
, "Incorrect hIST chunk length");
928 png_crc_finish(png_ptr
, length
);
932 num
= (int)length
/ 2;
933 png_ptr
->hist
= (png_uint_16p
)png_malloc(png_ptr
,
934 (png_uint_32
)(num
* sizeof (png_uint_16
)));
935 png_ptr
->flags
|= PNG_FLAG_FREE_HIST
;
936 for (i
= 0; i
< num
; i
++)
940 png_crc_read(png_ptr
, buf
, 2);
941 png_ptr
->hist
[i
] = png_get_uint_16(buf
);
944 if (png_crc_finish(png_ptr
, 0))
947 png_set_hIST(png_ptr
, info_ptr
, png_ptr
->hist
);
951 #if defined(PNG_READ_pHYs_SUPPORTED)
953 png_handle_pHYs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
956 png_uint_32 res_x
, res_y
;
959 png_debug(1, "in png_handle_pHYs\n");
961 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
962 png_error(png_ptr
, "Missing IHDR before pHYS");
963 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
965 png_warning(png_ptr
, "Invalid pHYS after IDAT");
966 png_crc_finish(png_ptr
, length
);
969 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_pHYs
)
971 png_warning(png_ptr
, "Duplicate pHYS chunk");
972 png_crc_finish(png_ptr
, length
);
978 png_warning(png_ptr
, "Incorrect pHYs chunk length");
979 png_crc_finish(png_ptr
, length
);
983 png_crc_read(png_ptr
, buf
, 9);
984 if (png_crc_finish(png_ptr
, 0))
987 res_x
= png_get_uint_32(buf
);
988 res_y
= png_get_uint_32(buf
+ 4);
990 png_set_pHYs(png_ptr
, info_ptr
, res_x
, res_y
, unit_type
);
994 #if defined(PNG_READ_oFFs_SUPPORTED)
996 png_handle_oFFs(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
999 png_uint_32 offset_x
, offset_y
;
1002 png_debug(1, "in png_handle_oFFs\n");
1004 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1005 png_error(png_ptr
, "Missing IHDR before oFFs");
1006 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1008 png_warning(png_ptr
, "Invalid oFFs after IDAT");
1009 png_crc_finish(png_ptr
, length
);
1012 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_oFFs
)
1014 png_warning(png_ptr
, "Duplicate oFFs chunk");
1015 png_crc_finish(png_ptr
, length
);
1021 png_warning(png_ptr
, "Incorrect oFFs chunk length");
1022 png_crc_finish(png_ptr
, length
);
1026 png_crc_read(png_ptr
, buf
, 9);
1027 if (png_crc_finish(png_ptr
, 0))
1030 offset_x
= png_get_uint_32(buf
);
1031 offset_y
= png_get_uint_32(buf
+ 4);
1033 png_set_oFFs(png_ptr
, info_ptr
, offset_x
, offset_y
, unit_type
);
1037 #if defined(PNG_READ_pCAL_SUPPORTED)
1038 /* read the pCAL chunk (png-scivis-19970203) */
1040 png_handle_pCAL(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1044 png_byte type
, nparams
;
1045 png_charp buf
, units
, endptr
;
1050 png_debug(1, "in png_handle_pCAL\n");
1052 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1053 png_error(png_ptr
, "Missing IHDR before pCAL");
1054 else if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1056 png_warning(png_ptr
, "Invalid pCAL after IDAT");
1057 png_crc_finish(png_ptr
, length
);
1060 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_pCAL
)
1062 png_warning(png_ptr
, "Duplicate pCAL chunk");
1063 png_crc_finish(png_ptr
, length
);
1067 png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
1069 purpose
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1070 slength
= (png_size_t
)length
;
1071 png_crc_read(png_ptr
, (png_bytep
)purpose
, slength
);
1073 if (png_crc_finish(png_ptr
, 0))
1075 png_free(png_ptr
, purpose
);
1079 purpose
[slength
] = 0x00; /* null terminate the last string */
1081 png_debug(3, "Finding end of pCAL purpose string\n");
1082 for (buf
= purpose
; *buf
; buf
++)
1085 endptr
= purpose
+ slength
;
1087 /* We need to have at least 12 bytes after the purpose string
1088 in order to get the parameter information. */
1089 if (endptr
<= buf
+ 12)
1091 png_warning(png_ptr
, "Invalid pCAL data");
1092 png_free(png_ptr
, purpose
);
1096 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
1097 X0
= png_get_int_32((png_bytep
)buf
+1);
1098 X1
= png_get_int_32((png_bytep
)buf
+5);
1103 png_debug(3, "Checking pCAL equation type and number of parameters\n");
1104 /* Check that we have the right number of parameters for known
1106 if ((type
== PNG_EQUATION_LINEAR
&& nparams
!= 2) ||
1107 (type
== PNG_EQUATION_BASE_E
&& nparams
!= 3) ||
1108 (type
== PNG_EQUATION_ARBITRARY
&& nparams
!= 3) ||
1109 (type
== PNG_EQUATION_HYPERBOLIC
&& nparams
!= 4))
1111 png_warning(png_ptr
, "Invalid pCAL parameters for equation type");
1112 png_free(png_ptr
, purpose
);
1115 else if (type
>= PNG_EQUATION_LAST
)
1117 png_warning(png_ptr
, "Unrecognized equation type for pCAL chunk");
1120 for (buf
= units
; *buf
; buf
++)
1121 /* Empty loop to move past the units string. */ ;
1123 png_debug(3, "Allocating pCAL parameters array\n");
1124 params
= (png_charpp
)png_malloc(png_ptr
, (png_uint_32
)(nparams
1125 *sizeof(png_charp
))) ;
1127 /* Get pointers to the start of each parameter string. */
1128 for (i
= 0; i
< (int)nparams
; i
++)
1130 buf
++; /* Skip the null string terminator from previous parameter. */
1132 png_debug1(3, "Reading pCAL parameter %d\n", i
);
1133 for (params
[i
] = buf
; *buf
!= 0x00 && buf
<= endptr
; buf
++)
1134 /* Empty loop to move past each parameter string */ ;
1136 /* Make sure we haven't run out of data yet */
1139 png_warning(png_ptr
, "Invalid pCAL data");
1140 png_free(png_ptr
, purpose
);
1141 png_free(png_ptr
, params
);
1146 png_set_pCAL(png_ptr
, info_ptr
, purpose
, X0
, X1
, type
, nparams
,
1149 png_free(png_ptr
, purpose
);
1150 png_free(png_ptr
, params
);
1154 #if defined(PNG_READ_tIME_SUPPORTED)
1156 png_handle_tIME(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1161 png_debug(1, "in png_handle_tIME\n");
1163 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1164 png_error(png_ptr
, "Out of place tIME chunk");
1165 else if (info_ptr
!= NULL
&& info_ptr
->valid
& PNG_INFO_tIME
)
1167 png_warning(png_ptr
, "Duplicate tIME chunk");
1168 png_crc_finish(png_ptr
, length
);
1172 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1173 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1177 png_warning(png_ptr
, "Incorrect tIME chunk length");
1178 png_crc_finish(png_ptr
, length
);
1182 png_crc_read(png_ptr
, buf
, 7);
1183 if (png_crc_finish(png_ptr
, 0))
1186 mod_time
.second
= buf
[6];
1187 mod_time
.minute
= buf
[5];
1188 mod_time
.hour
= buf
[4];
1189 mod_time
.day
= buf
[3];
1190 mod_time
.month
= buf
[2];
1191 mod_time
.year
= png_get_uint_16(buf
);
1193 png_set_tIME(png_ptr
, info_ptr
, &mod_time
);
1197 #if defined(PNG_READ_tEXt_SUPPORTED)
1198 /* Note: this does not properly handle chunks that are > 64K under DOS */
1200 png_handle_tEXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1205 png_uint_32 skip
= 0;
1208 png_debug(1, "in png_handle_tEXt\n");
1210 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1211 png_error(png_ptr
, "Missing IHDR before tEXt");
1213 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1214 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1216 #ifdef PNG_MAX_MALLOC_64K
1217 if (length
> (png_uint_32
)65535L)
1219 png_warning(png_ptr
, "tEXt chunk too large to fit in memory");
1220 skip
= length
- (png_uint_32
)65535L;
1221 length
= (png_uint_32
)65535L;
1225 key
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1226 slength
= (png_size_t
)length
;
1227 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1229 if (png_crc_finish(png_ptr
, skip
))
1231 png_free(png_ptr
, key
);
1235 key
[slength
] = 0x00;
1237 for (text
= key
; *text
; text
++)
1238 /* empty loop to find end of key */ ;
1240 if (text
!= key
+ slength
)
1243 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1244 text_ptr
->compression
= PNG_TEXT_COMPRESSION_NONE
;
1245 text_ptr
->key
= key
;
1246 text_ptr
->text
= text
;
1248 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1250 png_free(png_ptr
, text_ptr
);
1254 #if defined(PNG_READ_zTXt_SUPPORTED)
1255 /* note: this does not correctly handle chunks that are > 64K under DOS */
1257 png_handle_zTXt(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1259 static char msg
[] = "Error decoding zTXt chunk";
1263 int comp_type
= PNG_TEXT_COMPRESSION_NONE
;
1266 png_debug(1, "in png_handle_zTXt\n");
1268 if (!(png_ptr
->mode
& PNG_HAVE_IHDR
))
1269 png_error(png_ptr
, "Missing IHDR before zTXt");
1271 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1272 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1274 #ifdef PNG_MAX_MALLOC_64K
1275 /* We will no doubt have problems with chunks even half this size, but
1276 there is no hard and fast rule to tell us where to stop. */
1277 if (length
> (png_uint_32
)65535L)
1279 png_warning(png_ptr
,"zTXt chunk too large to fit in memory");
1280 png_crc_finish(png_ptr
, length
);
1285 key
= (png_charp
)png_malloc(png_ptr
, length
+ 1);
1286 slength
= (png_size_t
)length
;
1287 png_crc_read(png_ptr
, (png_bytep
)key
, slength
);
1288 if (png_crc_finish(png_ptr
, 0))
1290 png_free(png_ptr
, key
);
1294 key
[slength
] = 0x00;
1296 for (text
= key
; *text
; text
++)
1299 /* zTXt must have some text after the keyword */
1300 if (text
== key
+ slength
)
1302 png_warning(png_ptr
, "Zero length zTXt chunk");
1304 else if ((comp_type
= *(++text
)) == PNG_TEXT_COMPRESSION_zTXt
)
1306 png_size_t text_size
, key_size
;
1309 png_ptr
->zstream
.next_in
= (png_bytep
)text
;
1310 png_ptr
->zstream
.avail_in
= (uInt
)(length
- (text
- key
));
1311 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
1312 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
1314 key_size
= (png_size_t
)(text
- key
);
1318 while (png_ptr
->zstream
.avail_in
)
1322 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
1323 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
)
1325 if (png_ptr
->zstream
.msg
!= NULL
)
1326 png_warning(png_ptr
, png_ptr
->zstream
.msg
);
1328 png_warning(png_ptr
, msg
);
1329 inflateReset(&png_ptr
->zstream
);
1330 png_ptr
->zstream
.avail_in
= 0;
1334 text_size
= key_size
+ sizeof(msg
) + 1;
1335 text
= (png_charp
)png_malloc(png_ptr
, (png_uint_32
)text_size
);
1336 png_memcpy(text
, key
, key_size
);
1339 text
[text_size
- 1] = 0x00;
1341 /* Copy what we can of the error message into the text chunk */
1342 text_size
= (png_size_t
)(slength
- (text
- key
) - 1);
1343 text_size
= sizeof(msg
) > text_size
? text_size
: sizeof(msg
);
1344 png_memcpy(text
+ key_size
, msg
, text_size
+ 1);
1347 if (!png_ptr
->zstream
.avail_out
|| ret
== Z_STREAM_END
)
1351 text
= (png_charp
)png_malloc(png_ptr
,
1352 (png_uint_32
)(png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
1354 png_memcpy(text
+ key_size
, png_ptr
->zbuf
,
1355 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
);
1356 png_memcpy(text
, key
, key_size
);
1357 text_size
= key_size
+ png_ptr
->zbuf_size
-
1358 png_ptr
->zstream
.avail_out
;
1359 *(text
+ text_size
) = 0x00;
1366 text
= (png_charp
)png_malloc(png_ptr
, (png_uint_32
)(text_size
+
1367 png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
+ 1));
1368 png_memcpy(text
, tmp
, text_size
);
1369 png_free(png_ptr
, tmp
);
1370 png_memcpy(text
+ text_size
, png_ptr
->zbuf
,
1371 (png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
));
1372 text_size
+= png_ptr
->zbuf_size
- png_ptr
->zstream
.avail_out
;
1373 *(text
+ text_size
) = 0x00;
1375 if (ret
!= Z_STREAM_END
)
1377 png_ptr
->zstream
.next_out
= png_ptr
->zbuf
;
1378 png_ptr
->zstream
.avail_out
= (uInt
)png_ptr
->zbuf_size
;
1387 inflateReset(&png_ptr
->zstream
);
1388 png_ptr
->zstream
.avail_in
= 0;
1390 png_free(png_ptr
, key
);
1394 else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
1396 png_size_t text_size
;
1397 #if !defined(PNG_NO_STDIO)
1400 sprintf(umsg
, "Unknown zTXt compression type %d", comp_type
);
1401 png_warning(png_ptr
, umsg
);
1403 png_warning(png_ptr
, "Unknown zTXt compression type");
1406 /* Copy what we can of the error message into the text chunk */
1407 text_size
= (png_size_t
)(slength
- (text
- key
) - 1);
1408 text_size
= sizeof(msg
) > text_size
? text_size
: sizeof(msg
);
1409 png_memcpy(text
, msg
, text_size
+ 1);
1412 text_ptr
= (png_textp
)png_malloc(png_ptr
, (png_uint_32
)sizeof(png_text
));
1413 text_ptr
->compression
= comp_type
;
1414 text_ptr
->key
= key
;
1415 text_ptr
->text
= text
;
1417 png_set_text(png_ptr
, info_ptr
, text_ptr
, 1);
1419 png_free(png_ptr
, text_ptr
);
1423 /* This function is called when we haven't found a handler for a
1424 chunk. If there isn't a problem with the chunk itself (ie bad
1425 chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
1427 png_handle_unknown(png_structp png_ptr
, png_infop info_ptr
, png_uint_32 length
)
1429 png_debug(1, "in png_handle_unknown\n");
1431 /* In the future we can have code here that calls user-supplied
1432 * callback functions for unknown chunks before they are ignored or
1435 png_check_chunk_name(png_ptr
, png_ptr
->chunk_name
);
1437 if (!(png_ptr
->chunk_name
[0] & 0x20))
1439 png_chunk_error(png_ptr
, "unknown critical chunk");
1441 /* to quiet compiler warnings about unused info_ptr */
1442 if (info_ptr
== NULL
)
1446 if (png_ptr
->mode
& PNG_HAVE_IDAT
)
1447 png_ptr
->mode
|= PNG_AFTER_IDAT
;
1449 png_crc_finish(png_ptr
, length
);
1453 /* This function is called to verify that a chunk name is valid.
1454 This function can't have the "critical chunk check" incorporated
1455 into it, since in the future we will need to be able to call user
1456 functions to handle unknown critical chunks after we check that
1457 the chunk name itself is valid. */
1459 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
1462 png_check_chunk_name(png_structp png_ptr
, png_bytep chunk_name
)
1464 png_debug(1, "in png_check_chunk_name\n");
1465 if (isnonalpha(chunk_name
[0]) || isnonalpha(chunk_name
[1]) ||
1466 isnonalpha(chunk_name
[2]) || isnonalpha(chunk_name
[3]))
1468 png_chunk_error(png_ptr
, "invalid chunk type");
1472 /* Combines the row recently read in with the existing pixels in the
1473 row. This routine takes care of alpha and transparency if requested.
1474 This routine also handles the two methods of progressive display
1475 of interlaced images, depending on the mask value.
1476 The mask value describes which pixels are to be combined with
1477 the row. The pattern always repeats every 8 pixels, so just 8
1478 bits are needed. A one indicates the pixel is to be combined,
1479 a zero indicates the pixel is to be skipped. This is in addition
1480 to any alpha or transparency value associated with the pixel. If
1481 you want all pixels to be combined, pass 0xff (255) in mask. */
1483 png_combine_row(png_structp png_ptr
, png_bytep row
,
1486 png_debug(1,"in png_combine_row\n");
1489 png_memcpy(row
, png_ptr
->row_buf
+ 1,
1490 (png_size_t
)((png_ptr
->width
*
1491 png_ptr
->row_info
.pixel_depth
+ 7) >> 3));
1495 switch (png_ptr
->row_info
.pixel_depth
)
1499 png_bytep sp
= png_ptr
->row_buf
+ 1;
1501 int s_inc
, s_start
, s_end
;
1505 png_uint_32 row_width
= png_ptr
->width
;
1507 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1508 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1524 for (i
= 0; i
< row_width
; i
++)
1530 value
= (*sp
>> shift
) & 0x1;
1531 *dp
&= (png_byte
)((0x7f7f >> (7 - shift
)) & 0xff);
1532 *dp
|= (png_byte
)(value
<< shift
);
1553 png_bytep sp
= png_ptr
->row_buf
+ 1;
1555 int s_start
, s_end
, s_inc
;
1559 png_uint_32 row_width
= png_ptr
->width
;
1562 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1563 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1579 for (i
= 0; i
< row_width
; i
++)
1583 value
= (*sp
>> shift
) & 0x3;
1584 *dp
&= (png_byte
)((0x3f3f >> (6 - shift
)) & 0xff);
1585 *dp
|= (png_byte
)(value
<< shift
);
1605 png_bytep sp
= png_ptr
->row_buf
+ 1;
1607 int s_start
, s_end
, s_inc
;
1611 png_uint_32 row_width
= png_ptr
->width
;
1614 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1615 if (png_ptr
->transformations
& PNG_PACKSWAP
)
1630 for (i
= 0; i
< row_width
; i
++)
1634 value
= (*sp
>> shift
) & 0xf;
1635 *dp
&= (png_byte
)((0xf0f >> (4 - shift
)) & 0xff);
1636 *dp
|= (png_byte
)(value
<< shift
);
1656 png_bytep sp
= png_ptr
->row_buf
+ 1;
1658 png_size_t pixel_bytes
= (png_ptr
->row_info
.pixel_depth
>> 3);
1660 png_uint_32 row_width
= png_ptr
->width
;
1664 for (i
= 0; i
< row_width
; i
++)
1668 png_memcpy(dp
, sp
, pixel_bytes
);
1685 #if defined(PNG_READ_INTERLACING_SUPPORTED)
1687 png_do_read_interlace(png_row_infop row_info
, png_bytep row
, int pass
,
1688 png_uint_32 transformations
)
1690 png_debug(1,"in png_do_read_interlace\n");
1691 if (row
!= NULL
&& row_info
!= NULL
)
1693 png_uint_32 final_width
;
1695 final_width
= row_info
->width
* png_pass_inc
[pass
];
1697 switch (row_info
->pixel_depth
)
1701 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 3);
1702 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 3);
1704 int s_start
, s_end
, s_inc
;
1705 int jstop
= png_pass_inc
[pass
];
1710 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1711 if (transformations
& PNG_PACKSWAP
)
1713 sshift
= (int)((row_info
->width
+ 7) & 7);
1714 dshift
= (int)((final_width
+ 7) & 7);
1722 sshift
= 7 - (int)((row_info
->width
+ 7) & 7);
1723 dshift
= 7 - (int)((final_width
+ 7) & 7);
1729 for (i
= 0; i
< row_info
->width
; i
++)
1731 v
= (png_byte
)((*sp
>> sshift
) & 0x1);
1732 for (j
= 0; j
< jstop
; j
++)
1734 *dp
&= (png_byte
)((0x7f7f >> (7 - dshift
)) & 0xff);
1735 *dp
|= (png_byte
)(v
<< dshift
);
1736 if (dshift
== s_end
)
1744 if (sshift
== s_end
)
1756 png_bytep sp
= row
+ (png_uint_32
)((row_info
->width
- 1) >> 2);
1757 png_bytep dp
= row
+ (png_uint_32
)((final_width
- 1) >> 2);
1759 int s_start
, s_end
, s_inc
;
1760 int jstop
= png_pass_inc
[pass
];
1763 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1764 if (transformations
& PNG_PACKSWAP
)
1766 sshift
= (int)(((row_info
->width
+ 3) & 3) << 1);
1767 dshift
= (int)(((final_width
+ 3) & 3) << 1);
1775 sshift
= (int)((3 - ((row_info
->width
+ 3) & 3)) << 1);
1776 dshift
= (int)((3 - ((final_width
+ 3) & 3)) << 1);
1782 for (i
= 0; i
< row_info
->width
; i
++)
1787 v
= (png_byte
)((*sp
>> sshift
) & 0x3);
1788 for (j
= 0; j
< jstop
; j
++)
1790 *dp
&= (png_byte
)((0x3f3f >> (6 - dshift
)) & 0xff);
1791 *dp
|= (png_byte
)(v
<< dshift
);
1792 if (dshift
== s_end
)
1800 if (sshift
== s_end
)
1812 png_bytep sp
= row
+ (png_size_t
)((row_info
->width
- 1) >> 1);
1813 png_bytep dp
= row
+ (png_size_t
)((final_width
- 1) >> 1);
1815 int s_start
, s_end
, s_inc
;
1817 int jstop
= png_pass_inc
[pass
];
1819 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1820 if (transformations
& PNG_PACKSWAP
)
1822 sshift
= (int)(((row_info
->width
+ 1) & 1) << 2);
1823 dshift
= (int)(((final_width
+ 1) & 1) << 2);
1831 sshift
= (int)((1 - ((row_info
->width
+ 1) & 1)) << 2);
1832 dshift
= (int)((1 - ((final_width
+ 1) & 1)) << 2);
1838 for (i
= 0; i
< row_info
->width
; i
++)
1840 png_byte v
= (png_byte
)((*sp
>> sshift
) & 0xf);
1843 for (j
= 0; j
< jstop
; j
++)
1845 *dp
&= (png_byte
)((0xf0f >> (4 - dshift
)) & 0xff);
1846 *dp
|= (png_byte
)(v
<< dshift
);
1847 if (dshift
== s_end
)
1855 if (sshift
== s_end
)
1867 png_size_t pixel_bytes
= (row_info
->pixel_depth
>> 3);
1868 png_bytep sp
= row
+ (png_size_t
)(row_info
->width
- 1) * pixel_bytes
;
1869 png_bytep dp
= row
+ (png_size_t
)(final_width
- 1) * pixel_bytes
;
1870 int jstop
= png_pass_inc
[pass
];
1873 for (i
= 0; i
< row_info
->width
; i
++)
1878 png_memcpy(v
, sp
, pixel_bytes
);
1879 for (j
= 0; j
< jstop
; j
++)
1881 png_memcpy(dp
, v
, pixel_bytes
);
1889 row_info
->width
= final_width
;
1890 row_info
->rowbytes
= ((final_width
*
1891 (png_uint_32
)row_info
->pixel_depth
+ 7) >> 3);
1897 png_read_filter_row(png_structp png_ptr
, png_row_infop row_info
, png_bytep row
,
1898 png_bytep prev_row
, int filter
)
1900 png_debug(1, "in png_read_filter_row\n");
1901 png_debug2(2,"row = %d, filter = %d\n", png_ptr
->row_number
, filter
);
1906 case PNG_FILTER_VALUE_NONE
:
1908 case PNG_FILTER_VALUE_SUB
:
1911 png_uint_32 istop
= row_info
->rowbytes
;
1912 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1913 png_bytep rp
= row
+ bpp
;
1916 for (i
= bpp
; i
< istop
; i
++)
1918 *rp
= (png_byte
)(((int)(*rp
) + (int)(*lp
++)) & 0xff);
1923 case PNG_FILTER_VALUE_UP
:
1926 png_uint_32 istop
= row_info
->rowbytes
;
1928 png_bytep pp
= prev_row
;
1930 for (i
= 0; i
< istop
; i
++)
1932 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
1937 case PNG_FILTER_VALUE_AVG
:
1941 png_bytep pp
= prev_row
;
1943 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1944 png_uint_32 istop
= row_info
->rowbytes
- bpp
;
1946 for (i
= 0; i
< bpp
; i
++)
1948 *rp
= (png_byte
)(((int)(*rp
) +
1949 ((int)(*pp
++) / 2)) & 0xff);
1953 for (i
= 0; i
< istop
; i
++)
1955 *rp
= (png_byte
)(((int)(*rp
) +
1956 (int)(*pp
++ + *lp
++) / 2) & 0xff);
1961 case PNG_FILTER_VALUE_PAETH
:
1965 png_bytep pp
= prev_row
;
1967 png_bytep cp
= prev_row
;
1968 png_uint_32 bpp
= (row_info
->pixel_depth
+ 7) / 8;
1969 png_uint_32 istop
=row_info
->rowbytes
- bpp
;
1971 for (i
= 0; i
< bpp
; i
++)
1973 *rp
= (png_byte
)(((int)(*rp
) + (int)(*pp
++)) & 0xff);
1977 for (i
= 0; i
< istop
; i
++) /* use leftover rp,pp */
1979 int a
, b
, c
, pa
, pb
, pc
, p
;
1993 pa
= p
< 0 ? -p
: p
;
1994 pb
= pc
< 0 ? -pc
: pc
;
1995 pc
= (p
+ pc
) < 0 ? -(p
+ pc
) : p
+ pc
;
1999 if (pa <= pb && pa <= pc)
2007 p
= (pa
<= pb
&& pa
<=pc
) ? a
: (pb
<= pc
) ? b
: c
;
2009 *rp
= (png_byte
)(((int)(*rp
) + p
) & 0xff);
2015 png_warning(png_ptr
, "Ignoring bad adaptive filter type");
2022 png_read_finish_row(png_structp png_ptr
)
2024 png_debug(1, "in png_read_finish_row\n");
2025 png_ptr
->row_number
++;
2026 if (png_ptr
->row_number
< png_ptr
->num_rows
)
2029 if (png_ptr
->interlaced
)
2031 png_ptr
->row_number
= 0;
2032 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2036 if (png_ptr
->pass
>= 7)
2038 png_ptr
->iwidth
= (png_ptr
->width
+
2039 png_pass_inc
[png_ptr
->pass
] - 1 -
2040 png_pass_start
[png_ptr
->pass
]) /
2041 png_pass_inc
[png_ptr
->pass
];
2042 png_ptr
->irowbytes
= ((png_ptr
->iwidth
*
2043 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2045 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2047 png_ptr
->num_rows
= (png_ptr
->height
+
2048 png_pass_yinc
[png_ptr
->pass
] - 1 -
2049 png_pass_ystart
[png_ptr
->pass
]) /
2050 png_pass_yinc
[png_ptr
->pass
];
2051 if (!(png_ptr
->num_rows
))
2054 else /* if (png_ptr->transformations & PNG_INTERLACE) */
2056 } while (png_ptr
->iwidth
== 0);
2058 if (png_ptr
->pass
< 7)
2062 if (!(png_ptr
->flags
& PNG_FLAG_ZLIB_FINISHED
))
2067 png_ptr
->zstream
.next_out
= (Byte
*)&extra
;
2068 png_ptr
->zstream
.avail_out
= (uInt
)1;
2071 if (!(png_ptr
->zstream
.avail_in
))
2073 while (!png_ptr
->idat_size
)
2075 png_byte chunk_length
[4];
2077 png_crc_finish(png_ptr
, 0);
2079 png_read_data(png_ptr
, chunk_length
, 4);
2080 png_ptr
->idat_size
= png_get_uint_32(chunk_length
);
2082 png_reset_crc(png_ptr
);
2083 png_crc_read(png_ptr
, png_ptr
->chunk_name
, 4);
2084 if (png_memcmp(png_ptr
->chunk_name
, png_IDAT
, 4))
2085 png_error(png_ptr
, "Not enough image data");
2088 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->zbuf_size
;
2089 png_ptr
->zstream
.next_in
= png_ptr
->zbuf
;
2090 if (png_ptr
->zbuf_size
> png_ptr
->idat_size
)
2091 png_ptr
->zstream
.avail_in
= (uInt
)png_ptr
->idat_size
;
2092 png_crc_read(png_ptr
, png_ptr
->zbuf
, png_ptr
->zstream
.avail_in
);
2093 png_ptr
->idat_size
-= png_ptr
->zstream
.avail_in
;
2095 ret
= inflate(&png_ptr
->zstream
, Z_PARTIAL_FLUSH
);
2096 if (ret
== Z_STREAM_END
)
2098 if (!(png_ptr
->zstream
.avail_out
) || png_ptr
->zstream
.avail_in
||
2100 png_error(png_ptr
, "Extra compressed data");
2101 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2102 png_ptr
->flags
|= PNG_FLAG_ZLIB_FINISHED
;
2106 png_error(png_ptr
, png_ptr
->zstream
.msg
? png_ptr
->zstream
.msg
:
2107 "Decompression Error");
2109 if (!(png_ptr
->zstream
.avail_out
))
2110 png_error(png_ptr
, "Extra compressed data");
2113 png_ptr
->zstream
.avail_out
= 0;
2116 if (png_ptr
->idat_size
|| png_ptr
->zstream
.avail_in
)
2117 png_error(png_ptr
, "Extra compression data");
2119 inflateReset(&png_ptr
->zstream
);
2121 png_ptr
->mode
|= PNG_AFTER_IDAT
;
2125 png_read_start_row(png_structp png_ptr
)
2127 int max_pixel_depth
;
2128 png_uint_32 row_bytes
;
2130 png_debug(1, "in png_read_start_row\n");
2131 png_ptr
->zstream
.avail_in
= 0;
2132 png_init_read_transformations(png_ptr
);
2133 if (png_ptr
->interlaced
)
2135 if (!(png_ptr
->transformations
& PNG_INTERLACE
))
2136 png_ptr
->num_rows
= (png_ptr
->height
+ png_pass_yinc
[0] - 1 -
2137 png_pass_ystart
[0]) / png_pass_yinc
[0];
2139 png_ptr
->num_rows
= png_ptr
->height
;
2141 png_ptr
->iwidth
= (png_ptr
->width
+
2142 png_pass_inc
[png_ptr
->pass
] - 1 -
2143 png_pass_start
[png_ptr
->pass
]) /
2144 png_pass_inc
[png_ptr
->pass
];
2146 row_bytes
= ((png_ptr
->iwidth
*
2147 (png_uint_32
)png_ptr
->pixel_depth
+ 7) >> 3) +1;
2148 png_ptr
->irowbytes
= (png_size_t
)row_bytes
;
2149 if((png_uint_32
)png_ptr
->irowbytes
!= row_bytes
)
2150 png_error(png_ptr
, "Rowbytes overflow in png_read_start_row");
2154 png_ptr
->num_rows
= png_ptr
->height
;
2155 png_ptr
->iwidth
= png_ptr
->width
;
2156 png_ptr
->irowbytes
= png_ptr
->rowbytes
+ 1;
2158 max_pixel_depth
= png_ptr
->pixel_depth
;
2160 #if defined(PNG_READ_PACK_SUPPORTED)
2161 if ((png_ptr
->transformations
& PNG_PACK
) && png_ptr
->bit_depth
< 8)
2162 max_pixel_depth
= 8;
2165 #if defined(PNG_READ_EXPAND_SUPPORTED)
2166 if (png_ptr
->transformations
& PNG_EXPAND
)
2168 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2170 if (png_ptr
->num_trans
)
2171 max_pixel_depth
= 32;
2173 max_pixel_depth
= 24;
2175 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
2177 if (max_pixel_depth
< 8)
2178 max_pixel_depth
= 8;
2179 if (png_ptr
->num_trans
)
2180 max_pixel_depth
*= 2;
2182 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
2184 if (png_ptr
->num_trans
)
2186 max_pixel_depth
*= 4;
2187 max_pixel_depth
/= 3;
2193 #if defined(PNG_READ_FILLER_SUPPORTED)
2194 if (png_ptr
->transformations
& (PNG_FILLER
))
2196 if (png_ptr
->color_type
== PNG_COLOR_TYPE_PALETTE
)
2197 max_pixel_depth
= 32;
2198 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY
)
2200 if (max_pixel_depth
<= 8)
2201 max_pixel_depth
= 16;
2203 max_pixel_depth
= 32;
2205 else if (png_ptr
->color_type
== PNG_COLOR_TYPE_RGB
)
2207 if (max_pixel_depth
<= 32)
2208 max_pixel_depth
= 32;
2210 max_pixel_depth
= 64;
2215 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2216 if (png_ptr
->transformations
& PNG_GRAY_TO_RGB
)
2219 #if defined(PNG_READ_EXPAND_SUPPORTED)
2220 (png_ptr
->num_trans
&& (png_ptr
->transformations
& PNG_EXPAND
)) ||
2222 #if defined(PNG_READ_FILLER_SUPPORTED)
2223 (png_ptr
->transformations
& (PNG_FILLER
)) ||
2225 png_ptr
->color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
2227 if (max_pixel_depth
<= 16)
2228 max_pixel_depth
= 32;
2230 max_pixel_depth
= 64;
2234 if (max_pixel_depth
<= 8)
2235 max_pixel_depth
= 24;
2237 max_pixel_depth
= 48;
2242 /* align the width on the next larger 8 pixels. Mainly used
2244 row_bytes
= ((png_ptr
->width
+ 7) & ~((png_uint_32
)7));
2245 /* calculate the maximum bytes needed, adding a byte and a pixel
2246 for safety's sake */
2247 row_bytes
= ((row_bytes
* (png_uint_32
)max_pixel_depth
+ 7) >> 3) +
2248 1 + ((max_pixel_depth
+ 7) >> 3);
2249 #ifdef PNG_MAX_MALLOC_64K
2250 if (row_bytes
> (png_uint_32
)65536L)
2251 png_error(png_ptr
, "This image requires a row greater than 64KB");
2253 png_ptr
->row_buf
= (png_bytep
)png_malloc(png_ptr
, row_bytes
);
2255 #ifdef PNG_MAX_MALLOC_64K
2256 if ((png_uint_32
)png_ptr
->rowbytes
+ 1 > (png_uint_32
)65536L)
2257 png_error(png_ptr
, "This image requires a row greater than 64KB");
2259 png_ptr
->prev_row
= (png_bytep
)png_malloc(png_ptr
, (png_uint_32
)(
2260 png_ptr
->rowbytes
+ 1));
2262 png_memset_check(png_ptr
, png_ptr
->prev_row
, 0, png_ptr
->rowbytes
+ 1);
2264 png_debug1(3, "width = %d,\n", png_ptr
->width
);
2265 png_debug1(3, "height = %d,\n", png_ptr
->height
);
2266 png_debug1(3, "iwidth = %d,\n", png_ptr
->iwidth
);
2267 png_debug1(3, "num_rows = %d\n", png_ptr
->num_rows
);
2268 png_debug1(3, "rowbytes = %d,\n", png_ptr
->rowbytes
);
2269 png_debug1(3, "irowbytes = %d,\n", png_ptr
->irowbytes
);
2271 png_ptr
->flags
|= PNG_FLAG_ROW_INIT
;