/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngrutil.c
ViewVC logotype

Contents of /trunk/3rdparty/wxWidgets/src/png/pngrutil.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22