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