Initial revision
[wxWidgets.git] / src / png / pngrutil.c
1
2 /* pngrutil.c - utilities to read a PNG file
3 *
4 * libpng 1.0.1
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
9 * March 15, 1998
10 *
11 * This file contains routines which are only called from within
12 * libpng itself during the course of reading an image.
13 */
14
15 #define PNG_INTERNAL
16 #include "png.h"
17
18 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
19 /* Grab an unsigned 32-bit integer from a buffer in big endian format. */
20 png_uint_32
21 png_get_uint_32(png_bytep buf)
22 {
23 png_uint_32 i;
24
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));
29
30 return (i);
31 }
32
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. */
37 png_int_32
38 png_get_int_32(png_bytep buf)
39 {
40 png_int_32 i;
41
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));
46
47 return (i);
48 }
49 #endif /* PNG_READ_pCAL_SUPPORTED */
50
51 /* Grab an unsigned 16-bit integer from a buffer in big endian format. */
52 png_uint_16
53 png_get_uint_16(png_bytep buf)
54 {
55 png_uint_16 i;
56
57 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
58 (png_uint_16)(*(buf + 1)));
59
60 return (i);
61 }
62 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
63
64 /* Read data, and (optionally) run it through the CRC. */
65 void
66 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
67 {
68 png_read_data(png_ptr, buf, length);
69 png_calculate_crc(png_ptr, buf, length);
70 }
71
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. */
76 int
77 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
78 {
79 png_uint_32 i;
80
81 for (i = skip; i > (png_uint_32)png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
82 {
83 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
84 }
85 if (i)
86 {
87 png_crc_read(png_ptr, png_ptr->zbuf, (png_size_t)i);
88 }
89
90 if (png_crc_error(png_ptr))
91 {
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))
96 {
97 png_chunk_warning(png_ptr, "CRC error");
98 }
99 else
100 {
101 png_chunk_error(png_ptr, "CRC error");
102 }
103 return (1);
104 }
105
106 return (0);
107 }
108
109 /* Compare the CRC stored in the PNG file with that calculated by libpng from
110 the data it has read thus far. */
111 int
112 png_crc_error(png_structp png_ptr)
113 {
114 png_byte crc_bytes[4];
115 png_uint_32 crc;
116 int need_crc = 1;
117
118 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
119 {
120 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
121 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
122 need_crc = 0;
123 }
124 else /* critical */
125 {
126 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
127 need_crc = 0;
128 }
129
130 png_read_data(png_ptr, crc_bytes, 4);
131
132 if (need_crc)
133 {
134 crc = png_get_uint_32(crc_bytes);
135 return ((int)(crc != png_ptr->crc));
136 }
137 else
138 return (0);
139 }
140
141
142 /* read and check the IDHR chunk */
143 void
144 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
145 {
146 png_byte buf[13];
147 png_uint_32 width, height;
148 int bit_depth, color_type, compression_type, filter_type;
149 int interlace_type;
150
151 png_debug(1, "in png_handle_IHDR\n");
152
153 if (png_ptr->mode != PNG_BEFORE_IHDR)
154 png_error(png_ptr, "Out of place IHDR");
155
156 /* check the length */
157 if (length != 13)
158 png_error(png_ptr, "Invalid IHDR chunk");
159
160 png_ptr->mode |= PNG_HAVE_IHDR;
161
162 png_crc_read(png_ptr, buf, 13);
163 png_crc_finish(png_ptr, 0);
164
165 width = png_get_uint_32(buf);
166 height = png_get_uint_32(buf + 4);
167 bit_depth = buf[8];
168 color_type = buf[9];
169 compression_type = buf[10];
170 filter_type = buf[11];
171 interlace_type = buf[12];
172
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");
177
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");
182
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");
186
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");
192
193 if (interlace_type >= PNG_INTERLACE_LAST)
194 png_error(png_ptr, "Unknown interlace method in IHDR");
195
196 if (compression_type != PNG_COMPRESSION_TYPE_BASE)
197 png_error(png_ptr, "Unknown compression method in IHDR");
198
199 if (filter_type != PNG_FILTER_TYPE_BASE)
200 png_error(png_ptr, "Unknown filter method in IHDR");
201
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;
208
209 /* find number of channels */
210 switch (png_ptr->color_type)
211 {
212 case PNG_COLOR_TYPE_GRAY:
213 case PNG_COLOR_TYPE_PALETTE:
214 png_ptr->channels = 1;
215 break;
216 case PNG_COLOR_TYPE_RGB:
217 png_ptr->channels = 3;
218 break;
219 case PNG_COLOR_TYPE_GRAY_ALPHA:
220 png_ptr->channels = 2;
221 break;
222 case PNG_COLOR_TYPE_RGB_ALPHA:
223 png_ptr->channels = 4;
224 break;
225 }
226
227 /* set up other useful info */
228 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
229 png_ptr->channels);
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);
237 }
238
239 /* read and check the palette */
240 void
241 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
242 {
243 png_colorp palette;
244 int num, i;
245
246 png_debug(1, "in png_handle_PLTE\n");
247
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)
251 {
252 png_warning(png_ptr, "Invalid PLTE after IDAT");
253 png_crc_finish(png_ptr, length);
254 return;
255 }
256 else if (png_ptr->mode & PNG_HAVE_PLTE)
257 png_error(png_ptr, "Duplicate PLTE chunk");
258
259 png_ptr->mode |= PNG_HAVE_PLTE;
260
261 #if defined (PNG_READ_tRNS_SUPPORTED)
262 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
263 {
264 if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
265 {
266 if (png_ptr->num_trans > png_ptr->num_palette)
267 {
268 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
269 png_ptr->num_trans = png_ptr->num_palette;
270 }
271 }
272 }
273 #endif
274
275 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
276 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
277 {
278 png_crc_finish(png_ptr, length);
279 return;
280 }
281 #endif
282
283 if (length % 3)
284 {
285 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
286 {
287 png_warning(png_ptr, "Invalid palette chunk");
288 png_crc_finish(png_ptr, length);
289 return;
290 }
291 else
292 {
293 png_error(png_ptr, "Invalid palette chunk");
294 }
295 }
296
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++)
301 {
302 png_byte buf[3];
303
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];
309 }
310
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)
317 #endif
318 {
319 png_crc_finish(png_ptr, 0);
320 }
321 #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
322 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
323 {
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))
329 {
330 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
331 {
332 png_chunk_error(png_ptr, "CRC error");
333 }
334 else
335 {
336 png_chunk_warning(png_ptr, "CRC error");
337 png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
338 png_zfree(png_ptr, palette);
339 return;
340 }
341 }
342 /* Otherwise, we (optionally) emit a warning and use the chunk. */
343 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
344 {
345 png_chunk_warning(png_ptr, "CRC error");
346 }
347 }
348 #endif
349 png_ptr->palette = palette;
350 png_ptr->num_palette = (png_uint_16)num;
351 png_set_PLTE(png_ptr, info_ptr, palette, num);
352 }
353
354 void
355 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
356 {
357 png_debug(1, "in png_handle_IEND\n");
358
359 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
360 {
361 png_error(png_ptr, "No image in file");
362
363 /* to quiet compiler warnings about unused info_ptr */
364 if (info_ptr == NULL)
365 return;
366 }
367
368 png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
369
370 if (length != 0)
371 {
372 png_warning(png_ptr, "Incorrect IEND chunk length");
373 }
374 png_crc_finish(png_ptr, length);
375 }
376
377 #if defined(PNG_READ_gAMA_SUPPORTED)
378 void
379 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
380 {
381 png_uint_32 igamma;
382 float file_gamma;
383 png_byte buf[4];
384
385 png_debug(1, "in png_handle_gAMA\n");
386
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)
390 {
391 png_warning(png_ptr, "Invalid gAMA after IDAT");
392 png_crc_finish(png_ptr, length);
393 return;
394 }
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");
398
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)
402 #endif
403 )
404 {
405 png_warning(png_ptr, "Duplicate gAMA chunk");
406 png_crc_finish(png_ptr, length);
407 return;
408 }
409
410 if (length != 4)
411 {
412 png_warning(png_ptr, "Incorrect gAMA chunk length");
413 png_crc_finish(png_ptr, length);
414 return;
415 }
416
417 png_crc_read(png_ptr, buf, 4);
418 if (png_crc_finish(png_ptr, 0))
419 return;
420
421 igamma = png_get_uint_32(buf);
422 /* check for zero gamma */
423 if (igamma == 0)
424 return;
425
426 #if defined(PNG_READ_sRGB_SUPPORTED)
427 if (info_ptr->valid & PNG_INFO_sRGB)
428 if(igamma != (png_uint_32)45000L)
429 {
430 png_warning(png_ptr,
431 "Ignoring incorrect gAMA value when sRGB is also present");
432 #ifndef PNG_NO_STDIO
433 fprintf(stderr, "igamma = %lu\n", igamma);
434 #endif
435 return;
436 }
437 #endif /* PNG_READ_sRGB_SUPPORTED */
438
439 file_gamma = (float)igamma / (float)100000.0;
440 #ifdef PNG_READ_GAMMA_SUPPORTED
441 png_ptr->gamma = file_gamma;
442 #endif
443 png_set_gAMA(png_ptr, info_ptr, file_gamma);
444 }
445 #endif
446
447 #if defined(PNG_READ_sBIT_SUPPORTED)
448 void
449 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
450 {
451 png_size_t truelen;
452 png_byte buf[4];
453
454 png_debug(1, "in png_handle_sBIT\n");
455
456 buf[0] = buf[1] = buf[2] = buf[3] = 0;
457
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)
461 {
462 png_warning(png_ptr, "Invalid sBIT after IDAT");
463 png_crc_finish(png_ptr, length);
464 return;
465 }
466 else if (png_ptr->mode & PNG_HAVE_PLTE)
467 {
468 /* Should be an error, but we can cope with it */
469 png_warning(png_ptr, "Out of place sBIT chunk");
470 }
471 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
472 {
473 png_warning(png_ptr, "Duplicate sBIT chunk");
474 png_crc_finish(png_ptr, length);
475 return;
476 }
477
478 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
479 truelen = 3;
480 else
481 truelen = (png_size_t)png_ptr->channels;
482
483 if (length != truelen)
484 {
485 png_warning(png_ptr, "Incorrect sBIT chunk length");
486 png_crc_finish(png_ptr, length);
487 return;
488 }
489
490 png_crc_read(png_ptr, buf, truelen);
491 if (png_crc_finish(png_ptr, 0))
492 return;
493
494 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
495 {
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];
500 }
501 else
502 {
503 png_ptr->sig_bit.gray = buf[0];
504 png_ptr->sig_bit.alpha = buf[1];
505 }
506 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
507 }
508 #endif
509
510 #if defined(PNG_READ_cHRM_SUPPORTED)
511 void
512 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
513 {
514 png_byte buf[4];
515 png_uint_32 val;
516 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
517
518 png_debug(1, "in png_handle_cHRM\n");
519
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)
523 {
524 png_warning(png_ptr, "Invalid cHRM after IDAT");
525 png_crc_finish(png_ptr, length);
526 return;
527 }
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");
531
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)
535 #endif
536 )
537 {
538 png_warning(png_ptr, "Duplicate cHRM chunk");
539 png_crc_finish(png_ptr, length);
540 return;
541 }
542
543 if (length != 32)
544 {
545 png_warning(png_ptr, "Incorrect cHRM chunk length");
546 png_crc_finish(png_ptr, length);
547 return;
548 }
549
550 png_crc_read(png_ptr, buf, 4);
551 val = png_get_uint_32(buf);
552 white_x = (float)val / (float)100000.0;
553
554 png_crc_read(png_ptr, buf, 4);
555 val = png_get_uint_32(buf);
556 white_y = (float)val / (float)100000.0;
557
558 if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
559 white_x + white_y > 1.0)
560 {
561 png_warning(png_ptr, "Invalid cHRM white point");
562 png_crc_finish(png_ptr, 24);
563 return;
564 }
565
566 png_crc_read(png_ptr, buf, 4);
567 val = png_get_uint_32(buf);
568 red_x = (float)val / (float)100000.0;
569
570 png_crc_read(png_ptr, buf, 4);
571 val = png_get_uint_32(buf);
572 red_y = (float)val / (float)100000.0;
573
574 if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
575 red_x + red_y > 1.0)
576 {
577 png_warning(png_ptr, "Invalid cHRM red point");
578 png_crc_finish(png_ptr, 16);
579 return;
580 }
581
582 png_crc_read(png_ptr, buf, 4);
583 val = png_get_uint_32(buf);
584 green_x = (float)val / (float)100000.0;
585
586 png_crc_read(png_ptr, buf, 4);
587 val = png_get_uint_32(buf);
588 green_y = (float)val / (float)100000.0;
589
590 if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
591 green_x + green_y > 1.0)
592 {
593 png_warning(png_ptr, "Invalid cHRM green point");
594 png_crc_finish(png_ptr, 8);
595 return;
596 }
597
598 png_crc_read(png_ptr, buf, 4);
599 val = png_get_uint_32(buf);
600 blue_x = (float)val / (float)100000.0;
601
602 png_crc_read(png_ptr, buf, 4);
603 val = png_get_uint_32(buf);
604 blue_y = (float)val / (float)100000.0;
605
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)
608 {
609 png_warning(png_ptr, "Invalid cHRM blue point");
610 png_crc_finish(png_ptr, 0);
611 return;
612 }
613
614 if (png_crc_finish(png_ptr, 0))
615 return;
616
617 #if defined(PNG_READ_sRGB_SUPPORTED)
618 if (info_ptr->valid & PNG_INFO_sRGB)
619 {
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)
628 {
629
630 png_warning(png_ptr,
631 "Ignoring incorrect cHRM value when sRGB is also present");
632 #ifndef PNG_NO_STDIO
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);
637 #endif
638 }
639 return;
640 }
641 #endif /* PNG_READ_sRGB_SUPPORTED */
642
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);
645 }
646 #endif
647
648 #if defined(PNG_READ_sRGB_SUPPORTED)
649 void
650 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
651 {
652 int intent;
653 png_byte buf[1];
654
655 png_debug(1, "in png_handle_sRGB\n");
656
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)
660 {
661 png_warning(png_ptr, "Invalid sRGB after IDAT");
662 png_crc_finish(png_ptr, length);
663 return;
664 }
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");
668
669 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sRGB)
670 {
671 png_warning(png_ptr, "Duplicate sRGB chunk");
672 png_crc_finish(png_ptr, length);
673 return;
674 }
675
676 if (length != 1)
677 {
678 png_warning(png_ptr, "Incorrect sRGB chunk length");
679 png_crc_finish(png_ptr, length);
680 return;
681 }
682
683 png_crc_read(png_ptr, buf, 1);
684 if (png_crc_finish(png_ptr, 0))
685 return;
686
687 intent = buf[0];
688 /* check for bad intent */
689 if (intent >= PNG_sRGB_INTENT_LAST)
690 {
691 png_warning(png_ptr, "Unknown sRGB intent");
692 return;
693 }
694
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)
698 {
699 png_warning(png_ptr,
700 "Ignoring incorrect gAMA value when sRGB is also present");
701 #ifndef PNG_NO_STDIO
702 fprintf(stderr,"gamma=%f\n",png_ptr->gamma);
703 #endif
704 }
705 #endif /* PNG_READ_gAMA_SUPPORTED */
706
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)
717 {
718 png_warning(png_ptr,
719 "Ignoring incorrect cHRM value when sRGB is also present");
720 }
721 #endif /* PNG_READ_cHRM_SUPPORTED */
722
723 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
724 }
725 #endif /* PNG_READ_sRGB_SUPPORTED */
726
727 #if defined(PNG_READ_tRNS_SUPPORTED)
728 void
729 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
730 {
731 png_debug(1, "in png_handle_tRNS\n");
732
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)
736 {
737 png_warning(png_ptr, "Invalid tRNS after IDAT");
738 png_crc_finish(png_ptr, length);
739 return;
740 }
741 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
742 {
743 png_warning(png_ptr, "Duplicate tRNS chunk");
744 png_crc_finish(png_ptr, length);
745 return;
746 }
747
748 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
749 {
750 if (!(png_ptr->mode & PNG_HAVE_PLTE))
751 {
752 /* Should be an error, but we can cope with it */
753 png_warning(png_ptr, "Missing PLTE before tRNS");
754 }
755 else if (length > png_ptr->num_palette)
756 {
757 png_warning(png_ptr, "Incorrect tRNS chunk length");
758 png_crc_finish(png_ptr, length);
759 return;
760 }
761
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;
766 }
767 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
768 {
769 png_byte buf[6];
770
771 if (length != 6)
772 {
773 png_warning(png_ptr, "Incorrect tRNS chunk length");
774 png_crc_finish(png_ptr, length);
775 return;
776 }
777
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);
783 }
784 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
785 {
786 png_byte buf[6];
787
788 if (length != 2)
789 {
790 png_warning(png_ptr, "Incorrect tRNS chunk length");
791 png_crc_finish(png_ptr, length);
792 return;
793 }
794
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);
798 }
799 else
800 {
801 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
802 png_crc_finish(png_ptr, length);
803 return;
804 }
805
806 if (png_crc_finish(png_ptr, 0))
807 return;
808
809 png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
810 &(png_ptr->trans_values));
811 }
812 #endif
813
814 #if defined(PNG_READ_bKGD_SUPPORTED)
815 void
816 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
817 {
818 png_size_t truelen;
819 png_byte buf[6];
820
821 png_debug(1, "in png_handle_bKGD\n");
822
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)
826 {
827 png_warning(png_ptr, "Invalid bKGD after IDAT");
828 png_crc_finish(png_ptr, length);
829 return;
830 }
831 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
832 !(png_ptr->mode & PNG_HAVE_PLTE))
833 {
834 png_warning(png_ptr, "Missing PLTE before bKGD");
835 png_crc_finish(png_ptr, length);
836 return;
837 }
838 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
839 {
840 png_warning(png_ptr, "Duplicate bKGD chunk");
841 png_crc_finish(png_ptr, length);
842 return;
843 }
844
845 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
846 truelen = 1;
847 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
848 truelen = 6;
849 else
850 truelen = 2;
851
852 if (length != truelen)
853 {
854 png_warning(png_ptr, "Incorrect bKGD chunk length");
855 png_crc_finish(png_ptr, length);
856 return;
857 }
858
859 png_crc_read(png_ptr, buf, truelen);
860 if (png_crc_finish(png_ptr, 0))
861 return;
862
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)
868 {
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;
873 }
874 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
875 {
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);
880 }
881 else
882 {
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);
886 }
887
888 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
889 }
890 #endif
891
892 #if defined(PNG_READ_hIST_SUPPORTED)
893 void
894 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
895 {
896 int num, i;
897
898 png_debug(1, "in png_handle_hIST\n");
899
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)
903 {
904 png_warning(png_ptr, "Invalid hIST after IDAT");
905 png_crc_finish(png_ptr, length);
906 return;
907 }
908 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
909 {
910 png_warning(png_ptr, "Missing PLTE before hIST");
911 png_crc_finish(png_ptr, length);
912 return;
913 }
914 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
915 {
916 png_warning(png_ptr, "Duplicate hIST chunk");
917 png_crc_finish(png_ptr, length);
918 return;
919 }
920
921 if (length != (png_uint_32)(2 * png_ptr->num_palette))
922 {
923 png_warning(png_ptr, "Incorrect hIST chunk length");
924 png_crc_finish(png_ptr, length);
925 return;
926 }
927
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++)
933 {
934 png_byte buf[2];
935
936 png_crc_read(png_ptr, buf, 2);
937 png_ptr->hist[i] = png_get_uint_16(buf);
938 }
939
940 if (png_crc_finish(png_ptr, 0))
941 return;
942
943 png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
944 }
945 #endif
946
947 #if defined(PNG_READ_pHYs_SUPPORTED)
948 void
949 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
950 {
951 png_byte buf[9];
952 png_uint_32 res_x, res_y;
953 int unit_type;
954
955 png_debug(1, "in png_handle_pHYs\n");
956
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)
960 {
961 png_warning(png_ptr, "Invalid pHYS after IDAT");
962 png_crc_finish(png_ptr, length);
963 return;
964 }
965 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
966 {
967 png_warning(png_ptr, "Duplicate pHYS chunk");
968 png_crc_finish(png_ptr, length);
969 return;
970 }
971
972 if (length != 9)
973 {
974 png_warning(png_ptr, "Incorrect pHYs chunk length");
975 png_crc_finish(png_ptr, length);
976 return;
977 }
978
979 png_crc_read(png_ptr, buf, 9);
980 if (png_crc_finish(png_ptr, 0))
981 return;
982
983 res_x = png_get_uint_32(buf);
984 res_y = png_get_uint_32(buf + 4);
985 unit_type = buf[8];
986 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
987 }
988 #endif
989
990 #if defined(PNG_READ_oFFs_SUPPORTED)
991 void
992 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
993 {
994 png_byte buf[9];
995 png_uint_32 offset_x, offset_y;
996 int unit_type;
997
998 png_debug(1, "in png_handle_oFFs\n");
999
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)
1003 {
1004 png_warning(png_ptr, "Invalid oFFs after IDAT");
1005 png_crc_finish(png_ptr, length);
1006 return;
1007 }
1008 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
1009 {
1010 png_warning(png_ptr, "Duplicate oFFs chunk");
1011 png_crc_finish(png_ptr, length);
1012 return;
1013 }
1014
1015 if (length != 9)
1016 {
1017 png_warning(png_ptr, "Incorrect oFFs chunk length");
1018 png_crc_finish(png_ptr, length);
1019 return;
1020 }
1021
1022 png_crc_read(png_ptr, buf, 9);
1023 if (png_crc_finish(png_ptr, 0))
1024 return;
1025
1026 offset_x = png_get_uint_32(buf);
1027 offset_y = png_get_uint_32(buf + 4);
1028 unit_type = buf[8];
1029 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1030 }
1031 #endif
1032
1033 #if defined(PNG_READ_pCAL_SUPPORTED)
1034 /* read the pCAL chunk (png-scivis-19970203) */
1035 void
1036 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1037 {
1038 png_charp purpose;
1039 png_int_32 X0, X1;
1040 png_byte type, nparams;
1041 png_charp buf, units, endptr;
1042 png_charpp params;
1043 png_size_t slength;
1044 int i;
1045
1046 png_debug(1, "in png_handle_pCAL\n");
1047
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)
1051 {
1052 png_warning(png_ptr, "Invalid pCAL after IDAT");
1053 png_crc_finish(png_ptr, length);
1054 return;
1055 }
1056 else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
1057 {
1058 png_warning(png_ptr, "Duplicate pCAL chunk");
1059 png_crc_finish(png_ptr, length);
1060 return;
1061 }
1062
1063 png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
1064 length + 1);
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);
1068
1069 if (png_crc_finish(png_ptr, 0))
1070 {
1071 png_free(png_ptr, purpose);
1072 return;
1073 }
1074
1075 purpose[slength] = 0x00; /* null terminate the last string */
1076
1077 png_debug(3, "Finding end of pCAL purpose string\n");
1078 for (buf = purpose; *buf != '\0'; buf++)
1079 /* empty loop */ ;
1080
1081 endptr = purpose + slength;
1082
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)
1086 {
1087 png_warning(png_ptr, "Invalid pCAL data");
1088 png_free(png_ptr, purpose);
1089 return;
1090 }
1091
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);
1095 type = buf[9];
1096 nparams = buf[10];
1097 units = buf + 11;
1098
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
1101 equation types. */
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))
1106 {
1107 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1108 png_free(png_ptr, purpose);
1109 return;
1110 }
1111 else if (type >= PNG_EQUATION_LAST)
1112 {
1113 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1114 }
1115
1116 for (buf = units; *buf != 0x00; buf++)
1117 /* Empty loop to move past the units string. */ ;
1118
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))) ;
1122
1123 /* Get pointers to the start of each parameter string. */
1124 for (i = 0; i < (int)nparams; i++)
1125 {
1126 buf++; /* Skip the null string terminator from previous parameter. */
1127
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 */ ;
1131
1132 /* Make sure we haven't run out of data yet */
1133 if (buf > endptr)
1134 {
1135 png_warning(png_ptr, "Invalid pCAL data");
1136 png_free(png_ptr, purpose);
1137 png_free(png_ptr, params);
1138 return;
1139 }
1140 }
1141
1142 png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
1143 units, params);
1144
1145 png_free(png_ptr, purpose);
1146 png_free(png_ptr, params);
1147 }
1148 #endif
1149
1150 #if defined(PNG_READ_tIME_SUPPORTED)
1151 void
1152 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1153 {
1154 png_byte buf[7];
1155 png_time mod_time;
1156
1157 png_debug(1, "in png_handle_tIME\n");
1158
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)
1162 {
1163 png_warning(png_ptr, "Duplicate tIME chunk");
1164 png_crc_finish(png_ptr, length);
1165 return;
1166 }
1167
1168 if (png_ptr->mode & PNG_HAVE_IDAT)
1169 png_ptr->mode |= PNG_AFTER_IDAT;
1170
1171 if (length != 7)
1172 {
1173 png_warning(png_ptr, "Incorrect tIME chunk length");
1174 png_crc_finish(png_ptr, length);
1175 return;
1176 }
1177
1178 png_crc_read(png_ptr, buf, 7);
1179 if (png_crc_finish(png_ptr, 0))
1180 return;
1181
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);
1188
1189 png_set_tIME(png_ptr, info_ptr, &mod_time);
1190 }
1191 #endif
1192
1193 #if defined(PNG_READ_tEXt_SUPPORTED)
1194 /* Note: this does not properly handle chunks that are > 64K under DOS */
1195 void
1196 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1197 {
1198 png_textp text_ptr;
1199 png_charp key;
1200 png_charp text;
1201 png_uint_32 skip = 0;
1202 png_size_t slength;
1203
1204 png_debug(1, "in png_handle_tEXt\n");
1205
1206 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1207 png_error(png_ptr, "Missing IHDR before tEXt");
1208
1209 if (png_ptr->mode & PNG_HAVE_IDAT)
1210 png_ptr->mode |= PNG_AFTER_IDAT;
1211
1212 #ifdef PNG_MAX_MALLOC_64K
1213 if (length > (png_uint_32)65535L)
1214 {
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;
1218 }
1219 #endif
1220
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);
1224
1225 if (png_crc_finish(png_ptr, skip))
1226 {
1227 png_free(png_ptr, key);
1228 return;
1229 }
1230
1231 key[slength] = 0x00;
1232
1233 for (text = key; *text; text++)
1234 /* empty loop to find end of key */ ;
1235
1236 if (text != key + slength)
1237 text++;
1238
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;
1243
1244 png_set_text(png_ptr, info_ptr, text_ptr, 1);
1245
1246 png_free(png_ptr, text_ptr);
1247 }
1248 #endif
1249
1250 #if defined(PNG_READ_zTXt_SUPPORTED)
1251 /* note: this does not correctly handle chunks that are > 64K under DOS */
1252 void
1253 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1254 {
1255 static char msg[] = "Error decoding zTXt chunk";
1256 png_textp text_ptr;
1257 png_charp key;
1258 png_charp text;
1259 int comp_type = PNG_TEXT_COMPRESSION_NONE;
1260 png_size_t slength;
1261
1262 png_debug(1, "in png_handle_zTXt\n");
1263
1264 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1265 png_error(png_ptr, "Missing IHDR before zTXt");
1266
1267 if (png_ptr->mode & PNG_HAVE_IDAT)
1268 png_ptr->mode |= PNG_AFTER_IDAT;
1269
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)
1274 {
1275 png_warning(png_ptr,"zTXt chunk too large to fit in memory");
1276 png_crc_finish(png_ptr, length);
1277 return;
1278 }
1279 #endif
1280
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))
1285 {
1286 png_free(png_ptr, key);
1287 return;
1288 }
1289
1290 key[slength] = 0x00;
1291
1292 for (text = key; *text; text++)
1293 /* empty loop */ ;
1294
1295 /* zTXt must have some text after the keyword */
1296 if (text == key + slength)
1297 {
1298 png_warning(png_ptr, "Zero length zTXt chunk");
1299 }
1300 else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
1301 {
1302 png_size_t text_size, key_size;
1303 text++;
1304
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;
1309
1310 key_size = (png_size_t)(text - key);
1311 text_size = 0;
1312 text = NULL;
1313
1314 while (png_ptr->zstream.avail_in)
1315 {
1316 int ret;
1317
1318 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1319 if (ret != Z_OK && ret != Z_STREAM_END)
1320 {
1321 if (png_ptr->zstream.msg != NULL)
1322 png_warning(png_ptr, png_ptr->zstream.msg);
1323 else
1324 png_warning(png_ptr, msg);
1325 inflateReset(&png_ptr->zstream);
1326 png_ptr->zstream.avail_in = 0;
1327
1328 if (text == NULL)
1329 {
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);
1333 }
1334
1335 text[text_size - 1] = 0x00;
1336
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);
1341 break;
1342 }
1343 if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
1344 {
1345 if (text == NULL)
1346 {
1347 text = (png_charp)png_malloc(png_ptr,
1348 (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
1349 + key_size + 1));
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;
1356 }
1357 else
1358 {
1359 png_charp tmp;
1360
1361 tmp = text;
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;
1370 }
1371 if (ret != Z_STREAM_END)
1372 {
1373 png_ptr->zstream.next_out = png_ptr->zbuf;
1374 png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1375 }
1376 else
1377 {
1378 break;
1379 }
1380 }
1381 }
1382
1383 inflateReset(&png_ptr->zstream);
1384 png_ptr->zstream.avail_in = 0;
1385
1386 png_free(png_ptr, key);
1387 key = text;
1388 text += key_size;
1389 }
1390 else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
1391 {
1392 png_size_t text_size;
1393 #if !defined(PNG_NO_STDIO)
1394 char umsg[50];
1395
1396 sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
1397 png_warning(png_ptr, umsg);
1398 #else
1399 png_warning(png_ptr, "Unknown zTXt compression type");
1400 #endif
1401
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);
1406 }
1407
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;
1412
1413 png_set_text(png_ptr, info_ptr, text_ptr, 1);
1414
1415 png_free(png_ptr, text_ptr);
1416 }
1417 #endif
1418
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. */
1422 void
1423 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1424 {
1425 png_debug(1, "in png_handle_unknown\n");
1426
1427 /* In the future we can have code here that calls user-supplied
1428 * callback functions for unknown chunks before they are ignored or
1429 * cause an error.
1430 */
1431 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
1432
1433 if (!(png_ptr->chunk_name[0] & 0x20))
1434 {
1435 png_chunk_error(png_ptr, "unknown critical chunk");
1436
1437 /* to quiet compiler warnings about unused info_ptr */
1438 if (info_ptr == NULL)
1439 return;
1440 }
1441
1442 if (png_ptr->mode & PNG_HAVE_IDAT)
1443 png_ptr->mode |= PNG_AFTER_IDAT;
1444
1445 png_crc_finish(png_ptr, length);
1446
1447 }
1448
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. */
1454
1455 #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
1456
1457 void
1458 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
1459 {
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]))
1463 {
1464 png_chunk_error(png_ptr, "invalid chunk type");
1465 }
1466 }
1467
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. */
1478 void
1479 png_combine_row(png_structp png_ptr, png_bytep row,
1480 int mask)
1481 {
1482 png_debug(1,"in png_combine_row\n");
1483 if (mask == 0xff)
1484 {
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));
1488 }
1489 else
1490 {
1491 switch (png_ptr->row_info.pixel_depth)
1492 {
1493 case 1:
1494 {
1495 png_bytep sp;
1496 png_bytep dp;
1497 int s_inc, s_start, s_end;
1498 int m;
1499 int shift;
1500 png_uint_32 i;
1501
1502 sp = png_ptr->row_buf + 1;
1503 dp = row;
1504 m = 0x80;
1505 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1506 if (png_ptr->transformations & PNG_PACKSWAP)
1507 {
1508 s_start = 0;
1509 s_end = 7;
1510 s_inc = 1;
1511 }
1512 else
1513 #endif
1514 {
1515 s_start = 7;
1516 s_end = 0;
1517 s_inc = -1;
1518 }
1519
1520 shift = s_start;
1521
1522 for (i = 0; i < png_ptr->width; i++)
1523 {
1524 if (m & mask)
1525 {
1526 int value;
1527
1528 value = (*sp >> shift) & 0x1;
1529 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
1530 *dp |= (png_byte)(value << shift);
1531 }
1532
1533 if (shift == s_end)
1534 {
1535 shift = s_start;
1536 sp++;
1537 dp++;
1538 }
1539 else
1540 shift += s_inc;
1541
1542 if (m == 1)
1543 m = 0x80;
1544 else
1545 m >>= 1;
1546 }
1547 break;
1548 }
1549 case 2:
1550 {
1551 png_bytep sp;
1552 png_bytep dp;
1553 int s_start, s_end, s_inc;
1554 int m;
1555 int shift;
1556 png_uint_32 i;
1557 int value;
1558
1559 sp = png_ptr->row_buf + 1;
1560 dp = row;
1561 m = 0x80;
1562 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1563 if (png_ptr->transformations & PNG_PACKSWAP)
1564 {
1565 s_start = 0;
1566 s_end = 6;
1567 s_inc = 2;
1568 }
1569 else
1570 #endif
1571 {
1572 s_start = 6;
1573 s_end = 0;
1574 s_inc = -2;
1575 }
1576
1577 shift = s_start;
1578
1579 for (i = 0; i < png_ptr->width; i++)
1580 {
1581 if (m & mask)
1582 {
1583 value = (*sp >> shift) & 0x3;
1584 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
1585 *dp |= (png_byte)(value << shift);
1586 }
1587
1588 if (shift == s_end)
1589 {
1590 shift = s_start;
1591 sp++;
1592 dp++;
1593 }
1594 else
1595 shift += s_inc;
1596 if (m == 1)
1597 m = 0x80;
1598 else
1599 m >>= 1;
1600 }
1601 break;
1602 }
1603 case 4:
1604 {
1605 png_bytep sp;
1606 png_bytep dp;
1607 int s_start, s_end, s_inc;
1608 int m;
1609 int shift;
1610 png_uint_32 i;
1611 int value;
1612
1613 sp = png_ptr->row_buf + 1;
1614 dp = row;
1615 m = 0x80;
1616 #if defined(PNG_READ_PACKSWAP_SUPPORTED)
1617 if (png_ptr->transformations & PNG_PACKSWAP)
1618 {
1619 s_start = 0;
1620 s_end = 4;
1621 s_inc = 4;
1622 }
1623 else
1624 #endif
1625 {
1626 s_start = 4;
1627 s_end = 0;
1628 s_inc = -4;
1629 }
1630 shift = s_start;
1631
1632 for (i = 0; i < png_ptr->width; i++)
1633 {
1634 if (m & mask)
1635 {
1636 value = (*sp >> shift) & 0xf;
1637 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
1638 *dp |= (png_byte)(value << shift);
1639 }
1640
1641 if (shift == s_end)
1642 {
1643 shift = s_start;
1644 sp++;
1645 dp++;
1646 }
1647 else
1648 shift += s_inc;
1649 if (m == 1)
1650 m = 0x80;
1651 else
1652 m >>= 1;
1653 }
1654 break;
1655 }
1656 default:
1657 {
1658 png_bytep sp;
1659 png_bytep dp;
1660 png_size_t pixel_bytes;
1661 png_uint_32 i;
1662 png_byte m;
1663
1664 pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
1665
1666 sp = png_ptr->row_buf + 1;
1667 dp = row;
1668 m = 0x80;
1669 for (i = 0; i < png_ptr->width; i++)
1670 {
1671 if (m & mask)
1672 {
1673 png_memcpy(dp, sp, pixel_bytes);
1674 }
1675
1676 sp += pixel_bytes;
1677 dp += pixel_bytes;
1678
1679 if (m == 1)
1680 m = 0x80;
1681 else
1682 m >>= 1;
1683 }
1684 break;
1685 }
1686 }
1687 }
1688 }
1689
1690 #if defined(PNG_READ_INTERLACING_SUPPORTED)
1691 void
1692 png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
1693 png_uint_32 transformations)
1694 {
1695 png_debug(1,"in png_do_read_interlace\n");
1696 if (row != NULL && row_info != NULL)
1697 {
1698 png_uint_32 final_width;
1699
1700 final_width = row_info->width * png_pass_inc[pass];
1701
1702 switch (row_info->pixel_depth)
1703 {
1704 case 1:
1705 {
1706 png_bytep sp, dp;
1707 int sshift, dshift;
1708 int s_start, s_end, s_inc;
1709 png_byte v;
1710 png_uint_32 i;
1711 int j;
1712
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)
1717 {
1718 sshift = (int)((row_info->width + 7) & 7);
1719 dshift = (int)((final_width + 7) & 7);
1720 s_start = 7;
1721 s_end = 0;
1722 s_inc = -1;
1723 }
1724 else
1725 #endif
1726 {
1727 sshift = 7 - (int)((row_info->width + 7) & 7);
1728 dshift = 7 - (int)((final_width + 7) & 7);
1729 s_start = 0;
1730 s_end = 7;
1731 s_inc = 1;
1732 }
1733
1734 for (i = row_info->width; i; i--)
1735 {
1736 v = (png_byte)((*sp >> sshift) & 0x1);
1737 for (j = 0; j < png_pass_inc[pass]; j++)
1738 {
1739 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
1740 *dp |= (png_byte)(v << dshift);
1741 if (dshift == s_end)
1742 {
1743 dshift = s_start;
1744 dp--;
1745 }
1746 else
1747 dshift += s_inc;
1748 }
1749 if (sshift == s_end)
1750 {
1751 sshift = s_start;
1752 sp--;
1753 }
1754 else
1755 sshift += s_inc;
1756 }
1757 break;
1758 }
1759 case 2:
1760 {
1761 png_bytep sp, dp;
1762 int sshift, dshift;
1763 int s_start, s_end, s_inc;
1764 png_uint_32 i;
1765
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)
1770 {
1771 sshift = (int)(((row_info->width + 3) & 3) << 1);
1772 dshift = (int)(((final_width + 3) & 3) << 1);
1773 s_start = 6;
1774 s_end = 0;
1775 s_inc = -2;
1776 }
1777 else
1778 #endif
1779 {
1780 sshift = (int)((3 - ((row_info->width + 3) & 3)) << 1);
1781 dshift = (int)((3 - ((final_width + 3) & 3)) << 1);
1782 s_start = 0;
1783 s_end = 6;
1784 s_inc = 2;
1785 }
1786
1787 for (i = row_info->width; i; i--)
1788 {
1789 png_byte v;
1790 int j;
1791
1792 v = (png_byte)((*sp >> sshift) & 0x3);
1793 for (j = 0; j < png_pass_inc[pass]; j++)
1794 {
1795 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
1796 *dp |= (png_byte)(v << dshift);
1797 if (dshift == s_end)
1798 {
1799 dshift = s_start;
1800 dp--;
1801 }
1802 else
1803 dshift += s_inc;
1804 }
1805 if (sshift == s_end)
1806 {
1807 sshift = s_start;
1808 sp--;
1809 }
1810 else
1811 sshift += s_inc;
1812 }
1813 break;
1814 }
1815 case 4:
1816 {
1817 png_bytep sp, dp;
1818 int sshift, dshift;
1819 int s_start, s_end, s_inc;
1820 png_uint_32 i;
1821
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)
1826 {
1827 sshift = (int)(((row_info->width + 1) & 1) << 2);
1828 dshift = (int)(((final_width + 1) & 1) << 2);
1829 s_start = 4;
1830 s_end = 0;
1831 s_inc = -4;
1832 }
1833 else
1834 #endif
1835 {
1836 sshift = (int)((1 - ((row_info->width + 1) & 1)) << 2);
1837 dshift = (int)((1 - ((final_width + 1) & 1)) << 2);
1838 s_start = 0;
1839 s_end = 4;
1840 s_inc = 4;
1841 }
1842
1843 for (i = row_info->width; i; i--)
1844 {
1845 png_byte v;
1846 int j;
1847
1848 v = (png_byte)((*sp >> sshift) & 0xf);
1849 for (j = 0; j < png_pass_inc[pass]; j++)
1850 {
1851 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
1852 *dp |= (png_byte)(v << dshift);
1853 if (dshift == s_end)
1854 {
1855 dshift = s_start;
1856 dp--;
1857 }
1858 else
1859 dshift += s_inc;
1860 }
1861 if (sshift == s_end)
1862 {
1863 sshift = s_start;
1864 sp--;
1865 }
1866 else
1867 sshift += s_inc;
1868 }
1869 break;
1870 }
1871 default:
1872 {
1873 png_bytep sp, dp;
1874 png_uint_32 i;
1875 png_size_t pixel_bytes;
1876
1877 pixel_bytes = (row_info->pixel_depth >> 3);
1878
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--)
1882 {
1883 png_byte v[8];
1884 int j;
1885
1886 png_memcpy(v, sp, pixel_bytes);
1887 for (j = 0; j < png_pass_inc[pass]; j++)
1888 {
1889 png_memcpy(dp, v, pixel_bytes);
1890 dp -= pixel_bytes;
1891 }
1892 sp -= pixel_bytes;
1893 }
1894 break;
1895 }
1896 }
1897 row_info->width = final_width;
1898 row_info->rowbytes = ((final_width *
1899 (png_uint_32)row_info->pixel_depth + 7) >> 3);
1900 }
1901 }
1902 #endif
1903
1904 void
1905 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
1906 png_bytep prev_row, int filter)
1907 {
1908 png_debug(1, "in png_read_filter_row\n");
1909 png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
1910
1911
1912 switch (filter)
1913 {
1914 case PNG_FILTER_VALUE_NONE:
1915 break;
1916 case PNG_FILTER_VALUE_SUB:
1917 {
1918 png_uint_32 i;
1919 int bpp;
1920 png_bytep rp;
1921 png_bytep lp;
1922
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++)
1926 {
1927 *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
1928 }
1929 break;
1930 }
1931 case PNG_FILTER_VALUE_UP:
1932 {
1933 png_uint_32 i;
1934 png_bytep rp;
1935 png_bytep pp;
1936
1937 for (i = 0, rp = row, pp = prev_row;
1938 i < row_info->rowbytes; i++, rp++, pp++)
1939 {
1940 *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
1941 }
1942 break;
1943 }
1944 case PNG_FILTER_VALUE_AVG:
1945 {
1946 png_uint_32 i;
1947 int bpp;
1948 png_bytep rp;
1949 png_bytep pp;
1950 png_bytep lp;
1951
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++)
1955 {
1956 *rp = (png_byte)(((int)(*rp) +
1957 ((int)(*pp) / 2)) & 0xff);
1958 }
1959 for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
1960 {
1961 *rp = (png_byte)(((int)(*rp) +
1962 (int)(*pp + *lp) / 2) & 0xff);
1963 }
1964 break;
1965 }
1966 case PNG_FILTER_VALUE_PAETH:
1967 {
1968 int bpp;
1969 png_uint_32 i;
1970 png_bytep rp;
1971 png_bytep pp;
1972 png_bytep lp;
1973 png_bytep cp;
1974
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++)
1979 {
1980 int a, b, c, pa, pb, pc, p;
1981
1982 b = *pp;
1983 if (i >= (png_uint_32)bpp)
1984 {
1985 c = *cp;
1986 a = *lp;
1987 }
1988 else
1989 {
1990 a = c = 0;
1991 }
1992 p = a + b - c;
1993 pa = abs(p - a);
1994 pb = abs(p - b);
1995 pc = abs(p - c);
1996
1997 if (pa <= pb && pa <= pc)
1998 p = a;
1999 else if (pb <= pc)
2000 p = b;
2001 else
2002 p = c;
2003
2004 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
2005 }
2006 break;
2007 }
2008 default:
2009 png_error(png_ptr, "Bad adaptive filter type");
2010 break;
2011 }
2012 }
2013
2014 void
2015 png_read_finish_row(png_structp png_ptr)
2016 {
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)
2020 return;
2021
2022 if (png_ptr->interlaced)
2023 {
2024 png_ptr->row_number = 0;
2025 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2026 do
2027 {
2028 png_ptr->pass++;
2029 if (png_ptr->pass >= 7)
2030 break;
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;
2037
2038 if (!(png_ptr->transformations & PNG_INTERLACE))
2039 {
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))
2045 continue;
2046 }
2047 if (png_ptr->transformations & PNG_INTERLACE)
2048 break;
2049 } while (png_ptr->iwidth == 0);
2050
2051 if (png_ptr->pass < 7)
2052 return;
2053 }
2054
2055 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
2056 {
2057 char extra;
2058 int ret;
2059
2060 png_ptr->zstream.next_out = (Byte *)&extra;
2061 png_ptr->zstream.avail_out = (uInt)1;
2062 for(;;)
2063 {
2064 if (!(png_ptr->zstream.avail_in))
2065 {
2066 while (!png_ptr->idat_size)
2067 {
2068 png_byte chunk_length[4];
2069
2070 png_crc_finish(png_ptr, 0);
2071
2072 png_read_data(png_ptr, chunk_length, 4);
2073 png_ptr->idat_size = png_get_uint_32(chunk_length);
2074
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");
2079
2080 }
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;
2087 }
2088 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2089 if (ret == Z_STREAM_END)
2090 {
2091 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
2092 png_ptr->idat_size)
2093 png_error(png_ptr, "Extra compressed data");
2094 png_ptr->mode |= PNG_AFTER_IDAT;
2095 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
2096 break;
2097 }
2098 if (ret != Z_OK)
2099 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
2100 "Decompression Error");
2101
2102 if (!(png_ptr->zstream.avail_out))
2103 png_error(png_ptr, "Extra compressed data");
2104
2105 }
2106 png_ptr->zstream.avail_out = 0;
2107 }
2108
2109 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
2110 png_error(png_ptr, "Extra compression data");
2111
2112 inflateReset(&png_ptr->zstream);
2113
2114 png_ptr->mode |= PNG_AFTER_IDAT;
2115 }
2116
2117 void
2118 png_read_start_row(png_structp png_ptr)
2119 {
2120 int max_pixel_depth;
2121 png_uint_32 rowbytes;
2122
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)
2127 {
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];
2131 else
2132 png_ptr->num_rows = png_ptr->height;
2133
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];
2138
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");
2144 }
2145 else
2146 {
2147 png_ptr->num_rows = png_ptr->height;
2148 png_ptr->iwidth = png_ptr->width;
2149 png_ptr->irowbytes = png_ptr->rowbytes + 1;
2150 }
2151 max_pixel_depth = png_ptr->pixel_depth;
2152
2153 #if defined(PNG_READ_PACK_SUPPORTED)
2154 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
2155 max_pixel_depth = 8;
2156 #endif
2157
2158 #if defined(PNG_READ_EXPAND_SUPPORTED)
2159 if (png_ptr->transformations & PNG_EXPAND)
2160 {
2161 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
2162 {
2163 if (png_ptr->num_trans)
2164 max_pixel_depth = 32;
2165 else
2166 max_pixel_depth = 24;
2167 }
2168 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
2169 {
2170 if (max_pixel_depth < 8)
2171 max_pixel_depth = 8;
2172 if (png_ptr->num_trans)
2173 max_pixel_depth *= 2;
2174 }
2175 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
2176 {
2177 if (png_ptr->num_trans)
2178 {
2179 max_pixel_depth *= 4;
2180 max_pixel_depth /= 3;
2181 }
2182 }
2183 }
2184 #endif
2185
2186 #if defined(PNG_READ_FILLER_SUPPORTED)
2187 if (png_ptr->transformations & (PNG_FILLER))
2188 {
2189 if (max_pixel_depth < 32)
2190 max_pixel_depth = 32;
2191 }
2192 #endif
2193
2194 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
2195 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
2196 {
2197 if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
2198 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
2199 {
2200 if (max_pixel_depth <= 16)
2201 max_pixel_depth = 32;
2202 else if (max_pixel_depth <= 32)
2203 max_pixel_depth = 64;
2204 }
2205 else
2206 {
2207 if (max_pixel_depth <= 8)
2208 max_pixel_depth = 24;
2209 else if (max_pixel_depth <= 16)
2210 max_pixel_depth = 48;
2211 }
2212 }
2213 #endif
2214
2215 /* align the width on the next larger 8 pixels. Mainly used
2216 for interlacing */
2217 rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
2218 /* calculate the maximum bytes needed, adding a byte and a pixel
2219 for safety sake */
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");
2225 #endif
2226 png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, rowbytes);
2227
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");
2231 #endif
2232 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
2233 png_ptr->rowbytes + 1));
2234
2235 png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
2236
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);
2243
2244 png_ptr->flags |= PNG_FLAG_ROW_INIT;
2245 }