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