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