1
2 /* pngrutil.c - utilities to read a PNG file
3 *
4 * Last changed in libpng 1.2.45 [July 7, 2011]
5 * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 *
9 * This code is released under the libpng license.
10 * For conditions of distribution and use, see the disclaimer
11 * and license in png.h
12 *
13 * This file contains routines that are only called from within
14 * libpng itself during the course of reading an image.
15 */
16
17 #define PNG_INTERNAL
18 #define PNG_NO_PEDANTIC_WARNINGS
19 #include "png.h"
20 #ifdef PNG_READ_SUPPORTED
21
22 #if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
23 # define WIN32_WCE_OLD
24 #endif
25
26 #ifdef PNG_FLOATING_POINT_SUPPORTED
27 # ifdef WIN32_WCE_OLD
28 /* The strtod() function is not supported on WindowsCE */
png_strtod(png_structp png_ptr,PNG_CONST char * nptr,char ** endptr)29 __inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
30 char **endptr)
31 {
32 double result = 0;
33 int len;
34 wchar_t *str, *end;
35
36 len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
37 str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
38 if ( NULL != str )
39 {
40 MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
41 result = wcstod(str, &end);
42 len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
43 *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
44 png_free(png_ptr, str);
45 }
46 return result;
47 }
48 # else
49 # define png_strtod(p,a,b) strtod(a,b)
50 # endif
51 #endif
52
53 png_uint_32 PNGAPI
png_get_uint_31(png_structp png_ptr,png_bytep buf)54 png_get_uint_31(png_structp png_ptr, png_bytep buf)
55 {
56 #ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
57 png_uint_32 i = png_get_uint_32(buf);
58 #else
59 /* Avoid an extra function call by inlining the result. */
60 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
61 ((png_uint_32)(*(buf + 1)) << 16) +
62 ((png_uint_32)(*(buf + 2)) << 8) +
63 (png_uint_32)(*(buf + 3));
64 #endif
65 if (i > PNG_UINT_31_MAX)
66 png_error(png_ptr, "PNG unsigned integer out of range.");
67 return (i);
68 }
69 #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
70 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
71 png_uint_32 PNGAPI
png_get_uint_32(png_bytep buf)72 png_get_uint_32(png_bytep buf)
73 {
74 png_uint_32 i = ((png_uint_32)(*buf) << 24) +
75 ((png_uint_32)(*(buf + 1)) << 16) +
76 ((png_uint_32)(*(buf + 2)) << 8) +
77 (png_uint_32)(*(buf + 3));
78
79 return (i);
80 }
81
82 /* Grab a signed 32-bit integer from a buffer in big-endian format. The
83 * data is stored in the PNG file in two's complement format, and it is
84 * assumed that the machine format for signed integers is the same.
85 */
86 png_int_32 PNGAPI
png_get_int_32(png_bytep buf)87 png_get_int_32(png_bytep buf)
88 {
89 png_int_32 i = ((png_int_32)(*buf) << 24) +
90 ((png_int_32)(*(buf + 1)) << 16) +
91 ((png_int_32)(*(buf + 2)) << 8) +
92 (png_int_32)(*(buf + 3));
93
94 return (i);
95 }
96
97 /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98 png_uint_16 PNGAPI
png_get_uint_16(png_bytep buf)99 png_get_uint_16(png_bytep buf)
100 {
101 png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
102 (png_uint_16)(*(buf + 1)));
103
104 return (i);
105 }
106 #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
107
108 /* Read the chunk header (length + type name).
109 * Put the type name into png_ptr->chunk_name, and return the length.
110 */
111 png_uint_32 /* PRIVATE */
png_read_chunk_header(png_structp png_ptr)112 png_read_chunk_header(png_structp png_ptr)
113 {
114 png_byte buf[8];
115 png_uint_32 length;
116
117 /* Read the length and the chunk name */
118 png_read_data(png_ptr, buf, 8);
119 length = png_get_uint_31(png_ptr, buf);
120
121 /* Put the chunk name into png_ptr->chunk_name */
122 png_memcpy(png_ptr->chunk_name, buf + 4, 4);
123
124 png_debug2(0, "Reading %s chunk, length = %lu",
125 png_ptr->chunk_name, length);
126
127 /* Reset the crc and run it over the chunk name */
128 png_reset_crc(png_ptr);
129 png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
130
131 /* Check to see if chunk name is valid */
132 png_check_chunk_name(png_ptr, png_ptr->chunk_name);
133
134 return length;
135 }
136
137 /* Read data, and (optionally) run it through the CRC. */
138 void /* PRIVATE */
png_crc_read(png_structp png_ptr,png_bytep buf,png_size_t length)139 png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
140 {
141 if (png_ptr == NULL)
142 return;
143 png_read_data(png_ptr, buf, length);
144 png_calculate_crc(png_ptr, buf, length);
145 }
146
147 #ifdef PNG_INDEX_SUPPORTED
148 /* Optionally skip data and then check the CRC. Depending on whether we
149 * are reading a ancillary or critical chunk, and how the program has set
150 * things up, we may calculate the CRC on the data and print a message.
151 * Returns '1' if there was a CRC error, '0' otherwise.
152 */
153 int /* PRIVATE */
png_opt_crc_finish(png_structp png_ptr,png_uint_32 skip,int check_crc)154 png_opt_crc_finish(png_structp png_ptr, png_uint_32 skip, int check_crc)
155 {
156 png_size_t i;
157 png_size_t istop = png_ptr->zbuf_size;
158
159 for (i = (png_size_t)skip; i > istop; i -= istop)
160 {
161 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
162 }
163 if (i)
164 {
165 png_crc_read(png_ptr, png_ptr->zbuf, i);
166 }
167
168 if (png_crc_error(png_ptr))
169 {
170 if (!check_crc) {
171 png_chunk_warning(png_ptr, "CRC error");
172 return (1);
173 }
174 if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
175 !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
176 (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
177 (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
178 {
179 png_chunk_warning(png_ptr, "CRC error");
180 }
181 else
182 {
183 png_chunk_error(png_ptr, "CRC error");
184 }
185 return (1);
186 }
187
188 return (0);
189 }
190 #endif
191
192 /* Optionally skip data and then check the CRC. Depending on whether we
193 * are reading a ancillary or critical chunk, and how the program has set
194 * things up, we may calculate the CRC on the data and print a message.
195 * Returns '1' if there was a CRC error, '0' otherwise.
196 */
197 int /* PRIVATE */
png_crc_finish(png_structp png_ptr,png_uint_32 skip)198 png_crc_finish(png_structp png_ptr, png_uint_32 skip)
199 {
200 return png_opt_crc_finish(png_ptr, skip, 1);
201 }
202
203 /* Compare the CRC stored in the PNG file with that calculated by libpng from
204 * the data it has read thus far.
205 */
206 int /* PRIVATE */
png_crc_error(png_structp png_ptr)207 png_crc_error(png_structp png_ptr)
208 {
209 png_byte crc_bytes[4];
210 png_uint_32 crc;
211 int need_crc = 1;
212
213 if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
214 {
215 if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
216 (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
217 need_crc = 0;
218 }
219 else /* critical */
220 {
221 if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
222 need_crc = 0;
223 }
224
225 png_read_data(png_ptr, crc_bytes, 4);
226
227 if (need_crc)
228 {
229 crc = png_get_uint_32(crc_bytes);
230 return ((int)(crc != png_ptr->crc));
231 }
232 else
233 return (0);
234 }
235
236 #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
237 defined(PNG_READ_iCCP_SUPPORTED)
238 static png_size_t
png_inflate(png_structp png_ptr,const png_byte * data,png_size_t size,png_bytep output,png_size_t output_size)239 png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
240 png_bytep output, png_size_t output_size)
241 {
242 png_size_t count = 0;
243
244 png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
245 png_ptr->zstream.avail_in = size;
246
247 while (1)
248 {
249 int ret, avail;
250
251 /* Reset the output buffer each time round - we empty it
252 * after every inflate call.
253 */
254 png_ptr->zstream.next_out = png_ptr->zbuf;
255 png_ptr->zstream.avail_out = png_ptr->zbuf_size;
256
257 ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
258 avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
259
260 /* First copy/count any new output - but only if we didn't
261 * get an error code.
262 */
263 if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
264 {
265 if (output != 0 && output_size > count)
266 {
267 int copy = output_size - count;
268 if (avail < copy) copy = avail;
269 png_memcpy(output + count, png_ptr->zbuf, copy);
270 }
271 count += avail;
272 }
273
274 if (ret == Z_OK)
275 continue;
276
277 /* Termination conditions - always reset the zstream, it
278 * must be left in inflateInit state.
279 */
280 png_ptr->zstream.avail_in = 0;
281 inflateReset(&png_ptr->zstream);
282
283 if (ret == Z_STREAM_END)
284 return count; /* NOTE: may be zero. */
285
286 /* Now handle the error codes - the API always returns 0
287 * and the error message is dumped into the uncompressed
288 * buffer if available.
289 */
290 {
291 PNG_CONST char *msg;
292 if (png_ptr->zstream.msg != 0)
293 msg = png_ptr->zstream.msg;
294 else
295 {
296 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
297 char umsg[52];
298
299 switch (ret)
300 {
301 case Z_BUF_ERROR:
302 msg = "Buffer error in compressed datastream in %s chunk";
303 break;
304 case Z_DATA_ERROR:
305 msg = "Data error in compressed datastream in %s chunk";
306 break;
307 default:
308 msg = "Incomplete compressed datastream in %s chunk";
309 break;
310 }
311
312 png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
313 msg = umsg;
314 #else
315 msg = "Damaged compressed datastream in chunk other than IDAT";
316 #endif
317 }
318
319 png_warning(png_ptr, msg);
320 }
321
322 /* 0 means an error - notice that this code simple ignores
323 * zero length compressed chunks as a result.
324 */
325 return 0;
326 }
327 }
328
329 /*
330 * Decompress trailing data in a chunk. The assumption is that chunkdata
331 * points at an allocated area holding the contents of a chunk with a
332 * trailing compressed part. What we get back is an allocated area
333 * holding the original prefix part and an uncompressed version of the
334 * trailing part (the malloc area passed in is freed).
335 */
336 void /* PRIVATE */
png_decompress_chunk(png_structp png_ptr,int comp_type,png_size_t chunklength,png_size_t prefix_size,png_size_t * newlength)337 png_decompress_chunk(png_structp png_ptr, int comp_type,
338 png_size_t chunklength,
339 png_size_t prefix_size, png_size_t *newlength)
340 {
341 /* The caller should guarantee this */
342 if (prefix_size > chunklength)
343 {
344 /* The recovery is to delete the chunk. */
345 png_warning(png_ptr, "invalid chunklength");
346 prefix_size = 0; /* To delete everything */
347 }
348
349 else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
350 {
351 png_size_t expanded_size = png_inflate(png_ptr,
352 (png_bytep)(png_ptr->chunkdata + prefix_size),
353 chunklength - prefix_size,
354 0/*output*/, 0/*output size*/);
355
356 /* Now check the limits on this chunk - if the limit fails the
357 * compressed data will be removed, the prefix will remain.
358 */
359 #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
360 if (png_ptr->user_chunk_malloc_max &&
361 (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
362 #else
363 # ifdef PNG_USER_CHUNK_MALLOC_MAX
364 if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
365 prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
366 # endif
367 #endif
368 png_warning(png_ptr, "Exceeded size limit while expanding chunk");
369
370 /* If the size is zero either there was an error and a message
371 * has already been output (warning) or the size really is zero
372 * and we have nothing to do - the code will exit through the
373 * error case below.
374 */
375 #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
376 defined(PNG_USER_CHUNK_MALLOC_MAX)
377 else
378 #endif
379 if (expanded_size > 0)
380 {
381 /* Success (maybe) - really uncompress the chunk. */
382 png_size_t new_size = 0;
383 png_charp text = png_malloc_warn(png_ptr,
384 prefix_size + expanded_size + 1);
385
386 if (text != NULL)
387 {
388 png_memcpy(text, png_ptr->chunkdata, prefix_size);
389 new_size = png_inflate(png_ptr,
390 (png_bytep)(png_ptr->chunkdata + prefix_size),
391 chunklength - prefix_size,
392 (png_bytep)(text + prefix_size), expanded_size);
393 text[prefix_size + expanded_size] = 0; /* just in case */
394
395 if (new_size == expanded_size)
396 {
397 png_free(png_ptr, png_ptr->chunkdata);
398 png_ptr->chunkdata = text;
399 *newlength = prefix_size + expanded_size;
400 return; /* The success return! */
401 }
402
403 png_warning(png_ptr, "png_inflate logic error");
404 png_free(png_ptr, text);
405 }
406 else
407 png_warning(png_ptr, "Not enough memory to decompress chunk.");
408 }
409 }
410
411 else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
412 {
413 #if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
414 char umsg[50];
415
416 png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
417 comp_type);
418 png_warning(png_ptr, umsg);
419 #else
420 png_warning(png_ptr, "Unknown zTXt compression type");
421 #endif
422
423 /* The recovery is to simply drop the data. */
424 }
425
426 /* Generic error return - leave the prefix, delete the compressed
427 * data, reallocate the chunkdata to remove the potentially large
428 * amount of compressed data.
429 */
430 {
431 png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
432 if (text != NULL)
433 {
434 if (prefix_size > 0)
435 png_memcpy(text, png_ptr->chunkdata, prefix_size);
436 png_free(png_ptr, png_ptr->chunkdata);
437 png_ptr->chunkdata = text;
438
439 /* This is an extra zero in the 'uncompressed' part. */
440 *(png_ptr->chunkdata + prefix_size) = 0x00;
441 }
442 /* Ignore a malloc error here - it is safe. */
443 }
444
445 *newlength = prefix_size;
446 }
447 #endif
448
449 /* Read and check the IDHR chunk */
450 void /* PRIVATE */
png_handle_IHDR(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)451 png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
452 {
453 png_byte buf[13];
454 png_uint_32 width, height;
455 int bit_depth, color_type, compression_type, filter_type;
456 int interlace_type;
457
458 png_debug(1, "in png_handle_IHDR");
459
460 if (png_ptr->mode & PNG_HAVE_IHDR)
461 png_error(png_ptr, "Out of place IHDR");
462
463 /* Check the length */
464 if (length != 13)
465 png_error(png_ptr, "Invalid IHDR chunk");
466
467 png_ptr->mode |= PNG_HAVE_IHDR;
468
469 png_crc_read(png_ptr, buf, 13);
470 png_crc_finish(png_ptr, 0);
471
472 width = png_get_uint_31(png_ptr, buf);
473 height = png_get_uint_31(png_ptr, buf + 4);
474 bit_depth = buf[8];
475 color_type = buf[9];
476 compression_type = buf[10];
477 filter_type = buf[11];
478 interlace_type = buf[12];
479
480 /* Set internal variables */
481 png_ptr->width = width;
482 png_ptr->height = height;
483 png_ptr->bit_depth = (png_byte)bit_depth;
484 png_ptr->interlaced = (png_byte)interlace_type;
485 png_ptr->color_type = (png_byte)color_type;
486 #ifdef PNG_MNG_FEATURES_SUPPORTED
487 png_ptr->filter_type = (png_byte)filter_type;
488 #endif
489 png_ptr->compression_type = (png_byte)compression_type;
490
491 /* Find number of channels */
492 switch (png_ptr->color_type)
493 {
494 case PNG_COLOR_TYPE_GRAY:
495 case PNG_COLOR_TYPE_PALETTE:
496 png_ptr->channels = 1;
497 break;
498
499 case PNG_COLOR_TYPE_RGB:
500 png_ptr->channels = 3;
501 break;
502
503 case PNG_COLOR_TYPE_GRAY_ALPHA:
504 png_ptr->channels = 2;
505 break;
506
507 case PNG_COLOR_TYPE_RGB_ALPHA:
508 png_ptr->channels = 4;
509 break;
510 }
511
512 /* Set up other useful info */
513 png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
514 png_ptr->channels);
515 png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
516 png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
517 png_debug1(3, "channels = %d", png_ptr->channels);
518 png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
519 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
520 color_type, interlace_type, compression_type, filter_type);
521 }
522
523 /* Read and check the palette */
524 void /* PRIVATE */
png_handle_PLTE(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)525 png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
526 {
527 png_color palette[PNG_MAX_PALETTE_LENGTH];
528 int num, i;
529 #ifdef PNG_POINTER_INDEXING_SUPPORTED
530 png_colorp pal_ptr;
531 #endif
532
533 png_debug(1, "in png_handle_PLTE");
534
535 if (!(png_ptr->mode & PNG_HAVE_IHDR))
536 png_error(png_ptr, "Missing IHDR before PLTE");
537
538 else if (png_ptr->mode & PNG_HAVE_IDAT)
539 {
540 png_warning(png_ptr, "Invalid PLTE after IDAT");
541 png_crc_finish(png_ptr, length);
542 return;
543 }
544
545 else if (png_ptr->mode & PNG_HAVE_PLTE)
546 png_error(png_ptr, "Duplicate PLTE chunk");
547
548 png_ptr->mode |= PNG_HAVE_PLTE;
549
550 if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
551 {
552 png_warning(png_ptr,
553 "Ignoring PLTE chunk in grayscale PNG");
554 png_crc_finish(png_ptr, length);
555 return;
556 }
557 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
558 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
559 {
560 png_crc_finish(png_ptr, length);
561 return;
562 }
563 #endif
564
565 if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
566 {
567 if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
568 {
569 png_warning(png_ptr, "Invalid palette chunk");
570 png_crc_finish(png_ptr, length);
571 return;
572 }
573
574 else
575 {
576 png_error(png_ptr, "Invalid palette chunk");
577 }
578 }
579
580 num = (int)length / 3;
581
582 #ifdef PNG_POINTER_INDEXING_SUPPORTED
583 for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
584 {
585 png_byte buf[3];
586
587 png_crc_read(png_ptr, buf, 3);
588 pal_ptr->red = buf[0];
589 pal_ptr->green = buf[1];
590 pal_ptr->blue = buf[2];
591 }
592 #else
593 for (i = 0; i < num; i++)
594 {
595 png_byte buf[3];
596
597 png_crc_read(png_ptr, buf, 3);
598 /* Don't depend upon png_color being any order */
599 palette[i].red = buf[0];
600 palette[i].green = buf[1];
601 palette[i].blue = buf[2];
602 }
603 #endif
604
605 /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
606 * whatever the normal CRC configuration tells us. However, if we
607 * have an RGB image, the PLTE can be considered ancillary, so
608 * we will act as though it is.
609 */
610 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
611 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
612 #endif
613 {
614 png_crc_finish(png_ptr, 0);
615 }
616 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
617 else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
618 {
619 /* If we don't want to use the data from an ancillary chunk,
620 we have two options: an error abort, or a warning and we
621 ignore the data in this chunk (which should be OK, since
622 it's considered ancillary for a RGB or RGBA image). */
623 if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
624 {
625 if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
626 {
627 png_chunk_error(png_ptr, "CRC error");
628 }
629 else
630 {
631 png_chunk_warning(png_ptr, "CRC error");
632 return;
633 }
634 }
635 /* Otherwise, we (optionally) emit a warning and use the chunk. */
636 else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
637 {
638 png_chunk_warning(png_ptr, "CRC error");
639 }
640 }
641 #endif
642
643 png_set_PLTE(png_ptr, info_ptr, palette, num);
644
645 #ifdef PNG_READ_tRNS_SUPPORTED
646 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
647 {
648 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
649 {
650 if (png_ptr->num_trans > (png_uint_16)num)
651 {
652 png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
653 png_ptr->num_trans = (png_uint_16)num;
654 }
655 if (info_ptr->num_trans > (png_uint_16)num)
656 {
657 png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
658 info_ptr->num_trans = (png_uint_16)num;
659 }
660 }
661 }
662 #endif
663
664 }
665
666 void /* PRIVATE */
png_handle_IEND(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)667 png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
668 {
669 png_debug(1, "in png_handle_IEND");
670
671 if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
672 {
673 png_error(png_ptr, "No image in file");
674 }
675
676 png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
677
678 if (length != 0)
679 {
680 png_warning(png_ptr, "Incorrect IEND chunk length");
681 }
682 png_crc_finish(png_ptr, length);
683
684 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
685 }
686
687 #ifdef PNG_READ_gAMA_SUPPORTED
688 void /* PRIVATE */
png_handle_gAMA(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)689 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
690 {
691 png_fixed_point igamma;
692 #ifdef PNG_FLOATING_POINT_SUPPORTED
693 float file_gamma;
694 #endif
695 png_byte buf[4];
696
697 png_debug(1, "in png_handle_gAMA");
698
699 if (!(png_ptr->mode & PNG_HAVE_IHDR))
700 png_error(png_ptr, "Missing IHDR before gAMA");
701 else if (png_ptr->mode & PNG_HAVE_IDAT)
702 {
703 png_warning(png_ptr, "Invalid gAMA after IDAT");
704 png_crc_finish(png_ptr, length);
705 return;
706 }
707 else if (png_ptr->mode & PNG_HAVE_PLTE)
708 /* Should be an error, but we can cope with it */
709 png_warning(png_ptr, "Out of place gAMA chunk");
710
711 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
712 #ifdef PNG_READ_sRGB_SUPPORTED
713 && !(info_ptr->valid & PNG_INFO_sRGB)
714 #endif
715 )
716 {
717 png_warning(png_ptr, "Duplicate gAMA chunk");
718 png_crc_finish(png_ptr, length);
719 return;
720 }
721
722 if (length != 4)
723 {
724 png_warning(png_ptr, "Incorrect gAMA chunk length");
725 png_crc_finish(png_ptr, length);
726 return;
727 }
728
729 png_crc_read(png_ptr, buf, 4);
730 if (png_crc_finish(png_ptr, 0))
731 return;
732
733 igamma = (png_fixed_point)png_get_uint_32(buf);
734 /* Check for zero gamma */
735 if (igamma == 0)
736 {
737 png_warning(png_ptr,
738 "Ignoring gAMA chunk with gamma=0");
739 return;
740 }
741
742 #ifdef PNG_READ_sRGB_SUPPORTED
743 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
744 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
745 {
746 png_warning(png_ptr,
747 "Ignoring incorrect gAMA value when sRGB is also present");
748 #ifdef PNG_CONSOLE_IO_SUPPORTED
749 fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
750 #endif
751 return;
752 }
753 #endif /* PNG_READ_sRGB_SUPPORTED */
754
755 #ifdef PNG_FLOATING_POINT_SUPPORTED
756 file_gamma = (float)igamma / (float)100000.0;
757 # ifdef PNG_READ_GAMMA_SUPPORTED
758 png_ptr->gamma = file_gamma;
759 # endif
760 png_set_gAMA(png_ptr, info_ptr, file_gamma);
761 #endif
762 #ifdef PNG_FIXED_POINT_SUPPORTED
763 png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
764 #endif
765 }
766 #endif
767
768 #ifdef PNG_READ_sBIT_SUPPORTED
769 void /* PRIVATE */
png_handle_sBIT(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)770 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
771 {
772 png_size_t truelen;
773 png_byte buf[4];
774
775 png_debug(1, "in png_handle_sBIT");
776
777 buf[0] = buf[1] = buf[2] = buf[3] = 0;
778
779 if (!(png_ptr->mode & PNG_HAVE_IHDR))
780 png_error(png_ptr, "Missing IHDR before sBIT");
781 else if (png_ptr->mode & PNG_HAVE_IDAT)
782 {
783 png_warning(png_ptr, "Invalid sBIT after IDAT");
784 png_crc_finish(png_ptr, length);
785 return;
786 }
787 else if (png_ptr->mode & PNG_HAVE_PLTE)
788 {
789 /* Should be an error, but we can cope with it */
790 png_warning(png_ptr, "Out of place sBIT chunk");
791 }
792 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
793 {
794 png_warning(png_ptr, "Duplicate sBIT chunk");
795 png_crc_finish(png_ptr, length);
796 return;
797 }
798
799 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
800 truelen = 3;
801 else
802 truelen = (png_size_t)png_ptr->channels;
803
804 if (length != truelen || length > 4)
805 {
806 png_warning(png_ptr, "Incorrect sBIT chunk length");
807 png_crc_finish(png_ptr, length);
808 return;
809 }
810
811 png_crc_read(png_ptr, buf, truelen);
812 if (png_crc_finish(png_ptr, 0))
813 return;
814
815 if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
816 {
817 png_ptr->sig_bit.red = buf[0];
818 png_ptr->sig_bit.green = buf[1];
819 png_ptr->sig_bit.blue = buf[2];
820 png_ptr->sig_bit.alpha = buf[3];
821 }
822 else
823 {
824 png_ptr->sig_bit.gray = buf[0];
825 png_ptr->sig_bit.red = buf[0];
826 png_ptr->sig_bit.green = buf[0];
827 png_ptr->sig_bit.blue = buf[0];
828 png_ptr->sig_bit.alpha = buf[1];
829 }
830 png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
831 }
832 #endif
833
834 #ifdef PNG_READ_cHRM_SUPPORTED
835 void /* PRIVATE */
png_handle_cHRM(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)836 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
837 {
838 png_byte buf[32];
839 #ifdef PNG_FLOATING_POINT_SUPPORTED
840 float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
841 #endif
842 png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
843 int_y_green, int_x_blue, int_y_blue;
844
845 png_uint_32 uint_x, uint_y;
846
847 png_debug(1, "in png_handle_cHRM");
848
849 if (!(png_ptr->mode & PNG_HAVE_IHDR))
850 png_error(png_ptr, "Missing IHDR before cHRM");
851 else if (png_ptr->mode & PNG_HAVE_IDAT)
852 {
853 png_warning(png_ptr, "Invalid cHRM after IDAT");
854 png_crc_finish(png_ptr, length);
855 return;
856 }
857 else if (png_ptr->mode & PNG_HAVE_PLTE)
858 /* Should be an error, but we can cope with it */
859 png_warning(png_ptr, "Missing PLTE before cHRM");
860
861 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
862 #ifdef PNG_READ_sRGB_SUPPORTED
863 && !(info_ptr->valid & PNG_INFO_sRGB)
864 #endif
865 )
866 {
867 png_warning(png_ptr, "Duplicate cHRM chunk");
868 png_crc_finish(png_ptr, length);
869 return;
870 }
871
872 if (length != 32)
873 {
874 png_warning(png_ptr, "Incorrect cHRM chunk length");
875 png_crc_finish(png_ptr, length);
876 return;
877 }
878
879 png_crc_read(png_ptr, buf, 32);
880 if (png_crc_finish(png_ptr, 0))
881 return;
882
883 uint_x = png_get_uint_32(buf);
884 uint_y = png_get_uint_32(buf + 4);
885 int_x_white = (png_fixed_point)uint_x;
886 int_y_white = (png_fixed_point)uint_y;
887
888 uint_x = png_get_uint_32(buf + 8);
889 uint_y = png_get_uint_32(buf + 12);
890 int_x_red = (png_fixed_point)uint_x;
891 int_y_red = (png_fixed_point)uint_y;
892
893 uint_x = png_get_uint_32(buf + 16);
894 uint_y = png_get_uint_32(buf + 20);
895 int_x_green = (png_fixed_point)uint_x;
896 int_y_green = (png_fixed_point)uint_y;
897
898 uint_x = png_get_uint_32(buf + 24);
899 uint_y = png_get_uint_32(buf + 28);
900 int_x_blue = (png_fixed_point)uint_x;
901 int_y_blue = (png_fixed_point)uint_y;
902
903 #ifdef PNG_FLOATING_POINT_SUPPORTED
904 white_x = (float)int_x_white / (float)100000.0;
905 white_y = (float)int_y_white / (float)100000.0;
906 red_x = (float)int_x_red / (float)100000.0;
907 red_y = (float)int_y_red / (float)100000.0;
908 green_x = (float)int_x_green / (float)100000.0;
909 green_y = (float)int_y_green / (float)100000.0;
910 blue_x = (float)int_x_blue / (float)100000.0;
911 blue_y = (float)int_y_blue / (float)100000.0;
912 #endif
913
914 #ifdef PNG_READ_sRGB_SUPPORTED
915 if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
916 {
917 if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) ||
918 PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) ||
919 PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) ||
920 PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) ||
921 PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) ||
922 PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
923 PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) ||
924 PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000))
925 {
926 png_warning(png_ptr,
927 "Ignoring incorrect cHRM value when sRGB is also present");
928 #ifdef PNG_CONSOLE_IO_SUPPORTED
929 #ifdef PNG_FLOATING_POINT_SUPPORTED
930 fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
931 white_x, white_y, red_x, red_y);
932 fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
933 green_x, green_y, blue_x, blue_y);
934 #else
935 fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
936 (long)int_x_white, (long)int_y_white,
937 (long)int_x_red, (long)int_y_red);
938 fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
939 (long)int_x_green, (long)int_y_green,
940 (long)int_x_blue, (long)int_y_blue);
941 #endif
942 #endif /* PNG_CONSOLE_IO_SUPPORTED */
943 }
944 return;
945 }
946 #endif /* PNG_READ_sRGB_SUPPORTED */
947
948 #ifdef PNG_FLOATING_POINT_SUPPORTED
949 png_set_cHRM(png_ptr, info_ptr,
950 white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
951 #endif
952 #ifdef PNG_FIXED_POINT_SUPPORTED
953 png_set_cHRM_fixed(png_ptr, info_ptr,
954 int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
955 int_y_green, int_x_blue, int_y_blue);
956 #endif
957 }
958 #endif
959
960 #ifdef PNG_READ_sRGB_SUPPORTED
961 void /* PRIVATE */
png_handle_sRGB(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)962 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
963 {
964 int intent;
965 png_byte buf[1];
966
967 png_debug(1, "in png_handle_sRGB");
968
969 if (!(png_ptr->mode & PNG_HAVE_IHDR))
970 png_error(png_ptr, "Missing IHDR before sRGB");
971 else if (png_ptr->mode & PNG_HAVE_IDAT)
972 {
973 png_warning(png_ptr, "Invalid sRGB after IDAT");
974 png_crc_finish(png_ptr, length);
975 return;
976 }
977 else if (png_ptr->mode & PNG_HAVE_PLTE)
978 /* Should be an error, but we can cope with it */
979 png_warning(png_ptr, "Out of place sRGB chunk");
980
981 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
982 {
983 png_warning(png_ptr, "Duplicate sRGB chunk");
984 png_crc_finish(png_ptr, length);
985 return;
986 }
987
988 if (length != 1)
989 {
990 png_warning(png_ptr, "Incorrect sRGB chunk length");
991 png_crc_finish(png_ptr, length);
992 return;
993 }
994
995 png_crc_read(png_ptr, buf, 1);
996 if (png_crc_finish(png_ptr, 0))
997 return;
998
999 intent = buf[0];
1000 /* Check for bad intent */
1001 if (intent >= PNG_sRGB_INTENT_LAST)
1002 {
1003 png_warning(png_ptr, "Unknown sRGB intent");
1004 return;
1005 }
1006
1007 #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1008 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1009 {
1010 png_fixed_point igamma;
1011 #ifdef PNG_FIXED_POINT_SUPPORTED
1012 igamma=info_ptr->int_gamma;
1013 #else
1014 # ifdef PNG_FLOATING_POINT_SUPPORTED
1015 igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
1016 # endif
1017 #endif
1018 if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
1019 {
1020 png_warning(png_ptr,
1021 "Ignoring incorrect gAMA value when sRGB is also present");
1022 #ifdef PNG_CONSOLE_IO_SUPPORTED
1023 # ifdef PNG_FIXED_POINT_SUPPORTED
1024 fprintf(stderr, "incorrect gamma=(%d/100000)\n",
1025 (int)png_ptr->int_gamma);
1026 # else
1027 # ifdef PNG_FLOATING_POINT_SUPPORTED
1028 fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
1029 # endif
1030 # endif
1031 #endif
1032 }
1033 }
1034 #endif /* PNG_READ_gAMA_SUPPORTED */
1035
1036 #ifdef PNG_READ_cHRM_SUPPORTED
1037 #ifdef PNG_FIXED_POINT_SUPPORTED
1038 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1039 if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) ||
1040 PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) ||
1041 PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) ||
1042 PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) ||
1043 PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) ||
1044 PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1045 PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) ||
1046 PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000))
1047 {
1048 png_warning(png_ptr,
1049 "Ignoring incorrect cHRM value when sRGB is also present");
1050 }
1051 #endif /* PNG_FIXED_POINT_SUPPORTED */
1052 #endif /* PNG_READ_cHRM_SUPPORTED */
1053
1054 png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1055 }
1056 #endif /* PNG_READ_sRGB_SUPPORTED */
1057
1058 #ifdef PNG_READ_iCCP_SUPPORTED
1059 void /* PRIVATE */
png_handle_iCCP(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1060 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1061 /* Note: this does not properly handle chunks that are > 64K under DOS */
1062 {
1063 png_byte compression_type;
1064 png_bytep pC;
1065 png_charp profile;
1066 png_uint_32 skip = 0;
1067 png_uint_32 profile_size, profile_length;
1068 png_size_t slength, prefix_length, data_length;
1069
1070 png_debug(1, "in png_handle_iCCP");
1071
1072 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1073 png_error(png_ptr, "Missing IHDR before iCCP");
1074 else if (png_ptr->mode & PNG_HAVE_IDAT)
1075 {
1076 png_warning(png_ptr, "Invalid iCCP after IDAT");
1077 png_crc_finish(png_ptr, length);
1078 return;
1079 }
1080 else if (png_ptr->mode & PNG_HAVE_PLTE)
1081 /* Should be an error, but we can cope with it */
1082 png_warning(png_ptr, "Out of place iCCP chunk");
1083
1084 if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1085 {
1086 png_warning(png_ptr, "Duplicate iCCP chunk");
1087 png_crc_finish(png_ptr, length);
1088 return;
1089 }
1090
1091 #ifdef PNG_MAX_MALLOC_64K
1092 if (length > (png_uint_32)65535L)
1093 {
1094 png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1095 skip = length - (png_uint_32)65535L;
1096 length = (png_uint_32)65535L;
1097 }
1098 #endif
1099
1100 png_free(png_ptr, png_ptr->chunkdata);
1101 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1102 slength = (png_size_t)length;
1103 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1104
1105 if (png_crc_finish(png_ptr, skip))
1106 {
1107 png_free(png_ptr, png_ptr->chunkdata);
1108 png_ptr->chunkdata = NULL;
1109 return;
1110 }
1111
1112 png_ptr->chunkdata[slength] = 0x00;
1113
1114 for (profile = png_ptr->chunkdata; *profile; profile++)
1115 /* Empty loop to find end of name */ ;
1116
1117 ++profile;
1118
1119 /* There should be at least one zero (the compression type byte)
1120 * following the separator, and we should be on it
1121 */
1122 if ( profile >= png_ptr->chunkdata + slength - 1)
1123 {
1124 png_free(png_ptr, png_ptr->chunkdata);
1125 png_ptr->chunkdata = NULL;
1126 png_warning(png_ptr, "Malformed iCCP chunk");
1127 return;
1128 }
1129
1130 /* Compression_type should always be zero */
1131 compression_type = *profile++;
1132 if (compression_type)
1133 {
1134 png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1135 compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1136 wrote nonzero) */
1137 }
1138
1139 prefix_length = profile - png_ptr->chunkdata;
1140 png_decompress_chunk(png_ptr, compression_type,
1141 slength, prefix_length, &data_length);
1142
1143 profile_length = data_length - prefix_length;
1144
1145 if ( prefix_length > data_length || profile_length < 4)
1146 {
1147 png_free(png_ptr, png_ptr->chunkdata);
1148 png_ptr->chunkdata = NULL;
1149 png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1150 return;
1151 }
1152
1153 /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1154 pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1155 profile_size = ((*(pC ))<<24) |
1156 ((*(pC + 1))<<16) |
1157 ((*(pC + 2))<< 8) |
1158 ((*(pC + 3)) );
1159
1160 if (profile_size < profile_length)
1161 profile_length = profile_size;
1162
1163 if (profile_size > profile_length)
1164 {
1165 png_free(png_ptr, png_ptr->chunkdata);
1166 png_ptr->chunkdata = NULL;
1167 png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1168 return;
1169 }
1170
1171 png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1172 compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1173 png_free(png_ptr, png_ptr->chunkdata);
1174 png_ptr->chunkdata = NULL;
1175 }
1176 #endif /* PNG_READ_iCCP_SUPPORTED */
1177
1178 #ifdef PNG_READ_sPLT_SUPPORTED
1179 void /* PRIVATE */
png_handle_sPLT(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1180 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1181 /* Note: this does not properly handle chunks that are > 64K under DOS */
1182 {
1183 png_bytep entry_start;
1184 png_sPLT_t new_palette;
1185 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1186 png_sPLT_entryp pp;
1187 #endif
1188 int data_length, entry_size, i;
1189 png_uint_32 skip = 0;
1190 png_size_t slength;
1191
1192 png_debug(1, "in png_handle_sPLT");
1193
1194 #ifdef PNG_USER_LIMITS_SUPPORTED
1195
1196 if (png_ptr->user_chunk_cache_max != 0)
1197 {
1198 if (png_ptr->user_chunk_cache_max == 1)
1199 {
1200 png_crc_finish(png_ptr, length);
1201 return;
1202 }
1203 if (--png_ptr->user_chunk_cache_max == 1)
1204 {
1205 png_warning(png_ptr, "No space in chunk cache for sPLT");
1206 png_crc_finish(png_ptr, length);
1207 return;
1208 }
1209 }
1210 #endif
1211
1212 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1213 png_error(png_ptr, "Missing IHDR before sPLT");
1214 else if (png_ptr->mode & PNG_HAVE_IDAT)
1215 {
1216 png_warning(png_ptr, "Invalid sPLT after IDAT");
1217 png_crc_finish(png_ptr, length);
1218 return;
1219 }
1220
1221 #ifdef PNG_MAX_MALLOC_64K
1222 if (length > (png_uint_32)65535L)
1223 {
1224 png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1225 skip = length - (png_uint_32)65535L;
1226 length = (png_uint_32)65535L;
1227 }
1228 #endif
1229
1230 png_free(png_ptr, png_ptr->chunkdata);
1231 png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1232 slength = (png_size_t)length;
1233 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1234
1235 if (png_crc_finish(png_ptr, skip))
1236 {
1237 png_free(png_ptr, png_ptr->chunkdata);
1238 png_ptr->chunkdata = NULL;
1239 return;
1240 }
1241
1242 png_ptr->chunkdata[slength] = 0x00;
1243
1244 for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1245 entry_start++)
1246 /* Empty loop to find end of name */ ;
1247 ++entry_start;
1248
1249 /* A sample depth should follow the separator, and we should be on it */
1250 if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1251 {
1252 png_free(png_ptr, png_ptr->chunkdata);
1253 png_ptr->chunkdata = NULL;
1254 png_warning(png_ptr, "malformed sPLT chunk");
1255 return;
1256 }
1257
1258 new_palette.depth = *entry_start++;
1259 entry_size = (new_palette.depth == 8 ? 6 : 10);
1260 data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1261
1262 /* Integrity-check the data length */
1263 if (data_length % entry_size)
1264 {
1265 png_free(png_ptr, png_ptr->chunkdata);
1266 png_ptr->chunkdata = NULL;
1267 png_warning(png_ptr, "sPLT chunk has bad length");
1268 return;
1269 }
1270
1271 new_palette.nentries = (png_int_32) ( data_length / entry_size);
1272 if ((png_uint_32) new_palette.nentries >
1273 (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1274 {
1275 png_warning(png_ptr, "sPLT chunk too long");
1276 return;
1277 }
1278 new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1279 png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1280 if (new_palette.entries == NULL)
1281 {
1282 png_warning(png_ptr, "sPLT chunk requires too much memory");
1283 return;
1284 }
1285
1286 #ifdef PNG_POINTER_INDEXING_SUPPORTED
1287 for (i = 0; i < new_palette.nentries; i++)
1288 {
1289 pp = new_palette.entries + i;
1290
1291 if (new_palette.depth == 8)
1292 {
1293 pp->red = *entry_start++;
1294 pp->green = *entry_start++;
1295 pp->blue = *entry_start++;
1296 pp->alpha = *entry_start++;
1297 }
1298 else
1299 {
1300 pp->red = png_get_uint_16(entry_start); entry_start += 2;
1301 pp->green = png_get_uint_16(entry_start); entry_start += 2;
1302 pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1303 pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1304 }
1305 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1306 }
1307 #else
1308 pp = new_palette.entries;
1309 for (i = 0; i < new_palette.nentries; i++)
1310 {
1311
1312 if (new_palette.depth == 8)
1313 {
1314 pp[i].red = *entry_start++;
1315 pp[i].green = *entry_start++;
1316 pp[i].blue = *entry_start++;
1317 pp[i].alpha = *entry_start++;
1318 }
1319 else
1320 {
1321 pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1322 pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1323 pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1324 pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1325 }
1326 pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1327 }
1328 #endif
1329
1330 /* Discard all chunk data except the name and stash that */
1331 new_palette.name = png_ptr->chunkdata;
1332
1333 png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1334
1335 png_free(png_ptr, png_ptr->chunkdata);
1336 png_ptr->chunkdata = NULL;
1337 png_free(png_ptr, new_palette.entries);
1338 }
1339 #endif /* PNG_READ_sPLT_SUPPORTED */
1340
1341 #ifdef PNG_READ_tRNS_SUPPORTED
1342 void /* PRIVATE */
png_handle_tRNS(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1343 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1344 {
1345 png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1346
1347 png_debug(1, "in png_handle_tRNS");
1348
1349 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1350 png_error(png_ptr, "Missing IHDR before tRNS");
1351 else if (png_ptr->mode & PNG_HAVE_IDAT)
1352 {
1353 png_warning(png_ptr, "Invalid tRNS after IDAT");
1354 png_crc_finish(png_ptr, length);
1355 return;
1356 }
1357 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1358 {
1359 png_warning(png_ptr, "Duplicate tRNS chunk");
1360 png_crc_finish(png_ptr, length);
1361 return;
1362 }
1363
1364 if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1365 {
1366 png_byte buf[2];
1367
1368 if (length != 2)
1369 {
1370 png_warning(png_ptr, "Incorrect tRNS chunk length");
1371 png_crc_finish(png_ptr, length);
1372 return;
1373 }
1374
1375 png_crc_read(png_ptr, buf, 2);
1376 png_ptr->num_trans = 1;
1377 png_ptr->trans_values.gray = png_get_uint_16(buf);
1378 }
1379 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1380 {
1381 png_byte buf[6];
1382
1383 if (length != 6)
1384 {
1385 png_warning(png_ptr, "Incorrect tRNS chunk length");
1386 png_crc_finish(png_ptr, length);
1387 return;
1388 }
1389 png_crc_read(png_ptr, buf, (png_size_t)length);
1390 png_ptr->num_trans = 1;
1391 png_ptr->trans_values.red = png_get_uint_16(buf);
1392 png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1393 png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1394 }
1395 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1396 {
1397 if (!(png_ptr->mode & PNG_HAVE_PLTE))
1398 {
1399 /* Should be an error, but we can cope with it. */
1400 png_warning(png_ptr, "Missing PLTE before tRNS");
1401 }
1402 if (length > (png_uint_32)png_ptr->num_palette ||
1403 length > PNG_MAX_PALETTE_LENGTH)
1404 {
1405 png_warning(png_ptr, "Incorrect tRNS chunk length");
1406 png_crc_finish(png_ptr, length);
1407 return;
1408 }
1409 if (length == 0)
1410 {
1411 png_warning(png_ptr, "Zero length tRNS chunk");
1412 png_crc_finish(png_ptr, length);
1413 return;
1414 }
1415 png_crc_read(png_ptr, readbuf, (png_size_t)length);
1416 png_ptr->num_trans = (png_uint_16)length;
1417 }
1418 else
1419 {
1420 png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1421 png_crc_finish(png_ptr, length);
1422 return;
1423 }
1424
1425 if (png_crc_finish(png_ptr, 0))
1426 {
1427 png_ptr->num_trans = 0;
1428 return;
1429 }
1430
1431 png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1432 &(png_ptr->trans_values));
1433 }
1434 #endif
1435
1436 #ifdef PNG_READ_bKGD_SUPPORTED
1437 void /* PRIVATE */
png_handle_bKGD(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1438 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1439 {
1440 png_size_t truelen;
1441 png_byte buf[6];
1442
1443 png_debug(1, "in png_handle_bKGD");
1444
1445 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1446 png_error(png_ptr, "Missing IHDR before bKGD");
1447 else if (png_ptr->mode & PNG_HAVE_IDAT)
1448 {
1449 png_warning(png_ptr, "Invalid bKGD after IDAT");
1450 png_crc_finish(png_ptr, length);
1451 return;
1452 }
1453 else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1454 !(png_ptr->mode & PNG_HAVE_PLTE))
1455 {
1456 png_warning(png_ptr, "Missing PLTE before bKGD");
1457 png_crc_finish(png_ptr, length);
1458 return;
1459 }
1460 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1461 {
1462 png_warning(png_ptr, "Duplicate bKGD chunk");
1463 png_crc_finish(png_ptr, length);
1464 return;
1465 }
1466
1467 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1468 truelen = 1;
1469 else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1470 truelen = 6;
1471 else
1472 truelen = 2;
1473
1474 if (length != truelen)
1475 {
1476 png_warning(png_ptr, "Incorrect bKGD chunk length");
1477 png_crc_finish(png_ptr, length);
1478 return;
1479 }
1480
1481 png_crc_read(png_ptr, buf, truelen);
1482 if (png_crc_finish(png_ptr, 0))
1483 return;
1484
1485 /* We convert the index value into RGB components so that we can allow
1486 * arbitrary RGB values for background when we have transparency, and
1487 * so it is easy to determine the RGB values of the background color
1488 * from the info_ptr struct. */
1489 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1490 {
1491 png_ptr->background.index = buf[0];
1492 if (info_ptr && info_ptr->num_palette)
1493 {
1494 if (buf[0] >= info_ptr->num_palette)
1495 {
1496 png_warning(png_ptr, "Incorrect bKGD chunk index value");
1497 return;
1498 }
1499 png_ptr->background.red =
1500 (png_uint_16)png_ptr->palette[buf[0]].red;
1501 png_ptr->background.green =
1502 (png_uint_16)png_ptr->palette[buf[0]].green;
1503 png_ptr->background.blue =
1504 (png_uint_16)png_ptr->palette[buf[0]].blue;
1505 }
1506 }
1507 else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1508 {
1509 png_ptr->background.red =
1510 png_ptr->background.green =
1511 png_ptr->background.blue =
1512 png_ptr->background.gray = png_get_uint_16(buf);
1513 }
1514 else
1515 {
1516 png_ptr->background.red = png_get_uint_16(buf);
1517 png_ptr->background.green = png_get_uint_16(buf + 2);
1518 png_ptr->background.blue = png_get_uint_16(buf + 4);
1519 }
1520
1521 png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1522 }
1523 #endif
1524
1525 #ifdef PNG_READ_hIST_SUPPORTED
1526 void /* PRIVATE */
png_handle_hIST(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1527 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1528 {
1529 unsigned int num, i;
1530 png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1531
1532 png_debug(1, "in png_handle_hIST");
1533
1534 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1535 png_error(png_ptr, "Missing IHDR before hIST");
1536 else if (png_ptr->mode & PNG_HAVE_IDAT)
1537 {
1538 png_warning(png_ptr, "Invalid hIST after IDAT");
1539 png_crc_finish(png_ptr, length);
1540 return;
1541 }
1542 else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1543 {
1544 png_warning(png_ptr, "Missing PLTE before hIST");
1545 png_crc_finish(png_ptr, length);
1546 return;
1547 }
1548 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1549 {
1550 png_warning(png_ptr, "Duplicate hIST chunk");
1551 png_crc_finish(png_ptr, length);
1552 return;
1553 }
1554
1555 num = length / 2 ;
1556 if (num != (unsigned int) png_ptr->num_palette || num >
1557 (unsigned int) PNG_MAX_PALETTE_LENGTH)
1558 {
1559 png_warning(png_ptr, "Incorrect hIST chunk length");
1560 png_crc_finish(png_ptr, length);
1561 return;
1562 }
1563
1564 for (i = 0; i < num; i++)
1565 {
1566 png_byte buf[2];
1567
1568 png_crc_read(png_ptr, buf, 2);
1569 readbuf[i] = png_get_uint_16(buf);
1570 }
1571
1572 if (png_crc_finish(png_ptr, 0))
1573 return;
1574
1575 png_set_hIST(png_ptr, info_ptr, readbuf);
1576 }
1577 #endif
1578
1579 #ifdef PNG_READ_pHYs_SUPPORTED
1580 void /* PRIVATE */
png_handle_pHYs(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1581 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1582 {
1583 png_byte buf[9];
1584 png_uint_32 res_x, res_y;
1585 int unit_type;
1586
1587 png_debug(1, "in png_handle_pHYs");
1588
1589 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1590 png_error(png_ptr, "Missing IHDR before pHYs");
1591 else if (png_ptr->mode & PNG_HAVE_IDAT)
1592 {
1593 png_warning(png_ptr, "Invalid pHYs after IDAT");
1594 png_crc_finish(png_ptr, length);
1595 return;
1596 }
1597 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1598 {
1599 png_warning(png_ptr, "Duplicate pHYs chunk");
1600 png_crc_finish(png_ptr, length);
1601 return;
1602 }
1603
1604 if (length != 9)
1605 {
1606 png_warning(png_ptr, "Incorrect pHYs chunk length");
1607 png_crc_finish(png_ptr, length);
1608 return;
1609 }
1610
1611 png_crc_read(png_ptr, buf, 9);
1612 if (png_crc_finish(png_ptr, 0))
1613 return;
1614
1615 res_x = png_get_uint_32(buf);
1616 res_y = png_get_uint_32(buf + 4);
1617 unit_type = buf[8];
1618 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1619 }
1620 #endif
1621
1622 #ifdef PNG_READ_oFFs_SUPPORTED
1623 void /* PRIVATE */
png_handle_oFFs(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1624 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1625 {
1626 png_byte buf[9];
1627 png_int_32 offset_x, offset_y;
1628 int unit_type;
1629
1630 png_debug(1, "in png_handle_oFFs");
1631
1632 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1633 png_error(png_ptr, "Missing IHDR before oFFs");
1634 else if (png_ptr->mode & PNG_HAVE_IDAT)
1635 {
1636 png_warning(png_ptr, "Invalid oFFs after IDAT");
1637 png_crc_finish(png_ptr, length);
1638 return;
1639 }
1640 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1641 {
1642 png_warning(png_ptr, "Duplicate oFFs chunk");
1643 png_crc_finish(png_ptr, length);
1644 return;
1645 }
1646
1647 if (length != 9)
1648 {
1649 png_warning(png_ptr, "Incorrect oFFs chunk length");
1650 png_crc_finish(png_ptr, length);
1651 return;
1652 }
1653
1654 png_crc_read(png_ptr, buf, 9);
1655 if (png_crc_finish(png_ptr, 0))
1656 return;
1657
1658 offset_x = png_get_int_32(buf);
1659 offset_y = png_get_int_32(buf + 4);
1660 unit_type = buf[8];
1661 png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1662 }
1663 #endif
1664
1665 #ifdef PNG_READ_pCAL_SUPPORTED
1666 /* Read the pCAL chunk (described in the PNG Extensions document) */
1667 void /* PRIVATE */
png_handle_pCAL(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1668 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1669 {
1670 png_int_32 X0, X1;
1671 png_byte type, nparams;
1672 png_charp buf, units, endptr;
1673 png_charpp params;
1674 png_size_t slength;
1675 int i;
1676
1677 png_debug(1, "in png_handle_pCAL");
1678
1679 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1680 png_error(png_ptr, "Missing IHDR before pCAL");
1681 else if (png_ptr->mode & PNG_HAVE_IDAT)
1682 {
1683 png_warning(png_ptr, "Invalid pCAL after IDAT");
1684 png_crc_finish(png_ptr, length);
1685 return;
1686 }
1687 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1688 {
1689 png_warning(png_ptr, "Duplicate pCAL chunk");
1690 png_crc_finish(png_ptr, length);
1691 return;
1692 }
1693
1694 png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1695 length + 1);
1696 png_free(png_ptr, png_ptr->chunkdata);
1697 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1698 if (png_ptr->chunkdata == NULL)
1699 {
1700 png_warning(png_ptr, "No memory for pCAL purpose.");
1701 return;
1702 }
1703 slength = (png_size_t)length;
1704 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1705
1706 if (png_crc_finish(png_ptr, 0))
1707 {
1708 png_free(png_ptr, png_ptr->chunkdata);
1709 png_ptr->chunkdata = NULL;
1710 return;
1711 }
1712
1713 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1714
1715 png_debug(3, "Finding end of pCAL purpose string");
1716 for (buf = png_ptr->chunkdata; *buf; buf++)
1717 /* Empty loop */ ;
1718
1719 endptr = png_ptr->chunkdata + slength;
1720
1721 /* We need to have at least 12 bytes after the purpose string
1722 in order to get the parameter information. */
1723 if (endptr <= buf + 12)
1724 {
1725 png_warning(png_ptr, "Invalid pCAL data");
1726 png_free(png_ptr, png_ptr->chunkdata);
1727 png_ptr->chunkdata = NULL;
1728 return;
1729 }
1730
1731 png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1732 X0 = png_get_int_32((png_bytep)buf+1);
1733 X1 = png_get_int_32((png_bytep)buf+5);
1734 type = buf[9];
1735 nparams = buf[10];
1736 units = buf + 11;
1737
1738 png_debug(3, "Checking pCAL equation type and number of parameters");
1739 /* Check that we have the right number of parameters for known
1740 equation types. */
1741 if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1742 (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1743 (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1744 (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1745 {
1746 png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1747 png_free(png_ptr, png_ptr->chunkdata);
1748 png_ptr->chunkdata = NULL;
1749 return;
1750 }
1751 else if (type >= PNG_EQUATION_LAST)
1752 {
1753 png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1754 }
1755
1756 for (buf = units; *buf; buf++)
1757 /* Empty loop to move past the units string. */ ;
1758
1759 png_debug(3, "Allocating pCAL parameters array");
1760 params = (png_charpp)png_malloc_warn(png_ptr,
1761 (png_uint_32)(nparams * png_sizeof(png_charp))) ;
1762 if (params == NULL)
1763 {
1764 png_free(png_ptr, png_ptr->chunkdata);
1765 png_ptr->chunkdata = NULL;
1766 png_warning(png_ptr, "No memory for pCAL params.");
1767 return;
1768 }
1769
1770 /* Get pointers to the start of each parameter string. */
1771 for (i = 0; i < (int)nparams; i++)
1772 {
1773 buf++; /* Skip the null string terminator from previous parameter. */
1774
1775 png_debug1(3, "Reading pCAL parameter %d", i);
1776 for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1777 /* Empty loop to move past each parameter string */ ;
1778
1779 /* Make sure we haven't run out of data yet */
1780 if (buf > endptr)
1781 {
1782 png_warning(png_ptr, "Invalid pCAL data");
1783 png_free(png_ptr, png_ptr->chunkdata);
1784 png_ptr->chunkdata = NULL;
1785 png_free(png_ptr, params);
1786 return;
1787 }
1788 }
1789
1790 png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1791 units, params);
1792
1793 png_free(png_ptr, png_ptr->chunkdata);
1794 png_ptr->chunkdata = NULL;
1795 png_free(png_ptr, params);
1796 }
1797 #endif
1798
1799 #ifdef PNG_READ_sCAL_SUPPORTED
1800 /* Read the sCAL chunk */
1801 void /* PRIVATE */
png_handle_sCAL(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1802 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1803 {
1804 png_charp ep;
1805 #ifdef PNG_FLOATING_POINT_SUPPORTED
1806 double width, height;
1807 png_charp vp;
1808 #else
1809 #ifdef PNG_FIXED_POINT_SUPPORTED
1810 png_charp swidth, sheight;
1811 #endif
1812 #endif
1813 png_size_t slength;
1814
1815 png_debug(1, "in png_handle_sCAL");
1816
1817 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1818 png_error(png_ptr, "Missing IHDR before sCAL");
1819 else if (png_ptr->mode & PNG_HAVE_IDAT)
1820 {
1821 png_warning(png_ptr, "Invalid sCAL after IDAT");
1822 png_crc_finish(png_ptr, length);
1823 return;
1824 }
1825 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1826 {
1827 png_warning(png_ptr, "Duplicate sCAL chunk");
1828 png_crc_finish(png_ptr, length);
1829 return;
1830 }
1831
1832 /* Need unit type, width, \0, height: minimum 4 bytes */
1833 else if (length < 4)
1834 {
1835 png_warning(png_ptr, "sCAL chunk too short");
1836 png_crc_finish(png_ptr, length);
1837 return;
1838 }
1839
1840 png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1841 length + 1);
1842 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1843 if (png_ptr->chunkdata == NULL)
1844 {
1845 png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1846 png_crc_finish(png_ptr, length);
1847 return;
1848 }
1849 slength = (png_size_t)length;
1850 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1851
1852 if (png_crc_finish(png_ptr, 0))
1853 {
1854 png_free(png_ptr, png_ptr->chunkdata);
1855 png_ptr->chunkdata = NULL;
1856 return;
1857 }
1858
1859 png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1860
1861 ep = png_ptr->chunkdata + 1; /* Skip unit byte */
1862
1863 #ifdef PNG_FLOATING_POINT_SUPPORTED
1864 width = png_strtod(png_ptr, ep, &vp);
1865 if (*vp)
1866 {
1867 png_warning(png_ptr, "malformed width string in sCAL chunk");
1868 png_free(png_ptr, png_ptr->chunkdata);
1869 png_ptr->chunkdata = NULL;
1870 return;
1871 }
1872 #else
1873 #ifdef PNG_FIXED_POINT_SUPPORTED
1874 swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1875 if (swidth == NULL)
1876 {
1877 png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1878 png_free(png_ptr, png_ptr->chunkdata);
1879 png_ptr->chunkdata = NULL;
1880 return;
1881 }
1882 png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1883 #endif
1884 #endif
1885
1886 for (ep = png_ptr->chunkdata; *ep; ep++)
1887 /* Empty loop */ ;
1888 ep++;
1889
1890 if (png_ptr->chunkdata + slength < ep)
1891 {
1892 png_warning(png_ptr, "Truncated sCAL chunk");
1893 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1894 png_free(png_ptr, swidth);
1895 #endif
1896 png_free(png_ptr, png_ptr->chunkdata);
1897 png_ptr->chunkdata = NULL;
1898 return;
1899 }
1900
1901 #ifdef PNG_FLOATING_POINT_SUPPORTED
1902 height = png_strtod(png_ptr, ep, &vp);
1903 if (*vp)
1904 {
1905 png_warning(png_ptr, "malformed height string in sCAL chunk");
1906 png_free(png_ptr, png_ptr->chunkdata);
1907 png_ptr->chunkdata = NULL;
1908 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1909 png_free(png_ptr, swidth);
1910 #endif
1911 return;
1912 }
1913 #else
1914 #ifdef PNG_FIXED_POINT_SUPPORTED
1915 sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1916 if (sheight == NULL)
1917 {
1918 png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1919 png_free(png_ptr, png_ptr->chunkdata);
1920 png_ptr->chunkdata = NULL;
1921 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1922 png_free(png_ptr, swidth);
1923 #endif
1924 return;
1925 }
1926 png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1927 #endif
1928 #endif
1929
1930 if (png_ptr->chunkdata + slength < ep
1931 #ifdef PNG_FLOATING_POINT_SUPPORTED
1932 || width <= 0. || height <= 0.
1933 #endif
1934 )
1935 {
1936 png_warning(png_ptr, "Invalid sCAL data");
1937 png_free(png_ptr, png_ptr->chunkdata);
1938 png_ptr->chunkdata = NULL;
1939 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1940 png_free(png_ptr, swidth);
1941 png_free(png_ptr, sheight);
1942 #endif
1943 return;
1944 }
1945
1946
1947 #ifdef PNG_FLOATING_POINT_SUPPORTED
1948 png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1949 #else
1950 #ifdef PNG_FIXED_POINT_SUPPORTED
1951 png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1952 #endif
1953 #endif
1954
1955 png_free(png_ptr, png_ptr->chunkdata);
1956 png_ptr->chunkdata = NULL;
1957 #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1958 png_free(png_ptr, swidth);
1959 png_free(png_ptr, sheight);
1960 #endif
1961 }
1962 #endif
1963
1964 #ifdef PNG_READ_tIME_SUPPORTED
1965 void /* PRIVATE */
png_handle_tIME(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)1966 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1967 {
1968 png_byte buf[7];
1969 png_time mod_time;
1970
1971 png_debug(1, "in png_handle_tIME");
1972
1973 if (!(png_ptr->mode & PNG_HAVE_IHDR))
1974 png_error(png_ptr, "Out of place tIME chunk");
1975 else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1976 {
1977 png_warning(png_ptr, "Duplicate tIME chunk");
1978 png_crc_finish(png_ptr, length);
1979 return;
1980 }
1981
1982 if (png_ptr->mode & PNG_HAVE_IDAT)
1983 png_ptr->mode |= PNG_AFTER_IDAT;
1984
1985 if (length != 7)
1986 {
1987 png_warning(png_ptr, "Incorrect tIME chunk length");
1988 png_crc_finish(png_ptr, length);
1989 return;
1990 }
1991
1992 png_crc_read(png_ptr, buf, 7);
1993 if (png_crc_finish(png_ptr, 0))
1994 return;
1995
1996 mod_time.second = buf[6];
1997 mod_time.minute = buf[5];
1998 mod_time.hour = buf[4];
1999 mod_time.day = buf[3];
2000 mod_time.month = buf[2];
2001 mod_time.year = png_get_uint_16(buf);
2002
2003 png_set_tIME(png_ptr, info_ptr, &mod_time);
2004 }
2005 #endif
2006
2007 #ifdef PNG_READ_tEXt_SUPPORTED
2008 /* Note: this does not properly handle chunks that are > 64K under DOS */
2009 void /* PRIVATE */
png_handle_tEXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2010 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2011 {
2012 png_textp text_ptr;
2013 png_charp key;
2014 png_charp text;
2015 png_uint_32 skip = 0;
2016 png_size_t slength;
2017 int ret;
2018
2019 png_debug(1, "in png_handle_tEXt");
2020
2021 #ifdef PNG_USER_LIMITS_SUPPORTED
2022 if (png_ptr->user_chunk_cache_max != 0)
2023 {
2024 if (png_ptr->user_chunk_cache_max == 1)
2025 {
2026 png_crc_finish(png_ptr, length);
2027 return;
2028 }
2029 if (--png_ptr->user_chunk_cache_max == 1)
2030 {
2031 png_warning(png_ptr, "No space in chunk cache for tEXt");
2032 png_crc_finish(png_ptr, length);
2033 return;
2034 }
2035 }
2036 #endif
2037
2038 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2039 png_error(png_ptr, "Missing IHDR before tEXt");
2040
2041 if (png_ptr->mode & PNG_HAVE_IDAT)
2042 png_ptr->mode |= PNG_AFTER_IDAT;
2043
2044 #ifdef PNG_MAX_MALLOC_64K
2045 if (length > (png_uint_32)65535L)
2046 {
2047 png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2048 skip = length - (png_uint_32)65535L;
2049 length = (png_uint_32)65535L;
2050 }
2051 #endif
2052
2053 png_free(png_ptr, png_ptr->chunkdata);
2054
2055 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2056 if (png_ptr->chunkdata == NULL)
2057 {
2058 png_warning(png_ptr, "No memory to process text chunk.");
2059 return;
2060 }
2061 slength = (png_size_t)length;
2062 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2063
2064 if (png_crc_finish(png_ptr, skip))
2065 {
2066 png_free(png_ptr, png_ptr->chunkdata);
2067 png_ptr->chunkdata = NULL;
2068 return;
2069 }
2070
2071 key = png_ptr->chunkdata;
2072
2073 key[slength] = 0x00;
2074
2075 for (text = key; *text; text++)
2076 /* Empty loop to find end of key */ ;
2077
2078 if (text != key + slength)
2079 text++;
2080
2081 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2082 (png_uint_32)png_sizeof(png_text));
2083 if (text_ptr == NULL)
2084 {
2085 png_warning(png_ptr, "Not enough memory to process text chunk.");
2086 png_free(png_ptr, png_ptr->chunkdata);
2087 png_ptr->chunkdata = NULL;
2088 return;
2089 }
2090 text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2091 text_ptr->key = key;
2092 #ifdef PNG_iTXt_SUPPORTED
2093 text_ptr->lang = NULL;
2094 text_ptr->lang_key = NULL;
2095 text_ptr->itxt_length = 0;
2096 #endif
2097 text_ptr->text = text;
2098 text_ptr->text_length = png_strlen(text);
2099
2100 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2101
2102 png_free(png_ptr, png_ptr->chunkdata);
2103 png_ptr->chunkdata = NULL;
2104 png_free(png_ptr, text_ptr);
2105 if (ret)
2106 png_warning(png_ptr, "Insufficient memory to process text chunk.");
2107 }
2108 #endif
2109
2110 #ifdef PNG_READ_zTXt_SUPPORTED
2111 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2112 void /* PRIVATE */
png_handle_zTXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2113 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2114 {
2115 png_textp text_ptr;
2116 png_charp text;
2117 int comp_type;
2118 int ret;
2119 png_size_t slength, prefix_len, data_len;
2120
2121 png_debug(1, "in png_handle_zTXt");
2122
2123 #ifdef PNG_USER_LIMITS_SUPPORTED
2124 if (png_ptr->user_chunk_cache_max != 0)
2125 {
2126 if (png_ptr->user_chunk_cache_max == 1)
2127 {
2128 png_crc_finish(png_ptr, length);
2129 return;
2130 }
2131 if (--png_ptr->user_chunk_cache_max == 1)
2132 {
2133 png_warning(png_ptr, "No space in chunk cache for zTXt");
2134 png_crc_finish(png_ptr, length);
2135 return;
2136 }
2137 }
2138 #endif
2139
2140 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2141 png_error(png_ptr, "Missing IHDR before zTXt");
2142
2143 if (png_ptr->mode & PNG_HAVE_IDAT)
2144 png_ptr->mode |= PNG_AFTER_IDAT;
2145
2146 #ifdef PNG_MAX_MALLOC_64K
2147 /* We will no doubt have problems with chunks even half this size, but
2148 there is no hard and fast rule to tell us where to stop. */
2149 if (length > (png_uint_32)65535L)
2150 {
2151 png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2152 png_crc_finish(png_ptr, length);
2153 return;
2154 }
2155 #endif
2156
2157 png_free(png_ptr, png_ptr->chunkdata);
2158 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2159 if (png_ptr->chunkdata == NULL)
2160 {
2161 png_warning(png_ptr, "Out of memory processing zTXt chunk.");
2162 return;
2163 }
2164 slength = (png_size_t)length;
2165 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2166 if (png_crc_finish(png_ptr, 0))
2167 {
2168 png_free(png_ptr, png_ptr->chunkdata);
2169 png_ptr->chunkdata = NULL;
2170 return;
2171 }
2172
2173 png_ptr->chunkdata[slength] = 0x00;
2174
2175 for (text = png_ptr->chunkdata; *text; text++)
2176 /* Empty loop */ ;
2177
2178 /* zTXt must have some text after the chunkdataword */
2179 if (text >= png_ptr->chunkdata + slength - 2)
2180 {
2181 png_warning(png_ptr, "Truncated zTXt chunk");
2182 png_free(png_ptr, png_ptr->chunkdata);
2183 png_ptr->chunkdata = NULL;
2184 return;
2185 }
2186 else
2187 {
2188 comp_type = *(++text);
2189 if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2190 {
2191 png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2192 comp_type = PNG_TEXT_COMPRESSION_zTXt;
2193 }
2194 text++; /* Skip the compression_method byte */
2195 }
2196 prefix_len = text - png_ptr->chunkdata;
2197
2198 png_decompress_chunk(png_ptr, comp_type,
2199 (png_size_t)length, prefix_len, &data_len);
2200
2201 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2202 (png_uint_32)png_sizeof(png_text));
2203 if (text_ptr == NULL)
2204 {
2205 png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
2206 png_free(png_ptr, png_ptr->chunkdata);
2207 png_ptr->chunkdata = NULL;
2208 return;
2209 }
2210 text_ptr->compression = comp_type;
2211 text_ptr->key = png_ptr->chunkdata;
2212 #ifdef PNG_iTXt_SUPPORTED
2213 text_ptr->lang = NULL;
2214 text_ptr->lang_key = NULL;
2215 text_ptr->itxt_length = 0;
2216 #endif
2217 text_ptr->text = png_ptr->chunkdata + prefix_len;
2218 text_ptr->text_length = data_len;
2219
2220 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2221
2222 png_free(png_ptr, text_ptr);
2223 png_free(png_ptr, png_ptr->chunkdata);
2224 png_ptr->chunkdata = NULL;
2225 if (ret)
2226 png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2227 }
2228 #endif
2229
2230 #ifdef PNG_READ_iTXt_SUPPORTED
2231 /* Note: this does not correctly handle chunks that are > 64K under DOS */
2232 void /* PRIVATE */
png_handle_iTXt(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2233 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2234 {
2235 png_textp text_ptr;
2236 png_charp key, lang, text, lang_key;
2237 int comp_flag;
2238 int comp_type = 0;
2239 int ret;
2240 png_size_t slength, prefix_len, data_len;
2241
2242 png_debug(1, "in png_handle_iTXt");
2243
2244 #ifdef PNG_USER_LIMITS_SUPPORTED
2245 if (png_ptr->user_chunk_cache_max != 0)
2246 {
2247 if (png_ptr->user_chunk_cache_max == 1)
2248 {
2249 png_crc_finish(png_ptr, length);
2250 return;
2251 }
2252 if (--png_ptr->user_chunk_cache_max == 1)
2253 {
2254 png_warning(png_ptr, "No space in chunk cache for iTXt");
2255 png_crc_finish(png_ptr, length);
2256 return;
2257 }
2258 }
2259 #endif
2260
2261 if (!(png_ptr->mode & PNG_HAVE_IHDR))
2262 png_error(png_ptr, "Missing IHDR before iTXt");
2263
2264 if (png_ptr->mode & PNG_HAVE_IDAT)
2265 png_ptr->mode |= PNG_AFTER_IDAT;
2266
2267 #ifdef PNG_MAX_MALLOC_64K
2268 /* We will no doubt have problems with chunks even half this size, but
2269 there is no hard and fast rule to tell us where to stop. */
2270 if (length > (png_uint_32)65535L)
2271 {
2272 png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2273 png_crc_finish(png_ptr, length);
2274 return;
2275 }
2276 #endif
2277
2278 png_free(png_ptr, png_ptr->chunkdata);
2279 png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2280 if (png_ptr->chunkdata == NULL)
2281 {
2282 png_warning(png_ptr, "No memory to process iTXt chunk.");
2283 return;
2284 }
2285 slength = (png_size_t)length;
2286 png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2287 if (png_crc_finish(png_ptr, 0))
2288 {
2289 png_free(png_ptr, png_ptr->chunkdata);
2290 png_ptr->chunkdata = NULL;
2291 return;
2292 }
2293
2294 png_ptr->chunkdata[slength] = 0x00;
2295
2296 for (lang = png_ptr->chunkdata; *lang; lang++)
2297 /* Empty loop */ ;
2298 lang++; /* Skip NUL separator */
2299
2300 /* iTXt must have a language tag (possibly empty), two compression bytes,
2301 * translated keyword (possibly empty), and possibly some text after the
2302 * keyword
2303 */
2304
2305 if (lang >= png_ptr->chunkdata + slength - 3)
2306 {
2307 png_warning(png_ptr, "Truncated iTXt chunk");
2308 png_free(png_ptr, png_ptr->chunkdata);
2309 png_ptr->chunkdata = NULL;
2310 return;
2311 }
2312 else
2313 {
2314 comp_flag = *lang++;
2315 comp_type = *lang++;
2316 }
2317
2318 for (lang_key = lang; *lang_key; lang_key++)
2319 /* Empty loop */ ;
2320 lang_key++; /* Skip NUL separator */
2321
2322 if (lang_key >= png_ptr->chunkdata + slength)
2323 {
2324 png_warning(png_ptr, "Truncated iTXt chunk");
2325 png_free(png_ptr, png_ptr->chunkdata);
2326 png_ptr->chunkdata = NULL;
2327 return;
2328 }
2329
2330 for (text = lang_key; *text; text++)
2331 /* Empty loop */ ;
2332 text++; /* Skip NUL separator */
2333 if (text >= png_ptr->chunkdata + slength)
2334 {
2335 png_warning(png_ptr, "Malformed iTXt chunk");
2336 png_free(png_ptr, png_ptr->chunkdata);
2337 png_ptr->chunkdata = NULL;
2338 return;
2339 }
2340
2341 prefix_len = text - png_ptr->chunkdata;
2342
2343 key=png_ptr->chunkdata;
2344 if (comp_flag)
2345 png_decompress_chunk(png_ptr, comp_type,
2346 (size_t)length, prefix_len, &data_len);
2347 else
2348 data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2349 text_ptr = (png_textp)png_malloc_warn(png_ptr,
2350 (png_uint_32)png_sizeof(png_text));
2351 if (text_ptr == NULL)
2352 {
2353 png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
2354 png_free(png_ptr, png_ptr->chunkdata);
2355 png_ptr->chunkdata = NULL;
2356 return;
2357 }
2358 text_ptr->compression = (int)comp_flag + 1;
2359 text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2360 text_ptr->lang = png_ptr->chunkdata + (lang - key);
2361 text_ptr->itxt_length = data_len;
2362 text_ptr->text_length = 0;
2363 text_ptr->key = png_ptr->chunkdata;
2364 text_ptr->text = png_ptr->chunkdata + prefix_len;
2365
2366 ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2367
2368 png_free(png_ptr, text_ptr);
2369 png_free(png_ptr, png_ptr->chunkdata);
2370 png_ptr->chunkdata = NULL;
2371 if (ret)
2372 png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2373 }
2374 #endif
2375
2376 /* This function is called when we haven't found a handler for a
2377 chunk. If there isn't a problem with the chunk itself (ie bad
2378 chunk name, CRC, or a critical chunk), the chunk is silently ignored
2379 -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2380 case it will be saved away to be written out later. */
2381 void /* PRIVATE */
png_handle_unknown(png_structp png_ptr,png_infop info_ptr,png_uint_32 length)2382 png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2383 {
2384 png_uint_32 skip = 0;
2385
2386 png_debug(1, "in png_handle_unknown");
2387
2388 #ifdef PNG_USER_LIMITS_SUPPORTED
2389 if (png_ptr->user_chunk_cache_max != 0)
2390 {
2391 if (png_ptr->user_chunk_cache_max == 1)
2392 {
2393 png_crc_finish(png_ptr, length);
2394 return;
2395 }
2396 if (--png_ptr->user_chunk_cache_max == 1)
2397 {
2398 png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2399 png_crc_finish(png_ptr, length);
2400 return;
2401 }
2402 }
2403 #endif
2404
2405 if (png_ptr->mode & PNG_HAVE_IDAT)
2406 {
2407 #ifdef PNG_USE_LOCAL_ARRAYS
2408 PNG_CONST PNG_IDAT;
2409 #endif
2410 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */
2411 png_ptr->mode |= PNG_AFTER_IDAT;
2412 }
2413
2414 if (!(png_ptr->chunk_name[0] & 0x20))
2415 {
2416 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2417 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2418 PNG_HANDLE_CHUNK_ALWAYS
2419 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2420 && png_ptr->read_user_chunk_fn == NULL
2421 #endif
2422 )
2423 #endif
2424 png_chunk_error(png_ptr, "unknown critical chunk");
2425 }
2426
2427 #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2428 if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2429 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2430 || (png_ptr->read_user_chunk_fn != NULL)
2431 #endif
2432 )
2433 {
2434 #ifdef PNG_MAX_MALLOC_64K
2435 if (length > (png_uint_32)65535L)
2436 {
2437 png_warning(png_ptr, "unknown chunk too large to fit in memory");
2438 skip = length - (png_uint_32)65535L;
2439 length = (png_uint_32)65535L;
2440 }
2441 #endif
2442 png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2443 (png_charp)png_ptr->chunk_name,
2444 png_sizeof(png_ptr->unknown_chunk.name));
2445 png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2446 = '\0';
2447 png_ptr->unknown_chunk.size = (png_size_t)length;
2448 if (length == 0)
2449 png_ptr->unknown_chunk.data = NULL;
2450 else
2451 {
2452 png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2453 png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2454 }
2455 #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2456 if (png_ptr->read_user_chunk_fn != NULL)
2457 {
2458 /* Callback to user unknown chunk handler */
2459 int ret;
2460 ret = (*(png_ptr->read_user_chunk_fn))
2461 (png_ptr, &png_ptr->unknown_chunk);
2462 if (ret < 0)
2463 png_chunk_error(png_ptr, "error in user chunk");
2464 if (ret == 0)
2465 {
2466 if (!(png_ptr->chunk_name[0] & 0x20))
2467 #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2468 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2469 PNG_HANDLE_CHUNK_ALWAYS)
2470 #endif
2471 png_chunk_error(png_ptr, "unknown critical chunk");
2472 png_set_unknown_chunks(png_ptr, info_ptr,
2473 &png_ptr->unknown_chunk, 1);
2474 }
2475 }
2476 else
2477 #endif
2478 png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2479 png_free(png_ptr, png_ptr->unknown_chunk.data);
2480 png_ptr->unknown_chunk.data = NULL;
2481 }
2482 else
2483 #endif
2484 skip = length;
2485
2486 png_crc_finish(png_ptr, skip);
2487
2488 #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2489 info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2490 #endif
2491 }
2492
2493 /* This function is called to verify that a chunk name is valid.
2494 This function can't have the "critical chunk check" incorporated
2495 into it, since in the future we will need to be able to call user
2496 functions to handle unknown critical chunks after we check that
2497 the chunk name itself is valid. */
2498
2499 #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2500
2501 void /* PRIVATE */
png_check_chunk_name(png_structp png_ptr,png_bytep chunk_name)2502 png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2503 {
2504 png_debug(1, "in png_check_chunk_name");
2505 if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2506 isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2507 {
2508 png_chunk_error(png_ptr, "invalid chunk type");
2509 }
2510 }
2511
2512 /* Combines the row recently read in with the existing pixels in the
2513 row. This routine takes care of alpha and transparency if requested.
2514 This routine also handles the two methods of progressive display
2515 of interlaced images, depending on the mask value.
2516 The mask value describes which pixels are to be combined with
2517 the row. The pattern always repeats every 8 pixels, so just 8
2518 bits are needed. A one indicates the pixel is to be combined,
2519 a zero indicates the pixel is to be skipped. This is in addition
2520 to any alpha or transparency value associated with the pixel. If
2521 you want all pixels to be combined, pass 0xff (255) in mask. */
2522
2523 void /* PRIVATE */
png_combine_row(png_structp png_ptr,png_bytep row,int mask)2524 png_combine_row(png_structp png_ptr, png_bytep row, int mask)
2525 {
2526 png_debug(1, "in png_combine_row");
2527 if (mask == 0xff)
2528 {
2529 png_memcpy(row, png_ptr->row_buf + 1,
2530 PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2531 }
2532 else
2533 {
2534 switch (png_ptr->row_info.pixel_depth)
2535 {
2536 case 1:
2537 {
2538 png_bytep sp = png_ptr->row_buf + 1;
2539 png_bytep dp = row;
2540 int s_inc, s_start, s_end;
2541 int m = 0x80;
2542 int shift;
2543 png_uint_32 i;
2544 png_uint_32 row_width = png_ptr->width;
2545
2546 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2547 if (png_ptr->transformations & PNG_PACKSWAP)
2548 {
2549 s_start = 0;
2550 s_end = 7;
2551 s_inc = 1;
2552 }
2553 else
2554 #endif
2555 {
2556 s_start = 7;
2557 s_end = 0;
2558 s_inc = -1;
2559 }
2560
2561 shift = s_start;
2562
2563 for (i = 0; i < row_width; i++)
2564 {
2565 if (m & mask)
2566 {
2567 int value;
2568
2569 value = (*sp >> shift) & 0x01;
2570 *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2571 *dp |= (png_byte)(value << shift);
2572 }
2573
2574 if (shift == s_end)
2575 {
2576 shift = s_start;
2577 sp++;
2578 dp++;
2579 }
2580 else
2581 shift += s_inc;
2582
2583 if (m == 1)
2584 m = 0x80;
2585 else
2586 m >>= 1;
2587 }
2588 break;
2589 }
2590 case 2:
2591 {
2592 png_bytep sp = png_ptr->row_buf + 1;
2593 png_bytep dp = row;
2594 int s_start, s_end, s_inc;
2595 int m = 0x80;
2596 int shift;
2597 png_uint_32 i;
2598 png_uint_32 row_width = png_ptr->width;
2599 int value;
2600
2601 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2602 if (png_ptr->transformations & PNG_PACKSWAP)
2603 {
2604 s_start = 0;
2605 s_end = 6;
2606 s_inc = 2;
2607 }
2608 else
2609 #endif
2610 {
2611 s_start = 6;
2612 s_end = 0;
2613 s_inc = -2;
2614 }
2615
2616 shift = s_start;
2617
2618 for (i = 0; i < row_width; i++)
2619 {
2620 if (m & mask)
2621 {
2622 value = (*sp >> shift) & 0x03;
2623 *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2624 *dp |= (png_byte)(value << shift);
2625 }
2626
2627 if (shift == s_end)
2628 {
2629 shift = s_start;
2630 sp++;
2631 dp++;
2632 }
2633 else
2634 shift += s_inc;
2635 if (m == 1)
2636 m = 0x80;
2637 else
2638 m >>= 1;
2639 }
2640 break;
2641 }
2642 case 4:
2643 {
2644 png_bytep sp = png_ptr->row_buf + 1;
2645 png_bytep dp = row;
2646 int s_start, s_end, s_inc;
2647 int m = 0x80;
2648 int shift;
2649 png_uint_32 i;
2650 png_uint_32 row_width = png_ptr->width;
2651 int value;
2652
2653 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2654 if (png_ptr->transformations & PNG_PACKSWAP)
2655 {
2656 s_start = 0;
2657 s_end = 4;
2658 s_inc = 4;
2659 }
2660 else
2661 #endif
2662 {
2663 s_start = 4;
2664 s_end = 0;
2665 s_inc = -4;
2666 }
2667 shift = s_start;
2668
2669 for (i = 0; i < row_width; i++)
2670 {
2671 if (m & mask)
2672 {
2673 value = (*sp >> shift) & 0xf;
2674 *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2675 *dp |= (png_byte)(value << shift);
2676 }
2677
2678 if (shift == s_end)
2679 {
2680 shift = s_start;
2681 sp++;
2682 dp++;
2683 }
2684 else
2685 shift += s_inc;
2686 if (m == 1)
2687 m = 0x80;
2688 else
2689 m >>= 1;
2690 }
2691 break;
2692 }
2693 default:
2694 {
2695 png_bytep sp = png_ptr->row_buf + 1;
2696 png_bytep dp = row;
2697 png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2698 png_uint_32 i;
2699 png_uint_32 row_width = png_ptr->width;
2700 png_byte m = 0x80;
2701
2702
2703 for (i = 0; i < row_width; i++)
2704 {
2705 if (m & mask)
2706 {
2707 png_memcpy(dp, sp, pixel_bytes);
2708 }
2709
2710 sp += pixel_bytes;
2711 dp += pixel_bytes;
2712
2713 if (m == 1)
2714 m = 0x80;
2715 else
2716 m >>= 1;
2717 }
2718 break;
2719 }
2720 }
2721 }
2722 }
2723
2724 #ifdef PNG_READ_INTERLACING_SUPPORTED
2725 /* OLD pre-1.0.9 interface:
2726 void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2727 png_uint_32 transformations)
2728 */
2729 void /* PRIVATE */
png_do_read_interlace(png_structp png_ptr)2730 png_do_read_interlace(png_structp png_ptr)
2731 {
2732 png_row_infop row_info = &(png_ptr->row_info);
2733 png_bytep row = png_ptr->row_buf + 1;
2734 int pass = png_ptr->pass;
2735 png_uint_32 transformations = png_ptr->transformations;
2736 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2737 /* Offset to next interlace block */
2738 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2739
2740 png_debug(1, "in png_do_read_interlace");
2741 if (row != NULL && row_info != NULL)
2742 {
2743 png_uint_32 final_width;
2744
2745 final_width = row_info->width * png_pass_inc[pass];
2746
2747 switch (row_info->pixel_depth)
2748 {
2749 case 1:
2750 {
2751 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2752 png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2753 int sshift, dshift;
2754 int s_start, s_end, s_inc;
2755 int jstop = png_pass_inc[pass];
2756 png_byte v;
2757 png_uint_32 i;
2758 int j;
2759
2760 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2761 if (transformations & PNG_PACKSWAP)
2762 {
2763 sshift = (int)((row_info->width + 7) & 0x07);
2764 dshift = (int)((final_width + 7) & 0x07);
2765 s_start = 7;
2766 s_end = 0;
2767 s_inc = -1;
2768 }
2769 else
2770 #endif
2771 {
2772 sshift = 7 - (int)((row_info->width + 7) & 0x07);
2773 dshift = 7 - (int)((final_width + 7) & 0x07);
2774 s_start = 0;
2775 s_end = 7;
2776 s_inc = 1;
2777 }
2778
2779 for (i = 0; i < row_info->width; i++)
2780 {
2781 v = (png_byte)((*sp >> sshift) & 0x01);
2782 for (j = 0; j < jstop; j++)
2783 {
2784 *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2785 *dp |= (png_byte)(v << dshift);
2786 if (dshift == s_end)
2787 {
2788 dshift = s_start;
2789 dp--;
2790 }
2791 else
2792 dshift += s_inc;
2793 }
2794 if (sshift == s_end)
2795 {
2796 sshift = s_start;
2797 sp--;
2798 }
2799 else
2800 sshift += s_inc;
2801 }
2802 break;
2803 }
2804 case 2:
2805 {
2806 png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2807 png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2808 int sshift, dshift;
2809 int s_start, s_end, s_inc;
2810 int jstop = png_pass_inc[pass];
2811 png_uint_32 i;
2812
2813 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2814 if (transformations & PNG_PACKSWAP)
2815 {
2816 sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2817 dshift = (int)(((final_width + 3) & 0x03) << 1);
2818 s_start = 6;
2819 s_end = 0;
2820 s_inc = -2;
2821 }
2822 else
2823 #endif
2824 {
2825 sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2826 dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2827 s_start = 0;
2828 s_end = 6;
2829 s_inc = 2;
2830 }
2831
2832 for (i = 0; i < row_info->width; i++)
2833 {
2834 png_byte v;
2835 int j;
2836
2837 v = (png_byte)((*sp >> sshift) & 0x03);
2838 for (j = 0; j < jstop; j++)
2839 {
2840 *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2841 *dp |= (png_byte)(v << dshift);
2842 if (dshift == s_end)
2843 {
2844 dshift = s_start;
2845 dp--;
2846 }
2847 else
2848 dshift += s_inc;
2849 }
2850 if (sshift == s_end)
2851 {
2852 sshift = s_start;
2853 sp--;
2854 }
2855 else
2856 sshift += s_inc;
2857 }
2858 break;
2859 }
2860 case 4:
2861 {
2862 png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2863 png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2864 int sshift, dshift;
2865 int s_start, s_end, s_inc;
2866 png_uint_32 i;
2867 int jstop = png_pass_inc[pass];
2868
2869 #ifdef PNG_READ_PACKSWAP_SUPPORTED
2870 if (transformations & PNG_PACKSWAP)
2871 {
2872 sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2873 dshift = (int)(((final_width + 1) & 0x01) << 2);
2874 s_start = 4;
2875 s_end = 0;
2876 s_inc = -4;
2877 }
2878 else
2879 #endif
2880 {
2881 sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2882 dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2883 s_start = 0;
2884 s_end = 4;
2885 s_inc = 4;
2886 }
2887
2888 for (i = 0; i < row_info->width; i++)
2889 {
2890 png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2891 int j;
2892
2893 for (j = 0; j < jstop; j++)
2894 {
2895 *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2896 *dp |= (png_byte)(v << dshift);
2897 if (dshift == s_end)
2898 {
2899 dshift = s_start;
2900 dp--;
2901 }
2902 else
2903 dshift += s_inc;
2904 }
2905 if (sshift == s_end)
2906 {
2907 sshift = s_start;
2908 sp--;
2909 }
2910 else
2911 sshift += s_inc;
2912 }
2913 break;
2914 }
2915 default:
2916 {
2917 png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2918 png_bytep sp = row + (png_size_t)(row_info->width - 1)
2919 * pixel_bytes;
2920 png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2921
2922 int jstop = png_pass_inc[pass];
2923 png_uint_32 i;
2924
2925 for (i = 0; i < row_info->width; i++)
2926 {
2927 png_byte v[8];
2928 int j;
2929
2930 png_memcpy(v, sp, pixel_bytes);
2931 for (j = 0; j < jstop; j++)
2932 {
2933 png_memcpy(dp, v, pixel_bytes);
2934 dp -= pixel_bytes;
2935 }
2936 sp -= pixel_bytes;
2937 }
2938 break;
2939 }
2940 }
2941 row_info->width = final_width;
2942 row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2943 }
2944 #ifndef PNG_READ_PACKSWAP_SUPPORTED
2945 transformations = transformations; /* Silence compiler warning */
2946 #endif
2947 }
2948 #endif /* PNG_READ_INTERLACING_SUPPORTED */
2949
2950 void /* PRIVATE */
png_read_filter_row(png_structp png_ptr,png_row_infop row_info,png_bytep row,png_bytep prev_row,int filter)2951 png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2952 png_bytep prev_row, int filter)
2953 {
2954 png_debug(1, "in png_read_filter_row");
2955 png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2956 switch (filter)
2957 {
2958 case PNG_FILTER_VALUE_NONE:
2959 break;
2960 case PNG_FILTER_VALUE_SUB:
2961 {
2962 png_uint_32 i;
2963 png_uint_32 istop = row_info->rowbytes;
2964 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2965 png_bytep rp = row + bpp;
2966 png_bytep lp = row;
2967
2968 for (i = bpp; i < istop; i++)
2969 {
2970 *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2971 rp++;
2972 }
2973 break;
2974 }
2975 case PNG_FILTER_VALUE_UP:
2976 {
2977 png_uint_32 i;
2978 png_uint_32 istop = row_info->rowbytes;
2979 png_bytep rp = row;
2980 png_bytep pp = prev_row;
2981
2982 for (i = 0; i < istop; i++)
2983 {
2984 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
2985 rp++;
2986 }
2987 break;
2988 }
2989 case PNG_FILTER_VALUE_AVG:
2990 {
2991 png_uint_32 i;
2992 png_bytep rp = row;
2993 png_bytep pp = prev_row;
2994 png_bytep lp = row;
2995 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2996 png_uint_32 istop = row_info->rowbytes - bpp;
2997
2998 for (i = 0; i < bpp; i++)
2999 {
3000 *rp = (png_byte)(((int)(*rp) +
3001 ((int)(*pp++) / 2 )) & 0xff);
3002 rp++;
3003 }
3004
3005 for (i = 0; i < istop; i++)
3006 {
3007 *rp = (png_byte)(((int)(*rp) +
3008 (int)(*pp++ + *lp++) / 2 ) & 0xff);
3009 rp++;
3010 }
3011 break;
3012 }
3013 case PNG_FILTER_VALUE_PAETH:
3014 {
3015 png_uint_32 i;
3016 png_bytep rp = row;
3017 png_bytep pp = prev_row;
3018 png_bytep lp = row;
3019 png_bytep cp = prev_row;
3020 png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
3021 png_uint_32 istop=row_info->rowbytes - bpp;
3022
3023 for (i = 0; i < bpp; i++)
3024 {
3025 *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3026 rp++;
3027 }
3028
3029 for (i = 0; i < istop; i++) /* Use leftover rp,pp */
3030 {
3031 int a, b, c, pa, pb, pc, p;
3032
3033 a = *lp++;
3034 b = *pp++;
3035 c = *cp++;
3036
3037 p = b - c;
3038 pc = a - c;
3039
3040 #ifdef PNG_USE_ABS
3041 pa = abs(p);
3042 pb = abs(pc);
3043 pc = abs(p + pc);
3044 #else
3045 pa = p < 0 ? -p : p;
3046 pb = pc < 0 ? -pc : pc;
3047 pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3048 #endif
3049
3050 /*
3051 if (pa <= pb && pa <= pc)
3052 p = a;
3053 else if (pb <= pc)
3054 p = b;
3055 else
3056 p = c;
3057 */
3058
3059 p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3060
3061 *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3062 rp++;
3063 }
3064 break;
3065 }
3066 default:
3067 png_warning(png_ptr, "Ignoring bad adaptive filter type");
3068 *row = 0;
3069 break;
3070 }
3071 }
3072
3073 #ifdef PNG_INDEX_SUPPORTED
3074 void /* PRIVATE */
png_set_interlaced_pass(png_structp png_ptr,int pass)3075 png_set_interlaced_pass(png_structp png_ptr, int pass)
3076 {
3077 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3078
3079 /* Start of interlace block */
3080 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3081
3082 /* Offset to next interlace block */
3083 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3084
3085 /* Start of interlace block in the y direction */
3086 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3087
3088 /* Offset to next interlace block in the y direction */
3089 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3090
3091 png_ptr->pass = pass;
3092 png_ptr->iwidth = (png_ptr->width +
3093 png_pass_inc[png_ptr->pass] - 1 -
3094 png_pass_start[png_ptr->pass]) /
3095 png_pass_inc[png_ptr->pass];
3096 }
3097 #endif
3098
3099 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3100 void /* PRIVATE */
png_read_finish_row(png_structp png_ptr)3101 png_read_finish_row(png_structp png_ptr)
3102 {
3103 #ifdef PNG_READ_INTERLACING_SUPPORTED
3104 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3105
3106 /* Start of interlace block */
3107 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3108
3109 /* Offset to next interlace block */
3110 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3111
3112 /* Start of interlace block in the y direction */
3113 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3114
3115 /* Offset to next interlace block in the y direction */
3116 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3117 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3118
3119 png_debug(1, "in png_read_finish_row");
3120 png_ptr->row_number++;
3121 if (png_ptr->row_number < png_ptr->num_rows)
3122 return;
3123
3124 #ifdef PNG_READ_INTERLACING_SUPPORTED
3125 if (png_ptr->interlaced)
3126 {
3127 png_ptr->row_number = 0;
3128 png_memset_check(png_ptr, png_ptr->prev_row, 0,
3129 png_ptr->rowbytes + 1);
3130 do
3131 {
3132 png_ptr->pass++;
3133 if (png_ptr->pass >= 7)
3134 break;
3135 png_ptr->iwidth = (png_ptr->width +
3136 png_pass_inc[png_ptr->pass] - 1 -
3137 png_pass_start[png_ptr->pass]) /
3138 png_pass_inc[png_ptr->pass];
3139
3140 if (!(png_ptr->transformations & PNG_INTERLACE))
3141 {
3142 png_ptr->num_rows = (png_ptr->height +
3143 png_pass_yinc[png_ptr->pass] - 1 -
3144 png_pass_ystart[png_ptr->pass]) /
3145 png_pass_yinc[png_ptr->pass];
3146 if (!(png_ptr->num_rows))
3147 continue;
3148 }
3149 else /* if (png_ptr->transformations & PNG_INTERLACE) */
3150 break;
3151 } while (png_ptr->iwidth == 0);
3152
3153 if (png_ptr->pass < 7)
3154 return;
3155 }
3156 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3157
3158 if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3159 {
3160 #ifdef PNG_USE_LOCAL_ARRAYS
3161 PNG_CONST PNG_IDAT;
3162 #endif
3163 char extra;
3164 int ret;
3165
3166 png_ptr->zstream.next_out = (Byte *)&extra;
3167 png_ptr->zstream.avail_out = (uInt)1;
3168 for (;;)
3169 {
3170 if (!(png_ptr->zstream.avail_in))
3171 {
3172 while (!png_ptr->idat_size)
3173 {
3174 png_byte chunk_length[4];
3175
3176 png_crc_finish(png_ptr, 0);
3177
3178 png_read_data(png_ptr, chunk_length, 4);
3179 png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3180 png_reset_crc(png_ptr);
3181 png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3182 if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3183 png_error(png_ptr, "Not enough image data");
3184
3185 }
3186 png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3187 png_ptr->zstream.next_in = png_ptr->zbuf;
3188 if (png_ptr->zbuf_size > png_ptr->idat_size)
3189 png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3190 png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3191 png_ptr->idat_size -= png_ptr->zstream.avail_in;
3192 }
3193 ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3194 if (ret == Z_STREAM_END)
3195 {
3196 if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3197 png_ptr->idat_size)
3198 png_warning(png_ptr, "Extra compressed data.");
3199 png_ptr->mode |= PNG_AFTER_IDAT;
3200 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3201 break;
3202 }
3203 if (ret != Z_OK)
3204 png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3205 "Decompression Error");
3206
3207 if (!(png_ptr->zstream.avail_out))
3208 {
3209 png_warning(png_ptr, "Extra compressed data.");
3210 png_ptr->mode |= PNG_AFTER_IDAT;
3211 png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3212 break;
3213 }
3214
3215 }
3216 png_ptr->zstream.avail_out = 0;
3217 }
3218
3219 if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3220 png_warning(png_ptr, "Extra compression data.");
3221
3222 inflateReset(&png_ptr->zstream);
3223
3224 png_ptr->mode |= PNG_AFTER_IDAT;
3225 }
3226 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3227
3228 void /* PRIVATE */
png_read_start_row(png_structp png_ptr)3229 png_read_start_row(png_structp png_ptr)
3230 {
3231 #ifdef PNG_READ_INTERLACING_SUPPORTED
3232 /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3233
3234 /* Start of interlace block */
3235 PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3236
3237 /* Offset to next interlace block */
3238 PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3239
3240 /* Start of interlace block in the y direction */
3241 PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3242
3243 /* Offset to next interlace block in the y direction */
3244 PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3245 #endif
3246
3247 int max_pixel_depth;
3248 png_size_t row_bytes;
3249
3250 png_debug(1, "in png_read_start_row");
3251 png_ptr->zstream.avail_in = 0;
3252 png_init_read_transformations(png_ptr);
3253 #ifdef PNG_READ_INTERLACING_SUPPORTED
3254 if (png_ptr->interlaced)
3255 {
3256 if (!(png_ptr->transformations & PNG_INTERLACE))
3257 png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3258 png_pass_ystart[0]) / png_pass_yinc[0];
3259 else
3260 png_ptr->num_rows = png_ptr->height;
3261
3262 png_ptr->iwidth = (png_ptr->width +
3263 png_pass_inc[png_ptr->pass] - 1 -
3264 png_pass_start[png_ptr->pass]) /
3265 png_pass_inc[png_ptr->pass];
3266 }
3267 else
3268 #endif /* PNG_READ_INTERLACING_SUPPORTED */
3269 {
3270 png_ptr->num_rows = png_ptr->height;
3271 png_ptr->iwidth = png_ptr->width;
3272 }
3273 max_pixel_depth = png_ptr->pixel_depth;
3274
3275 #ifdef PNG_READ_PACK_SUPPORTED
3276 if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3277 max_pixel_depth = 8;
3278 #endif
3279
3280 #ifdef PNG_READ_EXPAND_SUPPORTED
3281 if (png_ptr->transformations & PNG_EXPAND)
3282 {
3283 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3284 {
3285 if (png_ptr->num_trans)
3286 max_pixel_depth = 32;
3287 else
3288 max_pixel_depth = 24;
3289 }
3290 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3291 {
3292 if (max_pixel_depth < 8)
3293 max_pixel_depth = 8;
3294 if (png_ptr->num_trans)
3295 max_pixel_depth *= 2;
3296 }
3297 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3298 {
3299 if (png_ptr->num_trans)
3300 {
3301 max_pixel_depth *= 4;
3302 max_pixel_depth /= 3;
3303 }
3304 }
3305 }
3306 #endif
3307
3308 #ifdef PNG_READ_FILLER_SUPPORTED
3309 if (png_ptr->transformations & (PNG_FILLER))
3310 {
3311 if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3312 max_pixel_depth = 32;
3313 else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3314 {
3315 if (max_pixel_depth <= 8)
3316 max_pixel_depth = 16;
3317 else
3318 max_pixel_depth = 32;
3319 }
3320 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3321 {
3322 if (max_pixel_depth <= 32)
3323 max_pixel_depth = 32;
3324 else
3325 max_pixel_depth = 64;
3326 }
3327 }
3328 #endif
3329
3330 #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3331 if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3332 {
3333 if (
3334 #ifdef PNG_READ_EXPAND_SUPPORTED
3335 (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3336 #endif
3337 #ifdef PNG_READ_FILLER_SUPPORTED
3338 (png_ptr->transformations & (PNG_FILLER)) ||
3339 #endif
3340 png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3341 {
3342 if (max_pixel_depth <= 16)
3343 max_pixel_depth = 32;
3344 else
3345 max_pixel_depth = 64;
3346 }
3347 else
3348 {
3349 if (max_pixel_depth <= 8)
3350 {
3351 if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3352 max_pixel_depth = 32;
3353 else
3354 max_pixel_depth = 24;
3355 }
3356 else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3357 max_pixel_depth = 64;
3358 else
3359 max_pixel_depth = 48;
3360 }
3361 }
3362 #endif
3363
3364 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3365 defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3366 if (png_ptr->transformations & PNG_USER_TRANSFORM)
3367 {
3368 int user_pixel_depth = png_ptr->user_transform_depth*
3369 png_ptr->user_transform_channels;
3370 if (user_pixel_depth > max_pixel_depth)
3371 max_pixel_depth=user_pixel_depth;
3372 }
3373 #endif
3374
3375 /* Align the width on the next larger 8 pixels. Mainly used
3376 * for interlacing
3377 */
3378 row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3379 /* Calculate the maximum bytes needed, adding a byte and a pixel
3380 * for safety's sake
3381 */
3382 row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3383 1 + ((max_pixel_depth + 7) >> 3);
3384 #ifdef PNG_MAX_MALLOC_64K
3385 if (row_bytes > (png_uint_32)65536L)
3386 png_error(png_ptr, "This image requires a row greater than 64KB");
3387 #endif
3388
3389 if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3390 {
3391 png_free(png_ptr, png_ptr->big_row_buf);
3392 if (png_ptr->interlaced)
3393 png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3394 row_bytes + 64);
3395 else
3396 png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3397 row_bytes + 64);
3398 png_ptr->old_big_row_buf_size = row_bytes + 64;
3399
3400 /* Use 32 bytes of padding before and after row_buf. */
3401 png_ptr->row_buf = png_ptr->big_row_buf + 32;
3402 png_ptr->old_big_row_buf_size = row_bytes + 64;
3403 }
3404
3405 #ifdef PNG_MAX_MALLOC_64K
3406 if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
3407 png_error(png_ptr, "This image requires a row greater than 64KB");
3408 #endif
3409 if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3410 png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3411
3412 if (row_bytes + 1 > png_ptr->old_prev_row_size)
3413 {
3414 png_free(png_ptr, png_ptr->prev_row);
3415 png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3416 row_bytes + 1));
3417 png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3418 png_ptr->old_prev_row_size = row_bytes + 1;
3419 }
3420
3421 png_ptr->rowbytes = row_bytes;
3422
3423 png_debug1(3, "width = %lu,", png_ptr->width);
3424 png_debug1(3, "height = %lu,", png_ptr->height);
3425 png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3426 png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3427 png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3428 png_debug1(3, "irowbytes = %lu",
3429 PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3430
3431 png_ptr->flags |= PNG_FLAG_ROW_INIT;
3432 }
3433 #endif /* PNG_READ_SUPPORTED */
3434