/[zanavi_public1]/navit/navit/support/libpng/pngrutil.c
ZANavi

Contents of /navit/navit/support/libpng/pngrutil.c

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki