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