comparison libpng/pngrutil.c @ 42:cfc262e9955c libavformat

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