VirtualBox

source: vbox/trunk/src/libs/libpng-1.2.53/pngrutil.c@ 58639

最後變更 在這個檔案從58639是 58100,由 vboxsync 提交於 9 年 前

libpng 1.2.53 export fix

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette