source: trunk/src/3rdparty/libpng/pngrutil.c@ 890

Last change on this file since 890 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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