1 :
2 : /* pngrutil.c - utilities to read a PNG file
3 : *
4 : * Last changed in libpng 1.5.9 [February 18, 2012]
5 : * Copyright (c) 1998-2012 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 : #include "pngpriv.h"
18 :
19 : #ifdef PNG_READ_SUPPORTED
20 :
21 : #define png_strtod(p,a,b) strtod(a,b)
22 :
23 : png_uint_32 PNGAPI
24 24 : png_get_uint_31(png_structp png_ptr, png_const_bytep buf)
25 : {
26 24 : png_uint_32 uval = png_get_uint_32(buf);
27 :
28 24 : if (uval > PNG_UINT_31_MAX)
29 0 : png_error(png_ptr, "PNG unsigned integer out of range");
30 :
31 24 : return (uval);
32 : }
33 :
34 : #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
35 : /* The following is a variation on the above for use with the fixed
36 : * point values used for gAMA and cHRM. Instead of png_error it
37 : * issues a warning and returns (-1) - an invalid value because both
38 : * gAMA and cHRM use *unsigned* integers for fixed point values.
39 : */
40 : #define PNG_FIXED_ERROR (-1)
41 :
42 : static png_fixed_point /* PRIVATE */
43 1 : png_get_fixed_point(png_structp png_ptr, png_const_bytep buf)
44 : {
45 1 : png_uint_32 uval = png_get_uint_32(buf);
46 :
47 1 : if (uval <= PNG_UINT_31_MAX)
48 1 : return (png_fixed_point)uval; /* known to be in range */
49 :
50 : /* The caller can turn off the warning by passing NULL. */
51 : if (png_ptr != NULL)
52 : png_warning(png_ptr, "PNG fixed point integer out of range");
53 :
54 0 : return PNG_FIXED_ERROR;
55 : }
56 : #endif
57 :
58 : #ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
59 : /* NOTE: the read macros will obscure these definitions, so that if
60 : * PNG_USE_READ_MACROS is set the library will not use them internally,
61 : * but the APIs will still be available externally.
62 : *
63 : * The parentheses around "PNGAPI function_name" in the following three
64 : * functions are necessary because they allow the macros to co-exist with
65 : * these (unused but exported) functions.
66 : */
67 :
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_const_bytep buf)
71 : {
72 : png_uint_32 uval =
73 : ((png_uint_32)(*(buf )) << 24) +
74 : ((png_uint_32)(*(buf + 1)) << 16) +
75 : ((png_uint_32)(*(buf + 2)) << 8) +
76 : ((png_uint_32)(*(buf + 3)) ) ;
77 :
78 : return uval;
79 : }
80 :
81 : /* Grab a signed 32-bit integer from a buffer in big-endian format. The
82 : * data is stored in the PNG file in two's complement format and there
83 : * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
84 : * the following code does a two's complement to native conversion.
85 : */
86 : png_int_32 (PNGAPI
87 : png_get_int_32)(png_const_bytep buf)
88 : {
89 : png_uint_32 uval = png_get_uint_32(buf);
90 : if ((uval & 0x80000000) == 0) /* non-negative */
91 : return uval;
92 :
93 : uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
94 : return -(png_int_32)uval;
95 : }
96 :
97 : /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
98 : png_uint_16 (PNGAPI
99 : png_get_uint_16)(png_const_bytep buf)
100 : {
101 : /* ANSI-C requires an int value to accomodate at least 16 bits so this
102 : * works and allows the compiler not to worry about possible narrowing
103 : * on 32 bit systems. (Pre-ANSI systems did not make integers smaller
104 : * than 16 bits either.)
105 : */
106 : unsigned int val =
107 : ((unsigned int)(*buf) << 8) +
108 : ((unsigned int)(*(buf + 1)));
109 :
110 : return (png_uint_16)val;
111 : }
112 :
113 : #endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
114 :
115 : /* Read and check the PNG file signature */
116 : void /* PRIVATE */
117 0 : png_read_sig(png_structp png_ptr, png_infop info_ptr)
118 : {
119 : png_size_t num_checked, num_to_check;
120 :
121 : /* Exit if the user application does not expect a signature. */
122 0 : if (png_ptr->sig_bytes >= 8)
123 0 : return;
124 :
125 0 : num_checked = png_ptr->sig_bytes;
126 0 : num_to_check = 8 - num_checked;
127 :
128 : #ifdef PNG_IO_STATE_SUPPORTED
129 : png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
130 : #endif
131 :
132 : /* The signature must be serialized in a single I/O call. */
133 0 : png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
134 0 : png_ptr->sig_bytes = 8;
135 :
136 0 : if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
137 : {
138 0 : if (num_checked < 4 &&
139 0 : png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
140 0 : png_error(png_ptr, "Not a PNG file");
141 : else
142 0 : png_error(png_ptr, "PNG file corrupted by ASCII conversion");
143 : }
144 0 : if (num_checked < 3)
145 0 : png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
146 : }
147 :
148 : /* Read the chunk header (length + type name).
149 : * Put the type name into png_ptr->chunk_name, and return the length.
150 : */
151 : png_uint_32 /* PRIVATE */
152 0 : png_read_chunk_header(png_structp png_ptr)
153 : {
154 : png_byte buf[8];
155 : png_uint_32 length;
156 :
157 : #ifdef PNG_IO_STATE_SUPPORTED
158 : png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
159 : #endif
160 :
161 : /* Read the length and the chunk name.
162 : * This must be performed in a single I/O call.
163 : */
164 0 : png_read_data(png_ptr, buf, 8);
165 0 : length = png_get_uint_31(png_ptr, buf);
166 :
167 : /* Put the chunk name into png_ptr->chunk_name. */
168 0 : png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
169 :
170 : png_debug2(0, "Reading %lx chunk, length = %lu",
171 : (unsigned long)png_ptr->chunk_name, (unsigned long)length);
172 :
173 : /* Reset the crc and run it over the chunk name. */
174 0 : png_reset_crc(png_ptr);
175 0 : png_calculate_crc(png_ptr, buf + 4, 4);
176 :
177 : /* Check to see if chunk name is valid. */
178 0 : png_check_chunk_name(png_ptr, png_ptr->chunk_name);
179 :
180 : #ifdef PNG_IO_STATE_SUPPORTED
181 : png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
182 : #endif
183 :
184 0 : return length;
185 : }
186 :
187 : /* Read data, and (optionally) run it through the CRC. */
188 : void /* PRIVATE */
189 21 : png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
190 : {
191 21 : if (png_ptr == NULL)
192 0 : return;
193 :
194 21 : png_read_data(png_ptr, buf, length);
195 21 : png_calculate_crc(png_ptr, buf, length);
196 : }
197 :
198 : /* Optionally skip data and then check the CRC. Depending on whether we
199 : * are reading a ancillary or critical chunk, and how the program has set
200 : * things up, we may calculate the CRC on the data and print a message.
201 : * Returns '1' if there was a CRC error, '0' otherwise.
202 : */
203 : int /* PRIVATE */
204 16 : png_crc_finish(png_structp png_ptr, png_uint_32 skip)
205 : {
206 : png_size_t i;
207 16 : png_size_t istop = png_ptr->zbuf_size;
208 :
209 16 : for (i = (png_size_t)skip; i > istop; i -= istop)
210 : {
211 0 : png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
212 : }
213 :
214 16 : if (i)
215 : {
216 0 : png_crc_read(png_ptr, png_ptr->zbuf, i);
217 : }
218 :
219 16 : if (png_crc_error(png_ptr))
220 : {
221 0 : if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name) ?
222 0 : !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
223 0 : (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
224 : {
225 : png_chunk_warning(png_ptr, "CRC error");
226 : }
227 :
228 : else
229 : {
230 0 : png_chunk_benign_error(png_ptr, "CRC error");
231 : return (0);
232 : }
233 :
234 0 : return (1);
235 : }
236 :
237 16 : return (0);
238 : }
239 :
240 : /* Compare the CRC stored in the PNG file with that calculated by libpng from
241 : * the data it has read thus far.
242 : */
243 : int /* PRIVATE */
244 16 : png_crc_error(png_structp png_ptr)
245 : {
246 : png_byte crc_bytes[4];
247 : png_uint_32 crc;
248 16 : int need_crc = 1;
249 :
250 16 : if (PNG_CHUNK_ANCILLIARY(png_ptr->chunk_name))
251 : {
252 2 : if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
253 : (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
254 0 : need_crc = 0;
255 : }
256 :
257 : else /* critical */
258 : {
259 14 : if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
260 0 : need_crc = 0;
261 : }
262 :
263 : #ifdef PNG_IO_STATE_SUPPORTED
264 : png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
265 : #endif
266 :
267 : /* The chunk CRC must be serialized in a single I/O call. */
268 16 : png_read_data(png_ptr, crc_bytes, 4);
269 :
270 16 : if (need_crc)
271 : {
272 16 : crc = png_get_uint_32(crc_bytes);
273 16 : return ((int)(crc != png_ptr->crc));
274 : }
275 :
276 : else
277 0 : return (0);
278 : }
279 :
280 : #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
281 : static png_size_t
282 0 : png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
283 : png_bytep output, png_size_t output_size)
284 : {
285 0 : png_size_t count = 0;
286 :
287 : /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
288 : * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
289 : * more". Consequently it is necessary to chunk the input to zlib. This
290 : * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
291 : * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a
292 : * lower value in pngpriv.h and this may sometimes have a performance
293 : * advantage, because it forces access of the input data to be separated from
294 : * at least some of the use by some period of time.
295 : */
296 0 : png_ptr->zstream.next_in = data;
297 : /* avail_in is set below from 'size' */
298 0 : png_ptr->zstream.avail_in = 0;
299 :
300 : while (1)
301 : {
302 : int ret, avail;
303 :
304 : /* The setting of 'avail_in' used to be outside the loop; by setting it
305 : * inside it is possible to chunk the input to zlib and simply rely on
306 : * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o
307 : * data to be passed through zlib at the unavoidable cost of requiring a
308 : * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
309 : * input bytes.
310 : */
311 0 : if (png_ptr->zstream.avail_in == 0 && size > 0)
312 : {
313 : if (size <= ZLIB_IO_MAX)
314 : {
315 : /* The value is less than ZLIB_IO_MAX so the cast is safe: */
316 0 : png_ptr->zstream.avail_in = (uInt)size;
317 0 : size = 0;
318 : }
319 :
320 : else
321 : {
322 : png_ptr->zstream.avail_in = ZLIB_IO_MAX;
323 : size -= ZLIB_IO_MAX;
324 : }
325 : }
326 :
327 : /* Reset the output buffer each time round - we empty it
328 : * after every inflate call.
329 : */
330 0 : png_ptr->zstream.next_out = png_ptr->zbuf;
331 0 : png_ptr->zstream.avail_out = png_ptr->zbuf_size;
332 :
333 0 : ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
334 0 : avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
335 :
336 : /* First copy/count any new output - but only if we didn't
337 : * get an error code.
338 : */
339 0 : if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
340 : {
341 0 : png_size_t space = avail; /* > 0, see above */
342 :
343 0 : if (output != 0 && output_size > count)
344 : {
345 0 : png_size_t copy = output_size - count;
346 :
347 0 : if (space < copy)
348 0 : copy = space;
349 :
350 0 : png_memcpy(output + count, png_ptr->zbuf, copy);
351 : }
352 0 : count += space;
353 : }
354 :
355 0 : if (ret == Z_OK)
356 0 : continue;
357 :
358 : /* Termination conditions - always reset the zstream, it
359 : * must be left in inflateInit state.
360 : */
361 0 : png_ptr->zstream.avail_in = 0;
362 0 : inflateReset(&png_ptr->zstream);
363 :
364 0 : if (ret == Z_STREAM_END)
365 0 : return count; /* NOTE: may be zero. */
366 :
367 : /* Now handle the error codes - the API always returns 0
368 : * and the error message is dumped into the uncompressed
369 : * buffer if available.
370 : */
371 : # ifdef PNG_WARNINGS_SUPPORTED
372 : {
373 : png_const_charp msg;
374 :
375 : if (png_ptr->zstream.msg != 0)
376 : msg = png_ptr->zstream.msg;
377 :
378 : else switch (ret)
379 : {
380 : case Z_BUF_ERROR:
381 : msg = "Buffer error in compressed datastream";
382 : break;
383 :
384 : case Z_DATA_ERROR:
385 : msg = "Data error in compressed datastream";
386 : break;
387 :
388 : default:
389 : msg = "Incomplete compressed datastream";
390 : break;
391 : }
392 :
393 : png_chunk_warning(png_ptr, msg);
394 : }
395 : # endif
396 :
397 : /* 0 means an error - notice that this code simply ignores
398 : * zero length compressed chunks as a result.
399 : */
400 0 : return 0;
401 0 : }
402 : }
403 :
404 : /*
405 : * Decompress trailing data in a chunk. The assumption is that chunkdata
406 : * points at an allocated area holding the contents of a chunk with a
407 : * trailing compressed part. What we get back is an allocated area
408 : * holding the original prefix part and an uncompressed version of the
409 : * trailing part (the malloc area passed in is freed).
410 : */
411 : void /* PRIVATE */
412 0 : png_decompress_chunk(png_structp png_ptr, int comp_type,
413 : png_size_t chunklength,
414 : png_size_t prefix_size, png_size_t *newlength)
415 : {
416 : /* The caller should guarantee this */
417 0 : if (prefix_size > chunklength)
418 : {
419 : /* The recovery is to delete the chunk. */
420 : png_warning(png_ptr, "invalid chunklength");
421 0 : prefix_size = 0; /* To delete everything */
422 : }
423 :
424 0 : else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
425 : {
426 0 : png_size_t expanded_size = png_inflate(png_ptr,
427 0 : (png_bytep)(png_ptr->chunkdata + prefix_size),
428 : chunklength - prefix_size,
429 : 0, /* output */
430 : 0); /* output size */
431 :
432 : /* Now check the limits on this chunk - if the limit fails the
433 : * compressed data will be removed, the prefix will remain.
434 : */
435 0 : if (prefix_size >= (~(png_size_t)0) - 1 ||
436 0 : expanded_size >= (~(png_size_t)0) - 1 - prefix_size
437 : #ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
438 : || (png_ptr->user_chunk_malloc_max &&
439 : (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
440 : #else
441 : # ifdef PNG_USER_CHUNK_MALLOC_MAX
442 0 : || ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
443 0 : prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
444 : # endif
445 : #endif
446 : )
447 : png_warning(png_ptr, "Exceeded size limit while expanding chunk");
448 :
449 : /* If the size is zero either there was an error and a message
450 : * has already been output (warning) or the size really is zero
451 : * and we have nothing to do - the code will exit through the
452 : * error case below.
453 : */
454 0 : else if (expanded_size > 0)
455 : {
456 : /* Success (maybe) - really uncompress the chunk. */
457 0 : png_size_t new_size = 0;
458 0 : png_charp text = (png_charp)png_malloc_warn(png_ptr,
459 0 : prefix_size + expanded_size + 1);
460 :
461 0 : if (text != NULL)
462 : {
463 0 : png_memcpy(text, png_ptr->chunkdata, prefix_size);
464 0 : new_size = png_inflate(png_ptr,
465 0 : (png_bytep)(png_ptr->chunkdata + prefix_size),
466 : chunklength - prefix_size,
467 0 : (png_bytep)(text + prefix_size), expanded_size);
468 0 : text[prefix_size + expanded_size] = 0; /* just in case */
469 :
470 0 : if (new_size == expanded_size)
471 : {
472 0 : png_free(png_ptr, png_ptr->chunkdata);
473 0 : png_ptr->chunkdata = text;
474 0 : *newlength = prefix_size + expanded_size;
475 0 : return; /* The success return! */
476 : }
477 :
478 : png_warning(png_ptr, "png_inflate logic error");
479 0 : png_free(png_ptr, text);
480 : }
481 :
482 : else
483 : png_warning(png_ptr, "Not enough memory to decompress chunk");
484 : }
485 : }
486 :
487 : else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
488 : {
489 : PNG_WARNING_PARAMETERS(p)
490 : png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_d, comp_type);
491 : png_formatted_warning(png_ptr, p, "Unknown compression type @1");
492 :
493 : /* The recovery is to simply drop the data. */
494 : }
495 :
496 : /* Generic error return - leave the prefix, delete the compressed
497 : * data, reallocate the chunkdata to remove the potentially large
498 : * amount of compressed data.
499 : */
500 : {
501 0 : png_charp text = (png_charp)png_malloc_warn(png_ptr, prefix_size + 1);
502 :
503 0 : if (text != NULL)
504 : {
505 0 : if (prefix_size > 0)
506 0 : png_memcpy(text, png_ptr->chunkdata, prefix_size);
507 :
508 0 : png_free(png_ptr, png_ptr->chunkdata);
509 0 : png_ptr->chunkdata = text;
510 :
511 : /* This is an extra zero in the 'uncompressed' part. */
512 0 : *(png_ptr->chunkdata + prefix_size) = 0x00;
513 : }
514 : /* Ignore a malloc error here - it is safe. */
515 : }
516 :
517 0 : *newlength = prefix_size;
518 : }
519 : #endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
520 :
521 : /* Read and check the IDHR chunk */
522 : void /* PRIVATE */
523 4 : png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
524 : {
525 : png_byte buf[13];
526 : png_uint_32 width, height;
527 : int bit_depth, color_type, compression_type, filter_type;
528 : int interlace_type;
529 :
530 : png_debug(1, "in png_handle_IHDR");
531 :
532 4 : if (png_ptr->mode & PNG_HAVE_IHDR)
533 0 : png_error(png_ptr, "Out of place IHDR");
534 :
535 : /* Check the length */
536 4 : if (length != 13)
537 0 : png_error(png_ptr, "Invalid IHDR chunk");
538 :
539 4 : png_ptr->mode |= PNG_HAVE_IHDR;
540 :
541 4 : png_crc_read(png_ptr, buf, 13);
542 4 : png_crc_finish(png_ptr, 0);
543 :
544 4 : width = png_get_uint_31(png_ptr, buf);
545 4 : height = png_get_uint_31(png_ptr, buf + 4);
546 4 : bit_depth = buf[8];
547 4 : color_type = buf[9];
548 4 : compression_type = buf[10];
549 4 : filter_type = buf[11];
550 4 : interlace_type = buf[12];
551 :
552 : #ifdef PNG_READ_APNG_SUPPORTED
553 4 : png_ptr->first_frame_width = width;
554 4 : png_ptr->first_frame_height = height;
555 : #endif
556 :
557 : /* Set internal variables */
558 4 : png_ptr->width = width;
559 4 : png_ptr->height = height;
560 4 : png_ptr->bit_depth = (png_byte)bit_depth;
561 4 : png_ptr->interlaced = (png_byte)interlace_type;
562 4 : png_ptr->color_type = (png_byte)color_type;
563 : #ifdef PNG_MNG_FEATURES_SUPPORTED
564 : png_ptr->filter_type = (png_byte)filter_type;
565 : #endif
566 4 : png_ptr->compression_type = (png_byte)compression_type;
567 :
568 : /* Find number of channels */
569 4 : switch (png_ptr->color_type)
570 : {
571 : default: /* invalid, png_set_IHDR calls png_error */
572 : case PNG_COLOR_TYPE_GRAY:
573 : case PNG_COLOR_TYPE_PALETTE:
574 0 : png_ptr->channels = 1;
575 0 : break;
576 :
577 : case PNG_COLOR_TYPE_RGB:
578 1 : png_ptr->channels = 3;
579 1 : break;
580 :
581 : case PNG_COLOR_TYPE_GRAY_ALPHA:
582 0 : png_ptr->channels = 2;
583 0 : break;
584 :
585 : case PNG_COLOR_TYPE_RGB_ALPHA:
586 3 : png_ptr->channels = 4;
587 3 : break;
588 : }
589 :
590 : /* Set up other useful info */
591 8 : png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
592 4 : png_ptr->channels);
593 4 : png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
594 : png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
595 : png_debug1(3, "channels = %d", png_ptr->channels);
596 : png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
597 4 : png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
598 : color_type, interlace_type, compression_type, filter_type);
599 4 : }
600 :
601 : /* Read and check the palette */
602 : void /* PRIVATE */
603 0 : png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
604 : {
605 : png_color palette[PNG_MAX_PALETTE_LENGTH];
606 : int num, i;
607 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
608 : png_colorp pal_ptr;
609 : #endif
610 :
611 : png_debug(1, "in png_handle_PLTE");
612 :
613 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
614 0 : png_error(png_ptr, "Missing IHDR before PLTE");
615 :
616 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
617 : {
618 : png_warning(png_ptr, "Invalid PLTE after IDAT");
619 0 : png_crc_finish(png_ptr, length);
620 0 : return;
621 : }
622 :
623 0 : else if (png_ptr->mode & PNG_HAVE_PLTE)
624 0 : png_error(png_ptr, "Duplicate PLTE chunk");
625 :
626 0 : png_ptr->mode |= PNG_HAVE_PLTE;
627 :
628 0 : if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
629 : {
630 : png_warning(png_ptr,
631 : "Ignoring PLTE chunk in grayscale PNG");
632 0 : png_crc_finish(png_ptr, length);
633 0 : return;
634 : }
635 :
636 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
637 0 : if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
638 : {
639 0 : png_crc_finish(png_ptr, length);
640 0 : return;
641 : }
642 : #endif
643 :
644 0 : if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
645 : {
646 0 : if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
647 : {
648 : png_warning(png_ptr, "Invalid palette chunk");
649 0 : png_crc_finish(png_ptr, length);
650 0 : return;
651 : }
652 :
653 : else
654 : {
655 0 : png_error(png_ptr, "Invalid palette chunk");
656 : }
657 : }
658 :
659 0 : num = (int)length / 3;
660 :
661 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
662 0 : for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
663 : {
664 : png_byte buf[3];
665 :
666 0 : png_crc_read(png_ptr, buf, 3);
667 0 : pal_ptr->red = buf[0];
668 0 : pal_ptr->green = buf[1];
669 0 : pal_ptr->blue = buf[2];
670 : }
671 : #else
672 : for (i = 0; i < num; i++)
673 : {
674 : png_byte buf[3];
675 :
676 : png_crc_read(png_ptr, buf, 3);
677 : /* Don't depend upon png_color being any order */
678 : palette[i].red = buf[0];
679 : palette[i].green = buf[1];
680 : palette[i].blue = buf[2];
681 : }
682 : #endif
683 :
684 : /* If we actually need the PLTE chunk (ie for a paletted image), we do
685 : * whatever the normal CRC configuration tells us. However, if we
686 : * have an RGB image, the PLTE can be considered ancillary, so
687 : * we will act as though it is.
688 : */
689 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
690 0 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
691 : #endif
692 : {
693 0 : png_crc_finish(png_ptr, 0);
694 : }
695 :
696 : #ifndef PNG_READ_OPT_PLTE_SUPPORTED
697 0 : else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
698 : {
699 : /* If we don't want to use the data from an ancillary chunk,
700 : * we have two options: an error abort, or a warning and we
701 : * ignore the data in this chunk (which should be OK, since
702 : * it's considered ancillary for a RGB or RGBA image).
703 : */
704 0 : if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
705 : {
706 0 : if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
707 : {
708 0 : png_chunk_benign_error(png_ptr, "CRC error");
709 : }
710 :
711 : else
712 : {
713 : png_chunk_warning(png_ptr, "CRC error");
714 0 : return;
715 : }
716 : }
717 :
718 : /* Otherwise, we (optionally) emit a warning and use the chunk. */
719 0 : else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
720 : {
721 : png_chunk_warning(png_ptr, "CRC error");
722 : }
723 : }
724 : #endif
725 :
726 0 : png_set_PLTE(png_ptr, info_ptr, palette, num);
727 :
728 : #ifdef PNG_READ_tRNS_SUPPORTED
729 0 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
730 : {
731 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
732 : {
733 0 : if (png_ptr->num_trans > (png_uint_16)num)
734 : {
735 : png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
736 0 : png_ptr->num_trans = (png_uint_16)num;
737 : }
738 :
739 0 : if (info_ptr->num_trans > (png_uint_16)num)
740 : {
741 : png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
742 0 : info_ptr->num_trans = (png_uint_16)num;
743 : }
744 : }
745 : }
746 : #endif
747 :
748 : }
749 :
750 : void /* PRIVATE */
751 4 : png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
752 : {
753 : png_debug(1, "in png_handle_IEND");
754 :
755 4 : if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
756 : {
757 0 : png_error(png_ptr, "No image in file");
758 : }
759 :
760 4 : png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
761 :
762 : if (length != 0)
763 : {
764 : png_warning(png_ptr, "Incorrect IEND chunk length");
765 : }
766 :
767 4 : png_crc_finish(png_ptr, length);
768 :
769 : PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
770 4 : }
771 :
772 : #ifdef PNG_READ_gAMA_SUPPORTED
773 : void /* PRIVATE */
774 1 : png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
775 : {
776 : png_fixed_point igamma;
777 : png_byte buf[4];
778 :
779 : png_debug(1, "in png_handle_gAMA");
780 :
781 1 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
782 0 : png_error(png_ptr, "Missing IHDR before gAMA");
783 :
784 1 : else if (png_ptr->mode & PNG_HAVE_IDAT)
785 : {
786 : png_warning(png_ptr, "Invalid gAMA after IDAT");
787 0 : png_crc_finish(png_ptr, length);
788 0 : return;
789 : }
790 :
791 1 : else if (png_ptr->mode & PNG_HAVE_PLTE)
792 : /* Should be an error, but we can cope with it */
793 : png_warning(png_ptr, "Out of place gAMA chunk");
794 :
795 1 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
796 : #ifdef PNG_READ_sRGB_SUPPORTED
797 0 : && !(info_ptr->valid & PNG_INFO_sRGB)
798 : #endif
799 : )
800 : {
801 : png_warning(png_ptr, "Duplicate gAMA chunk");
802 0 : png_crc_finish(png_ptr, length);
803 0 : return;
804 : }
805 :
806 1 : if (length != 4)
807 : {
808 : png_warning(png_ptr, "Incorrect gAMA chunk length");
809 0 : png_crc_finish(png_ptr, length);
810 0 : return;
811 : }
812 :
813 1 : png_crc_read(png_ptr, buf, 4);
814 :
815 1 : if (png_crc_finish(png_ptr, 0))
816 0 : return;
817 :
818 1 : igamma = png_get_fixed_point(NULL, buf);
819 :
820 : /* Check for zero gamma or an error. */
821 1 : if (igamma <= 0)
822 : {
823 : png_warning(png_ptr,
824 : "Ignoring gAMA chunk with out of range gamma");
825 :
826 0 : return;
827 : }
828 :
829 : # ifdef PNG_READ_sRGB_SUPPORTED
830 1 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
831 : {
832 0 : if (PNG_OUT_OF_RANGE(igamma, 45500, 500))
833 : {
834 : PNG_WARNING_PARAMETERS(p)
835 : png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, igamma);
836 : png_formatted_warning(png_ptr, p,
837 : "Ignoring incorrect gAMA value @1 when sRGB is also present");
838 0 : return;
839 : }
840 : }
841 : # endif /* PNG_READ_sRGB_SUPPORTED */
842 :
843 : # ifdef PNG_READ_GAMMA_SUPPORTED
844 : /* Gamma correction on read is supported. */
845 1 : png_ptr->gamma = igamma;
846 : # endif
847 : /* And set the 'info' structure members. */
848 1 : png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
849 : }
850 : #endif
851 :
852 : #ifdef PNG_READ_sBIT_SUPPORTED
853 : void /* PRIVATE */
854 : png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
855 : {
856 : png_size_t truelen;
857 : png_byte buf[4];
858 :
859 : png_debug(1, "in png_handle_sBIT");
860 :
861 : buf[0] = buf[1] = buf[2] = buf[3] = 0;
862 :
863 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
864 : png_error(png_ptr, "Missing IHDR before sBIT");
865 :
866 : else if (png_ptr->mode & PNG_HAVE_IDAT)
867 : {
868 : png_warning(png_ptr, "Invalid sBIT after IDAT");
869 : png_crc_finish(png_ptr, length);
870 : return;
871 : }
872 :
873 : else if (png_ptr->mode & PNG_HAVE_PLTE)
874 : {
875 : /* Should be an error, but we can cope with it */
876 : png_warning(png_ptr, "Out of place sBIT chunk");
877 : }
878 :
879 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
880 : {
881 : png_warning(png_ptr, "Duplicate sBIT chunk");
882 : png_crc_finish(png_ptr, length);
883 : return;
884 : }
885 :
886 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
887 : truelen = 3;
888 :
889 : else
890 : truelen = (png_size_t)png_ptr->channels;
891 :
892 : if (length != truelen || length > 4)
893 : {
894 : png_warning(png_ptr, "Incorrect sBIT chunk length");
895 : png_crc_finish(png_ptr, length);
896 : return;
897 : }
898 :
899 : png_crc_read(png_ptr, buf, truelen);
900 :
901 : if (png_crc_finish(png_ptr, 0))
902 : return;
903 :
904 : if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
905 : {
906 : png_ptr->sig_bit.red = buf[0];
907 : png_ptr->sig_bit.green = buf[1];
908 : png_ptr->sig_bit.blue = buf[2];
909 : png_ptr->sig_bit.alpha = buf[3];
910 : }
911 :
912 : else
913 : {
914 : png_ptr->sig_bit.gray = buf[0];
915 : png_ptr->sig_bit.red = buf[0];
916 : png_ptr->sig_bit.green = buf[0];
917 : png_ptr->sig_bit.blue = buf[0];
918 : png_ptr->sig_bit.alpha = buf[1];
919 : }
920 :
921 : png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
922 : }
923 : #endif
924 :
925 : #ifdef PNG_READ_cHRM_SUPPORTED
926 : void /* PRIVATE */
927 0 : png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
928 : {
929 : png_byte buf[32];
930 : png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue,
931 : y_blue;
932 :
933 : png_debug(1, "in png_handle_cHRM");
934 :
935 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
936 0 : png_error(png_ptr, "Missing IHDR before cHRM");
937 :
938 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
939 : {
940 : png_warning(png_ptr, "Invalid cHRM after IDAT");
941 0 : png_crc_finish(png_ptr, length);
942 0 : return;
943 : }
944 :
945 0 : else if (png_ptr->mode & PNG_HAVE_PLTE)
946 : /* Should be an error, but we can cope with it */
947 : png_warning(png_ptr, "Out of place cHRM chunk");
948 :
949 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
950 : # ifdef PNG_READ_sRGB_SUPPORTED
951 0 : && !(info_ptr->valid & PNG_INFO_sRGB)
952 : # endif
953 : )
954 : {
955 : png_warning(png_ptr, "Duplicate cHRM chunk");
956 0 : png_crc_finish(png_ptr, length);
957 0 : return;
958 : }
959 :
960 0 : if (length != 32)
961 : {
962 : png_warning(png_ptr, "Incorrect cHRM chunk length");
963 0 : png_crc_finish(png_ptr, length);
964 0 : return;
965 : }
966 :
967 0 : png_crc_read(png_ptr, buf, 32);
968 :
969 0 : if (png_crc_finish(png_ptr, 0))
970 0 : return;
971 :
972 0 : x_white = png_get_fixed_point(NULL, buf);
973 0 : y_white = png_get_fixed_point(NULL, buf + 4);
974 0 : x_red = png_get_fixed_point(NULL, buf + 8);
975 0 : y_red = png_get_fixed_point(NULL, buf + 12);
976 0 : x_green = png_get_fixed_point(NULL, buf + 16);
977 0 : y_green = png_get_fixed_point(NULL, buf + 20);
978 0 : x_blue = png_get_fixed_point(NULL, buf + 24);
979 0 : y_blue = png_get_fixed_point(NULL, buf + 28);
980 :
981 0 : if (x_white == PNG_FIXED_ERROR ||
982 0 : y_white == PNG_FIXED_ERROR ||
983 0 : x_red == PNG_FIXED_ERROR ||
984 0 : y_red == PNG_FIXED_ERROR ||
985 0 : x_green == PNG_FIXED_ERROR ||
986 0 : y_green == PNG_FIXED_ERROR ||
987 0 : x_blue == PNG_FIXED_ERROR ||
988 : y_blue == PNG_FIXED_ERROR)
989 : {
990 : png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities");
991 0 : return;
992 : }
993 :
994 : #ifdef PNG_READ_sRGB_SUPPORTED
995 0 : if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
996 : {
997 : if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) ||
998 : PNG_OUT_OF_RANGE(y_white, 32900, 1000) ||
999 : PNG_OUT_OF_RANGE(x_red, 64000, 1000) ||
1000 : PNG_OUT_OF_RANGE(y_red, 33000, 1000) ||
1001 : PNG_OUT_OF_RANGE(x_green, 30000, 1000) ||
1002 : PNG_OUT_OF_RANGE(y_green, 60000, 1000) ||
1003 : PNG_OUT_OF_RANGE(x_blue, 15000, 1000) ||
1004 : PNG_OUT_OF_RANGE(y_blue, 6000, 1000))
1005 : {
1006 : PNG_WARNING_PARAMETERS(p)
1007 :
1008 : png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed, x_white);
1009 : png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_fixed, y_white);
1010 : png_warning_parameter_signed(p, 3, PNG_NUMBER_FORMAT_fixed, x_red);
1011 : png_warning_parameter_signed(p, 4, PNG_NUMBER_FORMAT_fixed, y_red);
1012 : png_warning_parameter_signed(p, 5, PNG_NUMBER_FORMAT_fixed, x_green);
1013 : png_warning_parameter_signed(p, 6, PNG_NUMBER_FORMAT_fixed, y_green);
1014 : png_warning_parameter_signed(p, 7, PNG_NUMBER_FORMAT_fixed, x_blue);
1015 : png_warning_parameter_signed(p, 8, PNG_NUMBER_FORMAT_fixed, y_blue);
1016 :
1017 : png_formatted_warning(png_ptr, p,
1018 : "Ignoring incorrect cHRM white(@1,@2) r(@3,@4)g(@5,@6)b(@7,@8) "
1019 : "when sRGB is also present");
1020 : }
1021 0 : return;
1022 : }
1023 : #endif /* PNG_READ_sRGB_SUPPORTED */
1024 :
1025 : #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1026 : /* Store the _white values as default coefficients for the rgb to gray
1027 : * operation if it is supported. Check if the transform is already set to
1028 : * avoid destroying the transform values.
1029 : */
1030 : if (!png_ptr->rgb_to_gray_coefficients_set)
1031 : {
1032 : /* png_set_background has not been called and we haven't seen an sRGB
1033 : * chunk yet. Find the XYZ of the three end points.
1034 : */
1035 : png_XYZ XYZ;
1036 : png_xy xy;
1037 :
1038 : xy.redx = x_red;
1039 : xy.redy = y_red;
1040 : xy.greenx = x_green;
1041 : xy.greeny = y_green;
1042 : xy.bluex = x_blue;
1043 : xy.bluey = y_blue;
1044 : xy.whitex = x_white;
1045 : xy.whitey = y_white;
1046 :
1047 : if (png_XYZ_from_xy_checked(png_ptr, &XYZ, xy))
1048 : {
1049 : /* The success case, because XYZ_from_xy normalises to a reference
1050 : * white Y of 1.0 we just need to scale the numbers. This should
1051 : * always work just fine. It is an internal error if this overflows.
1052 : */
1053 : {
1054 : png_fixed_point r, g, b;
1055 : if (png_muldiv(&r, XYZ.redY, 32768, PNG_FP_1) &&
1056 : r >= 0 && r <= 32768 &&
1057 : png_muldiv(&g, XYZ.greenY, 32768, PNG_FP_1) &&
1058 : g >= 0 && g <= 32768 &&
1059 : png_muldiv(&b, XYZ.blueY, 32768, PNG_FP_1) &&
1060 : b >= 0 && b <= 32768 &&
1061 : r+g+b <= 32769)
1062 : {
1063 : /* We allow 0 coefficients here. r+g+b may be 32769 if two or
1064 : * all of the coefficients were rounded up. Handle this by
1065 : * reducing the *largest* coefficient by 1; this matches the
1066 : * approach used for the default coefficients in pngrtran.c
1067 : */
1068 : int add = 0;
1069 :
1070 : if (r+g+b > 32768)
1071 : add = -1;
1072 : else if (r+g+b < 32768)
1073 : add = 1;
1074 :
1075 : if (add != 0)
1076 : {
1077 : if (g >= r && g >= b)
1078 : g += add;
1079 : else if (r >= g && r >= b)
1080 : r += add;
1081 : else
1082 : b += add;
1083 : }
1084 :
1085 : /* Check for an internal error. */
1086 : if (r+g+b != 32768)
1087 : png_error(png_ptr,
1088 : "internal error handling cHRM coefficients");
1089 :
1090 : png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
1091 : png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
1092 : }
1093 :
1094 : /* This is a png_error at present even though it could be ignored -
1095 : * it should never happen, but it is important that if it does, the
1096 : * bug is fixed.
1097 : */
1098 : else
1099 : png_error(png_ptr, "internal error handling cHRM->XYZ");
1100 : }
1101 : }
1102 : }
1103 : #endif
1104 :
1105 0 : png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red,
1106 : x_green, y_green, x_blue, y_blue);
1107 : }
1108 : #endif
1109 :
1110 : #ifdef PNG_READ_sRGB_SUPPORTED
1111 : void /* PRIVATE */
1112 0 : png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1113 : {
1114 : int intent;
1115 : png_byte buf[1];
1116 :
1117 : png_debug(1, "in png_handle_sRGB");
1118 :
1119 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1120 0 : png_error(png_ptr, "Missing IHDR before sRGB");
1121 :
1122 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1123 : {
1124 : png_warning(png_ptr, "Invalid sRGB after IDAT");
1125 0 : png_crc_finish(png_ptr, length);
1126 0 : return;
1127 : }
1128 :
1129 0 : else if (png_ptr->mode & PNG_HAVE_PLTE)
1130 : /* Should be an error, but we can cope with it */
1131 : png_warning(png_ptr, "Out of place sRGB chunk");
1132 :
1133 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
1134 : {
1135 : png_warning(png_ptr, "Duplicate sRGB chunk");
1136 0 : png_crc_finish(png_ptr, length);
1137 0 : return;
1138 : }
1139 :
1140 0 : if (length != 1)
1141 : {
1142 : png_warning(png_ptr, "Incorrect sRGB chunk length");
1143 0 : png_crc_finish(png_ptr, length);
1144 0 : return;
1145 : }
1146 :
1147 0 : png_crc_read(png_ptr, buf, 1);
1148 :
1149 0 : if (png_crc_finish(png_ptr, 0))
1150 0 : return;
1151 :
1152 0 : intent = buf[0];
1153 :
1154 : /* Check for bad intent */
1155 0 : if (intent >= PNG_sRGB_INTENT_LAST)
1156 : {
1157 : png_warning(png_ptr, "Unknown sRGB intent");
1158 0 : return;
1159 : }
1160 :
1161 : #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1162 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1163 : {
1164 0 : if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500, 500))
1165 : {
1166 : PNG_WARNING_PARAMETERS(p)
1167 :
1168 : png_warning_parameter_signed(p, 1, PNG_NUMBER_FORMAT_fixed,
1169 : info_ptr->gamma);
1170 :
1171 : png_formatted_warning(png_ptr, p,
1172 : "Ignoring incorrect gAMA value @1 when sRGB is also present");
1173 : }
1174 : }
1175 : #endif /* PNG_READ_gAMA_SUPPORTED */
1176 :
1177 : #ifdef PNG_READ_cHRM_SUPPORTED
1178 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1179 0 : if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) ||
1180 0 : PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) ||
1181 0 : PNG_OUT_OF_RANGE(info_ptr->x_red, 64000, 1000) ||
1182 0 : PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) ||
1183 0 : PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) ||
1184 0 : PNG_OUT_OF_RANGE(info_ptr->y_green, 60000, 1000) ||
1185 0 : PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) ||
1186 0 : PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000))
1187 : {
1188 : png_warning(png_ptr,
1189 : "Ignoring incorrect cHRM value when sRGB is also present");
1190 : }
1191 : #endif /* PNG_READ_cHRM_SUPPORTED */
1192 :
1193 : /* This is recorded for use when handling the cHRM chunk above. An sRGB
1194 : * chunk unconditionally overwrites the coefficients for grayscale conversion
1195 : * too.
1196 : */
1197 0 : png_ptr->is_sRGB = 1;
1198 :
1199 : # ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
1200 : /* Don't overwrite user supplied values: */
1201 : if (!png_ptr->rgb_to_gray_coefficients_set)
1202 : {
1203 : /* These numbers come from the sRGB specification (or, since one has to
1204 : * pay much money to get a copy, the wikipedia sRGB page) the
1205 : * chromaticity values quoted have been inverted to get the reverse
1206 : * transformation from RGB to XYZ and the 'Y' coefficients scaled by
1207 : * 32768 (then rounded).
1208 : *
1209 : * sRGB and ITU Rec-709 both truncate the values for the D65 white
1210 : * point to four digits and, even though it actually stores five
1211 : * digits, the PNG spec gives the truncated value.
1212 : *
1213 : * This means that when the chromaticities are converted back to XYZ
1214 : * end points we end up with (6968,23435,2366), which, as described in
1215 : * pngrtran.c, would overflow. If the five digit precision and up is
1216 : * used we get, instead:
1217 : *
1218 : * 6968*R + 23435*G + 2365*B
1219 : *
1220 : * (Notice that this rounds the blue coefficient down, rather than the
1221 : * choice used in pngrtran.c which is to round the green one down.)
1222 : */
1223 : png_ptr->rgb_to_gray_red_coeff = 6968; /* 0.212639005871510 */
1224 : png_ptr->rgb_to_gray_green_coeff = 23434; /* 0.715168678767756 */
1225 : /* png_ptr->rgb_to_gray_blue_coeff = 2366; 0.072192315360734 */
1226 :
1227 : /* The following keeps the cHRM chunk from destroying the
1228 : * coefficients again in the event that it follows the sRGB chunk.
1229 : */
1230 : png_ptr->rgb_to_gray_coefficients_set = 1;
1231 : }
1232 : # endif
1233 :
1234 0 : png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1235 : }
1236 : #endif /* PNG_READ_sRGB_SUPPORTED */
1237 :
1238 : #ifdef PNG_READ_iCCP_SUPPORTED
1239 : void /* PRIVATE */
1240 0 : png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1241 : /* Note: this does not properly handle chunks that are > 64K under DOS */
1242 : {
1243 : png_byte compression_type;
1244 : png_bytep pC;
1245 : png_charp profile;
1246 0 : png_uint_32 skip = 0;
1247 : png_uint_32 profile_size;
1248 : png_alloc_size_t profile_length;
1249 : png_size_t slength, prefix_length, data_length;
1250 :
1251 : png_debug(1, "in png_handle_iCCP");
1252 :
1253 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1254 0 : png_error(png_ptr, "Missing IHDR before iCCP");
1255 :
1256 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1257 : {
1258 : png_warning(png_ptr, "Invalid iCCP after IDAT");
1259 0 : png_crc_finish(png_ptr, length);
1260 0 : return;
1261 : }
1262 :
1263 0 : else if (png_ptr->mode & PNG_HAVE_PLTE)
1264 : /* Should be an error, but we can cope with it */
1265 : png_warning(png_ptr, "Out of place iCCP chunk");
1266 :
1267 0 : if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1268 : {
1269 : png_warning(png_ptr, "Duplicate iCCP chunk");
1270 0 : png_crc_finish(png_ptr, length);
1271 0 : return;
1272 : }
1273 :
1274 : #ifdef PNG_MAX_MALLOC_64K
1275 : if (length > (png_uint_32)65535L)
1276 : {
1277 : png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1278 : skip = length - (png_uint_32)65535L;
1279 : length = (png_uint_32)65535L;
1280 : }
1281 : #endif
1282 :
1283 0 : png_free(png_ptr, png_ptr->chunkdata);
1284 0 : png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1285 0 : slength = length;
1286 0 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1287 :
1288 0 : if (png_crc_finish(png_ptr, skip))
1289 : {
1290 0 : png_free(png_ptr, png_ptr->chunkdata);
1291 0 : png_ptr->chunkdata = NULL;
1292 0 : return;
1293 : }
1294 :
1295 0 : png_ptr->chunkdata[slength] = 0x00;
1296 :
1297 0 : for (profile = png_ptr->chunkdata; *profile; profile++)
1298 : /* Empty loop to find end of name */ ;
1299 :
1300 0 : ++profile;
1301 :
1302 : /* There should be at least one zero (the compression type byte)
1303 : * following the separator, and we should be on it
1304 : */
1305 0 : if (profile >= png_ptr->chunkdata + slength - 1)
1306 : {
1307 0 : png_free(png_ptr, png_ptr->chunkdata);
1308 0 : png_ptr->chunkdata = NULL;
1309 : png_warning(png_ptr, "Malformed iCCP chunk");
1310 0 : return;
1311 : }
1312 :
1313 : /* Compression_type should always be zero */
1314 0 : compression_type = *profile++;
1315 :
1316 0 : if (compression_type)
1317 : {
1318 : png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1319 0 : compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
1320 : wrote nonzero) */
1321 : }
1322 :
1323 0 : prefix_length = profile - png_ptr->chunkdata;
1324 0 : png_decompress_chunk(png_ptr, compression_type,
1325 : slength, prefix_length, &data_length);
1326 :
1327 0 : profile_length = data_length - prefix_length;
1328 :
1329 0 : if (prefix_length > data_length || profile_length < 4)
1330 : {
1331 0 : png_free(png_ptr, png_ptr->chunkdata);
1332 0 : png_ptr->chunkdata = NULL;
1333 : png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1334 0 : return;
1335 : }
1336 :
1337 : /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1338 0 : pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1339 0 : profile_size = ((*(pC )) << 24) |
1340 0 : ((*(pC + 1)) << 16) |
1341 0 : ((*(pC + 2)) << 8) |
1342 0 : ((*(pC + 3)) );
1343 :
1344 : /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
1345 : * because profile_size is a 32 bit value.
1346 : */
1347 0 : if (profile_size < profile_length)
1348 0 : profile_length = profile_size;
1349 :
1350 : /* And the following guarantees that profile_size == profile_length. */
1351 0 : if (profile_size > profile_length)
1352 : {
1353 : PNG_WARNING_PARAMETERS(p)
1354 :
1355 0 : png_free(png_ptr, png_ptr->chunkdata);
1356 0 : png_ptr->chunkdata = NULL;
1357 :
1358 : png_warning_parameter_unsigned(p, 1, PNG_NUMBER_FORMAT_u, profile_size);
1359 : png_warning_parameter_unsigned(p, 2, PNG_NUMBER_FORMAT_u, profile_length);
1360 : png_formatted_warning(png_ptr, p,
1361 : "Ignoring iCCP chunk with declared size = @1 and actual length = @2");
1362 0 : return;
1363 : }
1364 :
1365 0 : png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1366 0 : compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
1367 : profile_size);
1368 0 : png_free(png_ptr, png_ptr->chunkdata);
1369 0 : png_ptr->chunkdata = NULL;
1370 : }
1371 : #endif /* PNG_READ_iCCP_SUPPORTED */
1372 :
1373 : #ifdef PNG_READ_sPLT_SUPPORTED
1374 : void /* PRIVATE */
1375 : png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1376 : /* Note: this does not properly handle chunks that are > 64K under DOS */
1377 : {
1378 : png_bytep entry_start;
1379 : png_sPLT_t new_palette;
1380 : png_sPLT_entryp pp;
1381 : png_uint_32 data_length;
1382 : int entry_size, i;
1383 : png_uint_32 skip = 0;
1384 : png_size_t slength;
1385 : png_uint_32 dl;
1386 : png_size_t max_dl;
1387 :
1388 : png_debug(1, "in png_handle_sPLT");
1389 :
1390 : #ifdef PNG_USER_LIMITS_SUPPORTED
1391 :
1392 : if (png_ptr->user_chunk_cache_max != 0)
1393 : {
1394 : if (png_ptr->user_chunk_cache_max == 1)
1395 : {
1396 : png_crc_finish(png_ptr, length);
1397 : return;
1398 : }
1399 :
1400 : if (--png_ptr->user_chunk_cache_max == 1)
1401 : {
1402 : png_warning(png_ptr, "No space in chunk cache for sPLT");
1403 : png_crc_finish(png_ptr, length);
1404 : return;
1405 : }
1406 : }
1407 : #endif
1408 :
1409 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1410 : png_error(png_ptr, "Missing IHDR before sPLT");
1411 :
1412 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1413 : {
1414 : png_warning(png_ptr, "Invalid sPLT after IDAT");
1415 : png_crc_finish(png_ptr, length);
1416 : return;
1417 : }
1418 :
1419 : #ifdef PNG_MAX_MALLOC_64K
1420 : if (length > (png_uint_32)65535L)
1421 : {
1422 : png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1423 : skip = length - (png_uint_32)65535L;
1424 : length = (png_uint_32)65535L;
1425 : }
1426 : #endif
1427 :
1428 : png_free(png_ptr, png_ptr->chunkdata);
1429 : png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1430 :
1431 : /* WARNING: this may break if size_t is less than 32 bits; it is assumed
1432 : * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
1433 : * potential breakage point if the types in pngconf.h aren't exactly right.
1434 : */
1435 : slength = length;
1436 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1437 :
1438 : if (png_crc_finish(png_ptr, skip))
1439 : {
1440 : png_free(png_ptr, png_ptr->chunkdata);
1441 : png_ptr->chunkdata = NULL;
1442 : return;
1443 : }
1444 :
1445 : png_ptr->chunkdata[slength] = 0x00;
1446 :
1447 : for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1448 : entry_start++)
1449 : /* Empty loop to find end of name */ ;
1450 :
1451 : ++entry_start;
1452 :
1453 : /* A sample depth should follow the separator, and we should be on it */
1454 : if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1455 : {
1456 : png_free(png_ptr, png_ptr->chunkdata);
1457 : png_ptr->chunkdata = NULL;
1458 : png_warning(png_ptr, "malformed sPLT chunk");
1459 : return;
1460 : }
1461 :
1462 : new_palette.depth = *entry_start++;
1463 : entry_size = (new_palette.depth == 8 ? 6 : 10);
1464 : /* This must fit in a png_uint_32 because it is derived from the original
1465 : * chunk data length (and use 'length', not 'slength' here for clarity -
1466 : * they are guaranteed to be the same, see the tests above.)
1467 : */
1468 : data_length = length - (png_uint_32)(entry_start -
1469 : (png_bytep)png_ptr->chunkdata);
1470 :
1471 : /* Integrity-check the data length */
1472 : if (data_length % entry_size)
1473 : {
1474 : png_free(png_ptr, png_ptr->chunkdata);
1475 : png_ptr->chunkdata = NULL;
1476 : png_warning(png_ptr, "sPLT chunk has bad length");
1477 : return;
1478 : }
1479 :
1480 : dl = (png_int_32)(data_length / entry_size);
1481 : max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry);
1482 :
1483 : if (dl > max_dl)
1484 : {
1485 : png_warning(png_ptr, "sPLT chunk too long");
1486 : return;
1487 : }
1488 :
1489 : new_palette.nentries = (png_int_32)(data_length / entry_size);
1490 :
1491 : new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1492 : png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1493 :
1494 : if (new_palette.entries == NULL)
1495 : {
1496 : png_warning(png_ptr, "sPLT chunk requires too much memory");
1497 : return;
1498 : }
1499 :
1500 : #ifdef PNG_POINTER_INDEXING_SUPPORTED
1501 : for (i = 0; i < new_palette.nentries; i++)
1502 : {
1503 : pp = new_palette.entries + i;
1504 :
1505 : if (new_palette.depth == 8)
1506 : {
1507 : pp->red = *entry_start++;
1508 : pp->green = *entry_start++;
1509 : pp->blue = *entry_start++;
1510 : pp->alpha = *entry_start++;
1511 : }
1512 :
1513 : else
1514 : {
1515 : pp->red = png_get_uint_16(entry_start); entry_start += 2;
1516 : pp->green = png_get_uint_16(entry_start); entry_start += 2;
1517 : pp->blue = png_get_uint_16(entry_start); entry_start += 2;
1518 : pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1519 : }
1520 :
1521 : pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1522 : }
1523 : #else
1524 : pp = new_palette.entries;
1525 :
1526 : for (i = 0; i < new_palette.nentries; i++)
1527 : {
1528 :
1529 : if (new_palette.depth == 8)
1530 : {
1531 : pp[i].red = *entry_start++;
1532 : pp[i].green = *entry_start++;
1533 : pp[i].blue = *entry_start++;
1534 : pp[i].alpha = *entry_start++;
1535 : }
1536 :
1537 : else
1538 : {
1539 : pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
1540 : pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1541 : pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
1542 : pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1543 : }
1544 :
1545 : pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
1546 : }
1547 : #endif
1548 :
1549 : /* Discard all chunk data except the name and stash that */
1550 : new_palette.name = png_ptr->chunkdata;
1551 :
1552 : png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1553 :
1554 : png_free(png_ptr, png_ptr->chunkdata);
1555 : png_ptr->chunkdata = NULL;
1556 : png_free(png_ptr, new_palette.entries);
1557 : }
1558 : #endif /* PNG_READ_sPLT_SUPPORTED */
1559 :
1560 : #ifdef PNG_READ_tRNS_SUPPORTED
1561 : void /* PRIVATE */
1562 0 : png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1563 : {
1564 : png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1565 :
1566 : png_debug(1, "in png_handle_tRNS");
1567 :
1568 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1569 0 : png_error(png_ptr, "Missing IHDR before tRNS");
1570 :
1571 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1572 : {
1573 : png_warning(png_ptr, "Invalid tRNS after IDAT");
1574 0 : png_crc_finish(png_ptr, length);
1575 0 : return;
1576 : }
1577 :
1578 0 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1579 : {
1580 : png_warning(png_ptr, "Duplicate tRNS chunk");
1581 0 : png_crc_finish(png_ptr, length);
1582 0 : return;
1583 : }
1584 :
1585 0 : if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1586 : {
1587 : png_byte buf[2];
1588 :
1589 0 : if (length != 2)
1590 : {
1591 : png_warning(png_ptr, "Incorrect tRNS chunk length");
1592 0 : png_crc_finish(png_ptr, length);
1593 0 : return;
1594 : }
1595 :
1596 0 : png_crc_read(png_ptr, buf, 2);
1597 0 : png_ptr->num_trans = 1;
1598 0 : png_ptr->trans_color.gray = png_get_uint_16(buf);
1599 : }
1600 :
1601 0 : else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1602 : {
1603 : png_byte buf[6];
1604 :
1605 0 : if (length != 6)
1606 : {
1607 : png_warning(png_ptr, "Incorrect tRNS chunk length");
1608 0 : png_crc_finish(png_ptr, length);
1609 0 : return;
1610 : }
1611 :
1612 0 : png_crc_read(png_ptr, buf, (png_size_t)length);
1613 0 : png_ptr->num_trans = 1;
1614 0 : png_ptr->trans_color.red = png_get_uint_16(buf);
1615 0 : png_ptr->trans_color.green = png_get_uint_16(buf + 2);
1616 0 : png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
1617 : }
1618 :
1619 0 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1620 : {
1621 0 : if (!(png_ptr->mode & PNG_HAVE_PLTE))
1622 : {
1623 : /* Should be an error, but we can cope with it. */
1624 : png_warning(png_ptr, "Missing PLTE before tRNS");
1625 : }
1626 :
1627 0 : if (length > (png_uint_32)png_ptr->num_palette ||
1628 : length > PNG_MAX_PALETTE_LENGTH)
1629 : {
1630 : png_warning(png_ptr, "Incorrect tRNS chunk length");
1631 0 : png_crc_finish(png_ptr, length);
1632 0 : return;
1633 : }
1634 :
1635 0 : if (length == 0)
1636 : {
1637 : png_warning(png_ptr, "Zero length tRNS chunk");
1638 0 : png_crc_finish(png_ptr, length);
1639 0 : return;
1640 : }
1641 :
1642 0 : png_crc_read(png_ptr, readbuf, (png_size_t)length);
1643 0 : png_ptr->num_trans = (png_uint_16)length;
1644 : }
1645 :
1646 : else
1647 : {
1648 : png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1649 0 : png_crc_finish(png_ptr, length);
1650 0 : return;
1651 : }
1652 :
1653 0 : if (png_crc_finish(png_ptr, 0))
1654 : {
1655 0 : png_ptr->num_trans = 0;
1656 0 : return;
1657 : }
1658 :
1659 0 : png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1660 0 : &(png_ptr->trans_color));
1661 : }
1662 : #endif
1663 :
1664 : #ifdef PNG_READ_bKGD_SUPPORTED
1665 : void /* PRIVATE */
1666 : png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1667 : {
1668 : png_size_t truelen;
1669 : png_byte buf[6];
1670 : png_color_16 background;
1671 :
1672 : png_debug(1, "in png_handle_bKGD");
1673 :
1674 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1675 : png_error(png_ptr, "Missing IHDR before bKGD");
1676 :
1677 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1678 : {
1679 : png_warning(png_ptr, "Invalid bKGD after IDAT");
1680 : png_crc_finish(png_ptr, length);
1681 : return;
1682 : }
1683 :
1684 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1685 : !(png_ptr->mode & PNG_HAVE_PLTE))
1686 : {
1687 : png_warning(png_ptr, "Missing PLTE before bKGD");
1688 : png_crc_finish(png_ptr, length);
1689 : return;
1690 : }
1691 :
1692 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1693 : {
1694 : png_warning(png_ptr, "Duplicate bKGD chunk");
1695 : png_crc_finish(png_ptr, length);
1696 : return;
1697 : }
1698 :
1699 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1700 : truelen = 1;
1701 :
1702 : else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1703 : truelen = 6;
1704 :
1705 : else
1706 : truelen = 2;
1707 :
1708 : if (length != truelen)
1709 : {
1710 : png_warning(png_ptr, "Incorrect bKGD chunk length");
1711 : png_crc_finish(png_ptr, length);
1712 : return;
1713 : }
1714 :
1715 : png_crc_read(png_ptr, buf, truelen);
1716 :
1717 : if (png_crc_finish(png_ptr, 0))
1718 : return;
1719 :
1720 : /* We convert the index value into RGB components so that we can allow
1721 : * arbitrary RGB values for background when we have transparency, and
1722 : * so it is easy to determine the RGB values of the background color
1723 : * from the info_ptr struct.
1724 : */
1725 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1726 : {
1727 : background.index = buf[0];
1728 :
1729 : if (info_ptr && info_ptr->num_palette)
1730 : {
1731 : if (buf[0] >= info_ptr->num_palette)
1732 : {
1733 : png_warning(png_ptr, "Incorrect bKGD chunk index value");
1734 : return;
1735 : }
1736 :
1737 : background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
1738 : background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
1739 : background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
1740 : }
1741 :
1742 : else
1743 : background.red = background.green = background.blue = 0;
1744 :
1745 : background.gray = 0;
1746 : }
1747 :
1748 : else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1749 : {
1750 : background.index = 0;
1751 : background.red =
1752 : background.green =
1753 : background.blue =
1754 : background.gray = png_get_uint_16(buf);
1755 : }
1756 :
1757 : else
1758 : {
1759 : background.index = 0;
1760 : background.red = png_get_uint_16(buf);
1761 : background.green = png_get_uint_16(buf + 2);
1762 : background.blue = png_get_uint_16(buf + 4);
1763 : background.gray = 0;
1764 : }
1765 :
1766 : png_set_bKGD(png_ptr, info_ptr, &background);
1767 : }
1768 : #endif
1769 :
1770 : #ifdef PNG_READ_hIST_SUPPORTED
1771 : void /* PRIVATE */
1772 : png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1773 : {
1774 : unsigned int num, i;
1775 : png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1776 :
1777 : png_debug(1, "in png_handle_hIST");
1778 :
1779 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1780 : png_error(png_ptr, "Missing IHDR before hIST");
1781 :
1782 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1783 : {
1784 : png_warning(png_ptr, "Invalid hIST after IDAT");
1785 : png_crc_finish(png_ptr, length);
1786 : return;
1787 : }
1788 :
1789 : else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1790 : {
1791 : png_warning(png_ptr, "Missing PLTE before hIST");
1792 : png_crc_finish(png_ptr, length);
1793 : return;
1794 : }
1795 :
1796 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1797 : {
1798 : png_warning(png_ptr, "Duplicate hIST chunk");
1799 : png_crc_finish(png_ptr, length);
1800 : return;
1801 : }
1802 :
1803 : num = length / 2 ;
1804 :
1805 : if (num != (unsigned int)png_ptr->num_palette || num >
1806 : (unsigned int)PNG_MAX_PALETTE_LENGTH)
1807 : {
1808 : png_warning(png_ptr, "Incorrect hIST chunk length");
1809 : png_crc_finish(png_ptr, length);
1810 : return;
1811 : }
1812 :
1813 : for (i = 0; i < num; i++)
1814 : {
1815 : png_byte buf[2];
1816 :
1817 : png_crc_read(png_ptr, buf, 2);
1818 : readbuf[i] = png_get_uint_16(buf);
1819 : }
1820 :
1821 : if (png_crc_finish(png_ptr, 0))
1822 : return;
1823 :
1824 : png_set_hIST(png_ptr, info_ptr, readbuf);
1825 : }
1826 : #endif
1827 :
1828 : #ifdef PNG_READ_pHYs_SUPPORTED
1829 : void /* PRIVATE */
1830 : png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1831 : {
1832 : png_byte buf[9];
1833 : png_uint_32 res_x, res_y;
1834 : int unit_type;
1835 :
1836 : png_debug(1, "in png_handle_pHYs");
1837 :
1838 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1839 : png_error(png_ptr, "Missing IHDR before pHYs");
1840 :
1841 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1842 : {
1843 : png_warning(png_ptr, "Invalid pHYs after IDAT");
1844 : png_crc_finish(png_ptr, length);
1845 : return;
1846 : }
1847 :
1848 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1849 : {
1850 : png_warning(png_ptr, "Duplicate pHYs chunk");
1851 : png_crc_finish(png_ptr, length);
1852 : return;
1853 : }
1854 :
1855 : if (length != 9)
1856 : {
1857 : png_warning(png_ptr, "Incorrect pHYs chunk length");
1858 : png_crc_finish(png_ptr, length);
1859 : return;
1860 : }
1861 :
1862 : png_crc_read(png_ptr, buf, 9);
1863 :
1864 : if (png_crc_finish(png_ptr, 0))
1865 : return;
1866 :
1867 : res_x = png_get_uint_32(buf);
1868 : res_y = png_get_uint_32(buf + 4);
1869 : unit_type = buf[8];
1870 : png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1871 : }
1872 : #endif
1873 :
1874 : #ifdef PNG_READ_oFFs_SUPPORTED
1875 : void /* PRIVATE */
1876 : png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1877 : {
1878 : png_byte buf[9];
1879 : png_int_32 offset_x, offset_y;
1880 : int unit_type;
1881 :
1882 : png_debug(1, "in png_handle_oFFs");
1883 :
1884 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1885 : png_error(png_ptr, "Missing IHDR before oFFs");
1886 :
1887 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1888 : {
1889 : png_warning(png_ptr, "Invalid oFFs after IDAT");
1890 : png_crc_finish(png_ptr, length);
1891 : return;
1892 : }
1893 :
1894 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1895 : {
1896 : png_warning(png_ptr, "Duplicate oFFs chunk");
1897 : png_crc_finish(png_ptr, length);
1898 : return;
1899 : }
1900 :
1901 : if (length != 9)
1902 : {
1903 : png_warning(png_ptr, "Incorrect oFFs chunk length");
1904 : png_crc_finish(png_ptr, length);
1905 : return;
1906 : }
1907 :
1908 : png_crc_read(png_ptr, buf, 9);
1909 :
1910 : if (png_crc_finish(png_ptr, 0))
1911 : return;
1912 :
1913 : offset_x = png_get_int_32(buf);
1914 : offset_y = png_get_int_32(buf + 4);
1915 : unit_type = buf[8];
1916 : png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1917 : }
1918 : #endif
1919 :
1920 : #ifdef PNG_READ_pCAL_SUPPORTED
1921 : /* Read the pCAL chunk (described in the PNG Extensions document) */
1922 : void /* PRIVATE */
1923 : png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1924 : {
1925 : png_int_32 X0, X1;
1926 : png_byte type, nparams;
1927 : png_charp buf, units, endptr;
1928 : png_charpp params;
1929 : png_size_t slength;
1930 : int i;
1931 :
1932 : png_debug(1, "in png_handle_pCAL");
1933 :
1934 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
1935 : png_error(png_ptr, "Missing IHDR before pCAL");
1936 :
1937 : else if (png_ptr->mode & PNG_HAVE_IDAT)
1938 : {
1939 : png_warning(png_ptr, "Invalid pCAL after IDAT");
1940 : png_crc_finish(png_ptr, length);
1941 : return;
1942 : }
1943 :
1944 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1945 : {
1946 : png_warning(png_ptr, "Duplicate pCAL chunk");
1947 : png_crc_finish(png_ptr, length);
1948 : return;
1949 : }
1950 :
1951 : png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
1952 : length + 1);
1953 : png_free(png_ptr, png_ptr->chunkdata);
1954 : png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1955 :
1956 : if (png_ptr->chunkdata == NULL)
1957 : {
1958 : png_warning(png_ptr, "No memory for pCAL purpose");
1959 : return;
1960 : }
1961 :
1962 : slength = length;
1963 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1964 :
1965 : if (png_crc_finish(png_ptr, 0))
1966 : {
1967 : png_free(png_ptr, png_ptr->chunkdata);
1968 : png_ptr->chunkdata = NULL;
1969 : return;
1970 : }
1971 :
1972 : png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1973 :
1974 : png_debug(3, "Finding end of pCAL purpose string");
1975 : for (buf = png_ptr->chunkdata; *buf; buf++)
1976 : /* Empty loop */ ;
1977 :
1978 : endptr = png_ptr->chunkdata + slength;
1979 :
1980 : /* We need to have at least 12 bytes after the purpose string
1981 : * in order to get the parameter information.
1982 : */
1983 : if (endptr <= buf + 12)
1984 : {
1985 : png_warning(png_ptr, "Invalid pCAL data");
1986 : png_free(png_ptr, png_ptr->chunkdata);
1987 : png_ptr->chunkdata = NULL;
1988 : return;
1989 : }
1990 :
1991 : png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1992 : X0 = png_get_int_32((png_bytep)buf+1);
1993 : X1 = png_get_int_32((png_bytep)buf+5);
1994 : type = buf[9];
1995 : nparams = buf[10];
1996 : units = buf + 11;
1997 :
1998 : png_debug(3, "Checking pCAL equation type and number of parameters");
1999 : /* Check that we have the right number of parameters for known
2000 : * equation types.
2001 : */
2002 : if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
2003 : (type == PNG_EQUATION_BASE_E && nparams != 3) ||
2004 : (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
2005 : (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
2006 : {
2007 : png_warning(png_ptr, "Invalid pCAL parameters for equation type");
2008 : png_free(png_ptr, png_ptr->chunkdata);
2009 : png_ptr->chunkdata = NULL;
2010 : return;
2011 : }
2012 :
2013 : else if (type >= PNG_EQUATION_LAST)
2014 : {
2015 : png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
2016 : }
2017 :
2018 : for (buf = units; *buf; buf++)
2019 : /* Empty loop to move past the units string. */ ;
2020 :
2021 : png_debug(3, "Allocating pCAL parameters array");
2022 :
2023 : params = (png_charpp)png_malloc_warn(png_ptr,
2024 : (png_size_t)(nparams * png_sizeof(png_charp)));
2025 :
2026 : if (params == NULL)
2027 : {
2028 : png_free(png_ptr, png_ptr->chunkdata);
2029 : png_ptr->chunkdata = NULL;
2030 : png_warning(png_ptr, "No memory for pCAL params");
2031 : return;
2032 : }
2033 :
2034 : /* Get pointers to the start of each parameter string. */
2035 : for (i = 0; i < (int)nparams; i++)
2036 : {
2037 : buf++; /* Skip the null string terminator from previous parameter. */
2038 :
2039 : png_debug1(3, "Reading pCAL parameter %d", i);
2040 :
2041 : for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
2042 : /* Empty loop to move past each parameter string */ ;
2043 :
2044 : /* Make sure we haven't run out of data yet */
2045 : if (buf > endptr)
2046 : {
2047 : png_warning(png_ptr, "Invalid pCAL data");
2048 : png_free(png_ptr, png_ptr->chunkdata);
2049 : png_ptr->chunkdata = NULL;
2050 : png_free(png_ptr, params);
2051 : return;
2052 : }
2053 : }
2054 :
2055 : png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
2056 : units, params);
2057 :
2058 : png_free(png_ptr, png_ptr->chunkdata);
2059 : png_ptr->chunkdata = NULL;
2060 : png_free(png_ptr, params);
2061 : }
2062 : #endif
2063 :
2064 : #ifdef PNG_READ_sCAL_SUPPORTED
2065 : /* Read the sCAL chunk */
2066 : void /* PRIVATE */
2067 : png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2068 : {
2069 : png_size_t slength, i;
2070 : int state;
2071 :
2072 : png_debug(1, "in png_handle_sCAL");
2073 :
2074 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2075 : png_error(png_ptr, "Missing IHDR before sCAL");
2076 :
2077 : else if (png_ptr->mode & PNG_HAVE_IDAT)
2078 : {
2079 : png_warning(png_ptr, "Invalid sCAL after IDAT");
2080 : png_crc_finish(png_ptr, length);
2081 : return;
2082 : }
2083 :
2084 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
2085 : {
2086 : png_warning(png_ptr, "Duplicate sCAL chunk");
2087 : png_crc_finish(png_ptr, length);
2088 : return;
2089 : }
2090 :
2091 : /* Need unit type, width, \0, height: minimum 4 bytes */
2092 : else if (length < 4)
2093 : {
2094 : png_warning(png_ptr, "sCAL chunk too short");
2095 : png_crc_finish(png_ptr, length);
2096 : return;
2097 : }
2098 :
2099 : png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
2100 : length + 1);
2101 :
2102 : png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2103 :
2104 : if (png_ptr->chunkdata == NULL)
2105 : {
2106 : png_warning(png_ptr, "Out of memory while processing sCAL chunk");
2107 : png_crc_finish(png_ptr, length);
2108 : return;
2109 : }
2110 :
2111 : slength = length;
2112 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2113 : png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
2114 :
2115 : if (png_crc_finish(png_ptr, 0))
2116 : {
2117 : png_free(png_ptr, png_ptr->chunkdata);
2118 : png_ptr->chunkdata = NULL;
2119 : return;
2120 : }
2121 :
2122 : /* Validate the unit. */
2123 : if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2)
2124 : {
2125 : png_warning(png_ptr, "Invalid sCAL ignored: invalid unit");
2126 : png_free(png_ptr, png_ptr->chunkdata);
2127 : png_ptr->chunkdata = NULL;
2128 : return;
2129 : }
2130 :
2131 : /* Validate the ASCII numbers, need two ASCII numbers separated by
2132 : * a '\0' and they need to fit exactly in the chunk data.
2133 : */
2134 : i = 1;
2135 : state = 0;
2136 :
2137 : if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2138 : i >= slength || png_ptr->chunkdata[i++] != 0)
2139 : png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format");
2140 :
2141 : else if (!PNG_FP_IS_POSITIVE(state))
2142 : png_warning(png_ptr, "Invalid sCAL chunk ignored: non-positive width");
2143 :
2144 : else
2145 : {
2146 : png_size_t heighti = i;
2147 :
2148 : state = 0;
2149 : if (!png_check_fp_number(png_ptr->chunkdata, slength, &state, &i) ||
2150 : i != slength)
2151 : png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format");
2152 :
2153 : else if (!PNG_FP_IS_POSITIVE(state))
2154 : png_warning(png_ptr,
2155 : "Invalid sCAL chunk ignored: non-positive height");
2156 :
2157 : else
2158 : /* This is the (only) success case. */
2159 : png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0],
2160 : png_ptr->chunkdata+1, png_ptr->chunkdata+heighti);
2161 : }
2162 :
2163 : /* Clean up - just free the temporarily allocated buffer. */
2164 : png_free(png_ptr, png_ptr->chunkdata);
2165 : png_ptr->chunkdata = NULL;
2166 : }
2167 : #endif
2168 :
2169 : #ifdef PNG_READ_tIME_SUPPORTED
2170 : void /* PRIVATE */
2171 : png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2172 : {
2173 : png_byte buf[7];
2174 : png_time mod_time;
2175 :
2176 : png_debug(1, "in png_handle_tIME");
2177 :
2178 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2179 : png_error(png_ptr, "Out of place tIME chunk");
2180 :
2181 : else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
2182 : {
2183 : png_warning(png_ptr, "Duplicate tIME chunk");
2184 : png_crc_finish(png_ptr, length);
2185 : return;
2186 : }
2187 :
2188 : if (png_ptr->mode & PNG_HAVE_IDAT)
2189 : png_ptr->mode |= PNG_AFTER_IDAT;
2190 :
2191 : if (length != 7)
2192 : {
2193 : png_warning(png_ptr, "Incorrect tIME chunk length");
2194 : png_crc_finish(png_ptr, length);
2195 : return;
2196 : }
2197 :
2198 : png_crc_read(png_ptr, buf, 7);
2199 :
2200 : if (png_crc_finish(png_ptr, 0))
2201 : return;
2202 :
2203 : mod_time.second = buf[6];
2204 : mod_time.minute = buf[5];
2205 : mod_time.hour = buf[4];
2206 : mod_time.day = buf[3];
2207 : mod_time.month = buf[2];
2208 : mod_time.year = png_get_uint_16(buf);
2209 :
2210 : png_set_tIME(png_ptr, info_ptr, &mod_time);
2211 : }
2212 : #endif
2213 :
2214 : #ifdef PNG_READ_tEXt_SUPPORTED
2215 : /* Note: this does not properly handle chunks that are > 64K under DOS */
2216 : void /* PRIVATE */
2217 : png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2218 : {
2219 : png_textp text_ptr;
2220 : png_charp key;
2221 : png_charp text;
2222 : png_uint_32 skip = 0;
2223 : png_size_t slength;
2224 : int ret;
2225 :
2226 : png_debug(1, "in png_handle_tEXt");
2227 :
2228 : #ifdef PNG_USER_LIMITS_SUPPORTED
2229 : if (png_ptr->user_chunk_cache_max != 0)
2230 : {
2231 : if (png_ptr->user_chunk_cache_max == 1)
2232 : {
2233 : png_crc_finish(png_ptr, length);
2234 : return;
2235 : }
2236 :
2237 : if (--png_ptr->user_chunk_cache_max == 1)
2238 : {
2239 : png_warning(png_ptr, "No space in chunk cache for tEXt");
2240 : png_crc_finish(png_ptr, length);
2241 : return;
2242 : }
2243 : }
2244 : #endif
2245 :
2246 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2247 : png_error(png_ptr, "Missing IHDR before tEXt");
2248 :
2249 : if (png_ptr->mode & PNG_HAVE_IDAT)
2250 : png_ptr->mode |= PNG_AFTER_IDAT;
2251 :
2252 : #ifdef PNG_MAX_MALLOC_64K
2253 : if (length > (png_uint_32)65535L)
2254 : {
2255 : png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2256 : skip = length - (png_uint_32)65535L;
2257 : length = (png_uint_32)65535L;
2258 : }
2259 : #endif
2260 :
2261 : png_free(png_ptr, png_ptr->chunkdata);
2262 :
2263 : png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2264 :
2265 : if (png_ptr->chunkdata == NULL)
2266 : {
2267 : png_warning(png_ptr, "No memory to process text chunk");
2268 : return;
2269 : }
2270 :
2271 : slength = length;
2272 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2273 :
2274 : if (png_crc_finish(png_ptr, skip))
2275 : {
2276 : png_free(png_ptr, png_ptr->chunkdata);
2277 : png_ptr->chunkdata = NULL;
2278 : return;
2279 : }
2280 :
2281 : key = png_ptr->chunkdata;
2282 :
2283 : key[slength] = 0x00;
2284 :
2285 : for (text = key; *text; text++)
2286 : /* Empty loop to find end of key */ ;
2287 :
2288 : if (text != key + slength)
2289 : text++;
2290 :
2291 : text_ptr = (png_textp)png_malloc_warn(png_ptr,
2292 : png_sizeof(png_text));
2293 :
2294 : if (text_ptr == NULL)
2295 : {
2296 : png_warning(png_ptr, "Not enough memory to process text chunk");
2297 : png_free(png_ptr, png_ptr->chunkdata);
2298 : png_ptr->chunkdata = NULL;
2299 : return;
2300 : }
2301 :
2302 : text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2303 : text_ptr->key = key;
2304 : text_ptr->lang = NULL;
2305 : text_ptr->lang_key = NULL;
2306 : text_ptr->itxt_length = 0;
2307 : text_ptr->text = text;
2308 : text_ptr->text_length = png_strlen(text);
2309 :
2310 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2311 :
2312 : png_free(png_ptr, png_ptr->chunkdata);
2313 : png_ptr->chunkdata = NULL;
2314 : png_free(png_ptr, text_ptr);
2315 :
2316 : if (ret)
2317 : png_warning(png_ptr, "Insufficient memory to process text chunk");
2318 : }
2319 : #endif
2320 :
2321 : #ifdef PNG_READ_zTXt_SUPPORTED
2322 : /* Note: this does not correctly handle chunks that are > 64K under DOS */
2323 : void /* PRIVATE */
2324 : png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2325 : {
2326 : png_textp text_ptr;
2327 : png_charp text;
2328 : int comp_type;
2329 : int ret;
2330 : png_size_t slength, prefix_len, data_len;
2331 :
2332 : png_debug(1, "in png_handle_zTXt");
2333 :
2334 : #ifdef PNG_USER_LIMITS_SUPPORTED
2335 : if (png_ptr->user_chunk_cache_max != 0)
2336 : {
2337 : if (png_ptr->user_chunk_cache_max == 1)
2338 : {
2339 : png_crc_finish(png_ptr, length);
2340 : return;
2341 : }
2342 :
2343 : if (--png_ptr->user_chunk_cache_max == 1)
2344 : {
2345 : png_warning(png_ptr, "No space in chunk cache for zTXt");
2346 : png_crc_finish(png_ptr, length);
2347 : return;
2348 : }
2349 : }
2350 : #endif
2351 :
2352 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2353 : png_error(png_ptr, "Missing IHDR before zTXt");
2354 :
2355 : if (png_ptr->mode & PNG_HAVE_IDAT)
2356 : png_ptr->mode |= PNG_AFTER_IDAT;
2357 :
2358 : #ifdef PNG_MAX_MALLOC_64K
2359 : /* We will no doubt have problems with chunks even half this size, but
2360 : * there is no hard and fast rule to tell us where to stop.
2361 : */
2362 : if (length > (png_uint_32)65535L)
2363 : {
2364 : png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2365 : png_crc_finish(png_ptr, length);
2366 : return;
2367 : }
2368 : #endif
2369 :
2370 : png_free(png_ptr, png_ptr->chunkdata);
2371 : png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2372 :
2373 : if (png_ptr->chunkdata == NULL)
2374 : {
2375 : png_warning(png_ptr, "Out of memory processing zTXt chunk");
2376 : return;
2377 : }
2378 :
2379 : slength = length;
2380 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2381 :
2382 : if (png_crc_finish(png_ptr, 0))
2383 : {
2384 : png_free(png_ptr, png_ptr->chunkdata);
2385 : png_ptr->chunkdata = NULL;
2386 : return;
2387 : }
2388 :
2389 : png_ptr->chunkdata[slength] = 0x00;
2390 :
2391 : for (text = png_ptr->chunkdata; *text; text++)
2392 : /* Empty loop */ ;
2393 :
2394 : /* zTXt must have some text after the chunkdataword */
2395 : if (text >= png_ptr->chunkdata + slength - 2)
2396 : {
2397 : png_warning(png_ptr, "Truncated zTXt chunk");
2398 : png_free(png_ptr, png_ptr->chunkdata);
2399 : png_ptr->chunkdata = NULL;
2400 : return;
2401 : }
2402 :
2403 : else
2404 : {
2405 : comp_type = *(++text);
2406 :
2407 : if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2408 : {
2409 : png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2410 : comp_type = PNG_TEXT_COMPRESSION_zTXt;
2411 : }
2412 :
2413 : text++; /* Skip the compression_method byte */
2414 : }
2415 :
2416 : prefix_len = text - png_ptr->chunkdata;
2417 :
2418 : png_decompress_chunk(png_ptr, comp_type,
2419 : (png_size_t)length, prefix_len, &data_len);
2420 :
2421 : text_ptr = (png_textp)png_malloc_warn(png_ptr,
2422 : png_sizeof(png_text));
2423 :
2424 : if (text_ptr == NULL)
2425 : {
2426 : png_warning(png_ptr, "Not enough memory to process zTXt chunk");
2427 : png_free(png_ptr, png_ptr->chunkdata);
2428 : png_ptr->chunkdata = NULL;
2429 : return;
2430 : }
2431 :
2432 : text_ptr->compression = comp_type;
2433 : text_ptr->key = png_ptr->chunkdata;
2434 : text_ptr->lang = NULL;
2435 : text_ptr->lang_key = NULL;
2436 : text_ptr->itxt_length = 0;
2437 : text_ptr->text = png_ptr->chunkdata + prefix_len;
2438 : text_ptr->text_length = data_len;
2439 :
2440 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2441 :
2442 : png_free(png_ptr, text_ptr);
2443 : png_free(png_ptr, png_ptr->chunkdata);
2444 : png_ptr->chunkdata = NULL;
2445 :
2446 : if (ret)
2447 : png_error(png_ptr, "Insufficient memory to store zTXt chunk");
2448 : }
2449 : #endif
2450 :
2451 : #ifdef PNG_READ_iTXt_SUPPORTED
2452 : /* Note: this does not correctly handle chunks that are > 64K under DOS */
2453 : void /* PRIVATE */
2454 : png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2455 : {
2456 : png_textp text_ptr;
2457 : png_charp key, lang, text, lang_key;
2458 : int comp_flag;
2459 : int comp_type = 0;
2460 : int ret;
2461 : png_size_t slength, prefix_len, data_len;
2462 :
2463 : png_debug(1, "in png_handle_iTXt");
2464 :
2465 : #ifdef PNG_USER_LIMITS_SUPPORTED
2466 : if (png_ptr->user_chunk_cache_max != 0)
2467 : {
2468 : if (png_ptr->user_chunk_cache_max == 1)
2469 : {
2470 : png_crc_finish(png_ptr, length);
2471 : return;
2472 : }
2473 :
2474 : if (--png_ptr->user_chunk_cache_max == 1)
2475 : {
2476 : png_warning(png_ptr, "No space in chunk cache for iTXt");
2477 : png_crc_finish(png_ptr, length);
2478 : return;
2479 : }
2480 : }
2481 : #endif
2482 :
2483 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2484 : png_error(png_ptr, "Missing IHDR before iTXt");
2485 :
2486 : if (png_ptr->mode & PNG_HAVE_IDAT)
2487 : png_ptr->mode |= PNG_AFTER_IDAT;
2488 :
2489 : #ifdef PNG_MAX_MALLOC_64K
2490 : /* We will no doubt have problems with chunks even half this size, but
2491 : * there is no hard and fast rule to tell us where to stop.
2492 : */
2493 : if (length > (png_uint_32)65535L)
2494 : {
2495 : png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2496 : png_crc_finish(png_ptr, length);
2497 : return;
2498 : }
2499 : #endif
2500 :
2501 : png_free(png_ptr, png_ptr->chunkdata);
2502 : png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2503 :
2504 : if (png_ptr->chunkdata == NULL)
2505 : {
2506 : png_warning(png_ptr, "No memory to process iTXt chunk");
2507 : return;
2508 : }
2509 :
2510 : slength = length;
2511 : png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2512 :
2513 : if (png_crc_finish(png_ptr, 0))
2514 : {
2515 : png_free(png_ptr, png_ptr->chunkdata);
2516 : png_ptr->chunkdata = NULL;
2517 : return;
2518 : }
2519 :
2520 : png_ptr->chunkdata[slength] = 0x00;
2521 :
2522 : for (lang = png_ptr->chunkdata; *lang; lang++)
2523 : /* Empty loop */ ;
2524 :
2525 : lang++; /* Skip NUL separator */
2526 :
2527 : /* iTXt must have a language tag (possibly empty), two compression bytes,
2528 : * translated keyword (possibly empty), and possibly some text after the
2529 : * keyword
2530 : */
2531 :
2532 : if (lang >= png_ptr->chunkdata + slength - 3)
2533 : {
2534 : png_warning(png_ptr, "Truncated iTXt chunk");
2535 : png_free(png_ptr, png_ptr->chunkdata);
2536 : png_ptr->chunkdata = NULL;
2537 : return;
2538 : }
2539 :
2540 : else
2541 : {
2542 : comp_flag = *lang++;
2543 : comp_type = *lang++;
2544 : }
2545 :
2546 : if (comp_type || (comp_flag && comp_flag != PNG_TEXT_COMPRESSION_zTXt))
2547 : {
2548 : png_warning(png_ptr, "Unknown iTXt compression type or method");
2549 : png_free(png_ptr, png_ptr->chunkdata);
2550 : png_ptr->chunkdata = NULL;
2551 : return;
2552 : }
2553 :
2554 : for (lang_key = lang; *lang_key; lang_key++)
2555 : /* Empty loop */ ;
2556 :
2557 : lang_key++; /* Skip NUL separator */
2558 :
2559 : if (lang_key >= png_ptr->chunkdata + slength)
2560 : {
2561 : png_warning(png_ptr, "Truncated iTXt chunk");
2562 : png_free(png_ptr, png_ptr->chunkdata);
2563 : png_ptr->chunkdata = NULL;
2564 : return;
2565 : }
2566 :
2567 : for (text = lang_key; *text; text++)
2568 : /* Empty loop */ ;
2569 :
2570 : text++; /* Skip NUL separator */
2571 :
2572 : if (text >= png_ptr->chunkdata + slength)
2573 : {
2574 : png_warning(png_ptr, "Malformed iTXt chunk");
2575 : png_free(png_ptr, png_ptr->chunkdata);
2576 : png_ptr->chunkdata = NULL;
2577 : return;
2578 : }
2579 :
2580 : prefix_len = text - png_ptr->chunkdata;
2581 :
2582 : key=png_ptr->chunkdata;
2583 :
2584 : if (comp_flag)
2585 : png_decompress_chunk(png_ptr, comp_type,
2586 : (size_t)length, prefix_len, &data_len);
2587 :
2588 : else
2589 : data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2590 :
2591 : text_ptr = (png_textp)png_malloc_warn(png_ptr,
2592 : png_sizeof(png_text));
2593 :
2594 : if (text_ptr == NULL)
2595 : {
2596 : png_warning(png_ptr, "Not enough memory to process iTXt chunk");
2597 : png_free(png_ptr, png_ptr->chunkdata);
2598 : png_ptr->chunkdata = NULL;
2599 : return;
2600 : }
2601 :
2602 : text_ptr->compression = (int)comp_flag + 1;
2603 : text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2604 : text_ptr->lang = png_ptr->chunkdata + (lang - key);
2605 : text_ptr->itxt_length = data_len;
2606 : text_ptr->text_length = 0;
2607 : text_ptr->key = png_ptr->chunkdata;
2608 : text_ptr->text = png_ptr->chunkdata + prefix_len;
2609 :
2610 : ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2611 :
2612 : png_free(png_ptr, text_ptr);
2613 : png_free(png_ptr, png_ptr->chunkdata);
2614 : png_ptr->chunkdata = NULL;
2615 :
2616 : if (ret)
2617 : png_error(png_ptr, "Insufficient memory to store iTXt chunk");
2618 : }
2619 : #endif
2620 :
2621 : #ifdef PNG_READ_APNG_SUPPORTED
2622 : void /* PRIVATE */
2623 0 : png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2624 : {
2625 : png_byte data[8];
2626 : png_uint_32 num_frames;
2627 : png_uint_32 num_plays;
2628 : png_uint_32 didSet;
2629 :
2630 : png_debug(1, "in png_handle_acTL");
2631 :
2632 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2633 : {
2634 0 : png_error(png_ptr, "Missing IHDR before acTL");
2635 : }
2636 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
2637 : {
2638 : png_warning(png_ptr, "Invalid acTL after IDAT skipped");
2639 0 : png_crc_finish(png_ptr, length);
2640 0 : return;
2641 : }
2642 0 : else if (png_ptr->mode & PNG_HAVE_acTL)
2643 : {
2644 : png_warning(png_ptr, "Duplicate acTL skipped");
2645 0 : png_crc_finish(png_ptr, length);
2646 0 : return;
2647 : }
2648 0 : else if (length != 8)
2649 : {
2650 : png_warning(png_ptr, "acTL with invalid length skipped");
2651 0 : png_crc_finish(png_ptr, length);
2652 0 : return;
2653 : }
2654 :
2655 0 : png_crc_read(png_ptr, data, 8);
2656 0 : png_crc_finish(png_ptr, 0);
2657 :
2658 0 : num_frames = png_get_uint_31(png_ptr, data);
2659 0 : num_plays = png_get_uint_31(png_ptr, data + 4);
2660 :
2661 : /* the set function will do error checking on num_frames */
2662 0 : didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays);
2663 0 : if(didSet)
2664 0 : png_ptr->mode |= PNG_HAVE_acTL;
2665 : }
2666 :
2667 : void /* PRIVATE */
2668 0 : png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2669 : {
2670 : png_byte data[22];
2671 : png_uint_32 width;
2672 : png_uint_32 height;
2673 : png_uint_32 x_offset;
2674 : png_uint_32 y_offset;
2675 : png_uint_16 delay_num;
2676 : png_uint_16 delay_den;
2677 : png_byte dispose_op;
2678 : png_byte blend_op;
2679 :
2680 : png_debug(1, "in png_handle_fcTL");
2681 :
2682 0 : png_ensure_sequence_number(png_ptr, length);
2683 :
2684 0 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
2685 : {
2686 0 : png_error(png_ptr, "Missing IHDR before fcTL");
2687 : }
2688 0 : else if (png_ptr->mode & PNG_HAVE_IDAT)
2689 : {
2690 : /* for any frames other then the first this message may be misleading,
2691 : * but correct. PNG_HAVE_IDAT is unset before the frame head is read
2692 : * i can't think of a better message */
2693 : png_warning(png_ptr, "Invalid fcTL after IDAT skipped");
2694 0 : png_crc_finish(png_ptr, length-4);
2695 0 : return;
2696 : }
2697 0 : else if (png_ptr->mode & PNG_HAVE_fcTL)
2698 : {
2699 : png_warning(png_ptr, "Duplicate fcTL within one frame skipped");
2700 0 : png_crc_finish(png_ptr, length-4);
2701 0 : return;
2702 : }
2703 0 : else if (length != 26)
2704 : {
2705 : png_warning(png_ptr, "fcTL with invalid length skipped");
2706 0 : png_crc_finish(png_ptr, length-4);
2707 0 : return;
2708 : }
2709 :
2710 0 : png_crc_read(png_ptr, data, 22);
2711 0 : png_crc_finish(png_ptr, 0);
2712 :
2713 0 : width = png_get_uint_31(png_ptr, data);
2714 0 : height = png_get_uint_31(png_ptr, data + 4);
2715 0 : x_offset = png_get_uint_31(png_ptr, data + 8);
2716 0 : y_offset = png_get_uint_31(png_ptr, data + 12);
2717 0 : delay_num = png_get_uint_16(data + 16);
2718 0 : delay_den = png_get_uint_16(data + 18);
2719 0 : dispose_op = data[20];
2720 0 : blend_op = data[21];
2721 :
2722 0 : if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0))
2723 : {
2724 : png_warning(png_ptr, "fcTL for the first frame must have zero offset");
2725 0 : return;
2726 : }
2727 :
2728 0 : if (info_ptr != NULL)
2729 : {
2730 0 : if (png_ptr->num_frames_read == 0 &&
2731 0 : (width != info_ptr->width || height != info_ptr->height))
2732 : {
2733 : png_warning(png_ptr, "size in first frame's fcTL must match "
2734 : "the size in IHDR");
2735 0 : return;
2736 : }
2737 :
2738 : /* The set function will do more error checking */
2739 0 : png_set_next_frame_fcTL(png_ptr, info_ptr, width, height,
2740 : x_offset, y_offset, delay_num, delay_den,
2741 : dispose_op, blend_op);
2742 :
2743 0 : png_read_reinit(png_ptr, info_ptr);
2744 :
2745 0 : png_ptr->mode |= PNG_HAVE_fcTL;
2746 : }
2747 : }
2748 :
2749 : void /* PRIVATE */
2750 4 : png_have_info(png_structp png_ptr, png_infop info_ptr)
2751 : {
2752 4 : if((info_ptr->valid & PNG_INFO_acTL) && !(info_ptr->valid & PNG_INFO_fcTL))
2753 : {
2754 0 : png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN;
2755 0 : info_ptr->num_frames++;
2756 : }
2757 4 : }
2758 :
2759 : void /* PRIVATE */
2760 0 : png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2761 : {
2762 0 : png_ensure_sequence_number(png_ptr, length);
2763 :
2764 : /* This function is only called from png_read_end(), png_read_info(),
2765 : * and png_push_read_chunk() which means that:
2766 : * - the user doesn't want to read this frame
2767 : * - or this is an out-of-place fdAT
2768 : * in either case it is safe to ignore the chunk with a warning */
2769 : png_warning(png_ptr, "ignoring fdAT chunk");
2770 0 : png_crc_finish(png_ptr, length - 4);
2771 : PNG_UNUSED(info_ptr)
2772 0 : }
2773 :
2774 : void /* PRIVATE */
2775 0 : png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length)
2776 : {
2777 : png_byte data[4];
2778 : png_uint_32 sequence_number;
2779 :
2780 0 : if (length < 4)
2781 0 : png_error(png_ptr, "invalid fcTL or fdAT chunk found");
2782 :
2783 0 : png_crc_read(png_ptr, data, 4);
2784 0 : sequence_number = png_get_uint_31(png_ptr, data);
2785 :
2786 0 : if (sequence_number != png_ptr->next_seq_num)
2787 0 : png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence "
2788 : "number found");
2789 :
2790 0 : png_ptr->next_seq_num++;
2791 0 : }
2792 : #endif /* PNG_READ_APNG_SUPPORTED */
2793 :
2794 : /* This function is called when we haven't found a handler for a
2795 : * chunk. If there isn't a problem with the chunk itself (ie bad
2796 : * chunk name, CRC, or a critical chunk), the chunk is silently ignored
2797 : * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2798 : * case it will be saved away to be written out later.
2799 : */
2800 : void /* PRIVATE */
2801 0 : png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2802 : {
2803 0 : png_uint_32 skip = 0;
2804 :
2805 : png_debug(1, "in png_handle_unknown");
2806 :
2807 : #ifdef PNG_USER_LIMITS_SUPPORTED
2808 : if (png_ptr->user_chunk_cache_max != 0)
2809 : {
2810 : if (png_ptr->user_chunk_cache_max == 1)
2811 : {
2812 : png_crc_finish(png_ptr, length);
2813 : return;
2814 : }
2815 :
2816 : if (--png_ptr->user_chunk_cache_max == 1)
2817 : {
2818 : png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2819 : png_crc_finish(png_ptr, length);
2820 : return;
2821 : }
2822 : }
2823 : #endif
2824 :
2825 0 : if (png_ptr->mode & PNG_HAVE_IDAT)
2826 : {
2827 0 : if (png_ptr->chunk_name != png_IDAT)
2828 0 : png_ptr->mode |= PNG_AFTER_IDAT;
2829 : }
2830 :
2831 0 : if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2832 : {
2833 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2834 : if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2835 : PNG_HANDLE_CHUNK_ALWAYS
2836 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2837 : && png_ptr->read_user_chunk_fn == NULL
2838 : #endif
2839 : )
2840 : #endif
2841 0 : png_chunk_error(png_ptr, "unknown critical chunk");
2842 : }
2843 :
2844 : #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2845 : if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2846 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2847 : || (png_ptr->read_user_chunk_fn != NULL)
2848 : #endif
2849 : )
2850 : {
2851 : #ifdef PNG_MAX_MALLOC_64K
2852 : if (length > 65535)
2853 : {
2854 : png_warning(png_ptr, "unknown chunk too large to fit in memory");
2855 : skip = length - 65535;
2856 : length = 65535;
2857 : }
2858 : #endif
2859 :
2860 : /* TODO: this code is very close to the unknown handling in pngpread.c,
2861 : * maybe it can be put into a common utility routine?
2862 : * png_struct::unknown_chunk is just used as a temporary variable, along
2863 : * with the data into which the chunk is read. These can be eliminated.
2864 : */
2865 : PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
2866 : png_ptr->unknown_chunk.size = (png_size_t)length;
2867 :
2868 : if (length == 0)
2869 : png_ptr->unknown_chunk.data = NULL;
2870 :
2871 : else
2872 : {
2873 : png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2874 : png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
2875 : }
2876 :
2877 : #ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2878 : if (png_ptr->read_user_chunk_fn != NULL)
2879 : {
2880 : /* Callback to user unknown chunk handler */
2881 : int ret;
2882 :
2883 : ret = (*(png_ptr->read_user_chunk_fn))
2884 : (png_ptr, &png_ptr->unknown_chunk);
2885 :
2886 : if (ret < 0)
2887 : png_chunk_error(png_ptr, "error in user chunk");
2888 :
2889 : if (ret == 0)
2890 : {
2891 : if (PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
2892 : {
2893 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2894 : if (png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name) !=
2895 : PNG_HANDLE_CHUNK_ALWAYS)
2896 : #endif
2897 : png_chunk_error(png_ptr, "unknown critical chunk");
2898 : }
2899 :
2900 : png_set_unknown_chunks(png_ptr, info_ptr,
2901 : &png_ptr->unknown_chunk, 1);
2902 : }
2903 : }
2904 :
2905 : else
2906 : #endif
2907 : png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2908 :
2909 : png_free(png_ptr, png_ptr->unknown_chunk.data);
2910 : png_ptr->unknown_chunk.data = NULL;
2911 : }
2912 :
2913 : else
2914 : #endif
2915 0 : skip = length;
2916 :
2917 0 : png_crc_finish(png_ptr, skip);
2918 :
2919 : #ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2920 : PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */
2921 : #endif
2922 0 : }
2923 :
2924 : /* This function is called to verify that a chunk name is valid.
2925 : * This function can't have the "critical chunk check" incorporated
2926 : * into it, since in the future we will need to be able to call user
2927 : * functions to handle unknown critical chunks after we check that
2928 : * the chunk name itself is valid.
2929 : */
2930 :
2931 : /* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
2932 : *
2933 : * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2934 : */
2935 :
2936 : void /* PRIVATE */
2937 10 : png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name)
2938 : {
2939 : int i;
2940 :
2941 : png_debug(1, "in png_check_chunk_name");
2942 :
2943 50 : for (i=1; i<=4; ++i)
2944 : {
2945 40 : int c = chunk_name & 0xff;
2946 :
2947 40 : if (c < 65 || c > 122 || (c > 90 && c < 97))
2948 0 : png_chunk_error(png_ptr, "invalid chunk type");
2949 :
2950 40 : chunk_name >>= 8;
2951 : }
2952 10 : }
2953 :
2954 : /* Combines the row recently read in with the existing pixels in the row. This
2955 : * routine takes care of alpha and transparency if requested. This routine also
2956 : * handles the two methods of progressive display of interlaced images,
2957 : * depending on the 'display' value; if 'display' is true then the whole row
2958 : * (dp) is filled from the start by replicating the available pixels. If
2959 : * 'display' is false only those pixels present in the pass are filled in.
2960 : */
2961 : void /* PRIVATE */
2962 0 : png_combine_row(png_structp png_ptr, png_bytep dp, int display)
2963 : {
2964 0 : unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
2965 0 : png_const_bytep sp = png_ptr->row_buf + 1;
2966 0 : png_uint_32 row_width = png_ptr->width;
2967 0 : unsigned int pass = png_ptr->pass;
2968 0 : png_bytep end_ptr = 0;
2969 0 : png_byte end_byte = 0;
2970 : unsigned int end_mask;
2971 :
2972 : png_debug(1, "in png_combine_row");
2973 :
2974 : /* Added in 1.5.6: it should not be possible to enter this routine until at
2975 : * least one row has been read from the PNG data and transformed.
2976 : */
2977 0 : if (pixel_depth == 0)
2978 0 : png_error(png_ptr, "internal row logic error");
2979 :
2980 : /* Added in 1.5.4: the pixel depth should match the information returned by
2981 : * any call to png_read_update_info at this point. Do not continue if we got
2982 : * this wrong.
2983 : */
2984 0 : if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
2985 0 : PNG_ROWBYTES(pixel_depth, row_width))
2986 0 : png_error(png_ptr, "internal row size calculation error");
2987 :
2988 : /* Don't expect this to ever happen: */
2989 0 : if (row_width == 0)
2990 0 : png_error(png_ptr, "internal row width error");
2991 :
2992 : /* Preserve the last byte in cases where only part of it will be overwritten,
2993 : * the multiply below may overflow, we don't care because ANSI-C guarantees
2994 : * we get the low bits.
2995 : */
2996 0 : end_mask = (pixel_depth * row_width) & 7;
2997 0 : if (end_mask != 0)
2998 : {
2999 : /* end_ptr == NULL is a flag to say do nothing */
3000 0 : end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
3001 0 : end_byte = *end_ptr;
3002 : # ifdef PNG_READ_PACKSWAP_SUPPORTED
3003 : if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
3004 : end_mask = 0xff << end_mask;
3005 :
3006 : else /* big-endian byte */
3007 : # endif
3008 0 : end_mask = 0xff >> end_mask;
3009 : /* end_mask is now the bits to *keep* from the destination row */
3010 : }
3011 :
3012 : /* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
3013 : * will also happen if interlacing isn't supported or if the application
3014 : * does not call png_set_interlace_handling(). In the latter cases the
3015 : * caller just gets a sequence of the unexpanded rows from each interlace
3016 : * pass.
3017 : */
3018 : #ifdef PNG_READ_INTERLACING_SUPPORTED
3019 0 : if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
3020 0 : pass < 6 && (display == 0 ||
3021 : /* The following copies everything for 'display' on passes 0, 2 and 4. */
3022 0 : (display == 1 && (pass & 1) != 0)))
3023 : {
3024 : /* Narrow images may have no bits in a pass; the caller should handle
3025 : * this, but this test is cheap:
3026 : */
3027 0 : if (row_width <= PNG_PASS_START_COL(pass))
3028 0 : return;
3029 :
3030 0 : if (pixel_depth < 8)
3031 : {
3032 : /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
3033 : * into 32 bits, then a single loop over the bytes using the four byte
3034 : * values in the 32-bit mask can be used. For the 'display' option the
3035 : * expanded mask may also not require any masking within a byte. To
3036 : * make this work the PACKSWAP option must be taken into account - it
3037 : * simply requires the pixels to be reversed in each byte.
3038 : *
3039 : * The 'regular' case requires a mask for each of the first 6 passes,
3040 : * the 'display' case does a copy for the even passes in the range
3041 : * 0..6. This has already been handled in the test above.
3042 : *
3043 : * The masks are arranged as four bytes with the first byte to use in
3044 : * the lowest bits (little-endian) regardless of the order (PACKSWAP or
3045 : * not) of the pixels in each byte.
3046 : *
3047 : * NOTE: the whole of this logic depends on the caller of this function
3048 : * only calling it on rows appropriate to the pass. This function only
3049 : * understands the 'x' logic; the 'y' logic is handled by the caller.
3050 : *
3051 : * The following defines allow generation of compile time constant bit
3052 : * masks for each pixel depth and each possibility of swapped or not
3053 : * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index,
3054 : * is in the range 0..7; and the result is 1 if the pixel is to be
3055 : * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B'
3056 : * for the block method.
3057 : *
3058 : * With some compilers a compile time expression of the general form:
3059 : *
3060 : * (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
3061 : *
3062 : * Produces warnings with values of 'shift' in the range 33 to 63
3063 : * because the right hand side of the ?: expression is evaluated by
3064 : * the compiler even though it isn't used. Microsoft Visual C (various
3065 : * versions) and the Intel C compiler are known to do this. To avoid
3066 : * this the following macros are used in 1.5.6. This is a temporary
3067 : * solution to avoid destabilizing the code during the release process.
3068 : */
3069 : # if PNG_USE_COMPILE_TIME_MASKS
3070 : # define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
3071 : # define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
3072 : # else
3073 : # define PNG_LSR(x,s) ((x)>>(s))
3074 : # define PNG_LSL(x,s) ((x)<<(s))
3075 : # endif
3076 : # define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
3077 : PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
3078 : # define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
3079 : PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
3080 :
3081 : /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is
3082 : * little endian - the first pixel is at bit 0 - however the extra
3083 : * parameter 's' can be set to cause the mask position to be swapped
3084 : * within each byte, to match the PNG format. This is done by XOR of
3085 : * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
3086 : */
3087 : # define PIXEL_MASK(p,x,d,s) \
3088 : (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
3089 :
3090 : /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
3091 : */
3092 : # define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
3093 : # define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
3094 :
3095 : /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp
3096 : * cases the result needs replicating, for the 4-bpp case the above
3097 : * generates a full 32 bits.
3098 : */
3099 : # define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
3100 :
3101 : # define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
3102 : S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
3103 : S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
3104 :
3105 : # define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
3106 : B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
3107 : B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
3108 :
3109 : #if PNG_USE_COMPILE_TIME_MASKS
3110 : /* Utility macros to construct all the masks for a depth/swap
3111 : * combination. The 's' parameter says whether the format is PNG
3112 : * (big endian bytes) or not. Only the three odd-numbered passes are
3113 : * required for the display/block algorithm.
3114 : */
3115 : # define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
3116 : S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
3117 :
3118 : # define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
3119 :
3120 : # define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
3121 :
3122 : /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
3123 : * then pass:
3124 : */
3125 : static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
3126 : {
3127 : /* Little-endian byte masks for PACKSWAP */
3128 : { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
3129 : /* Normal (big-endian byte) masks - PNG format */
3130 : { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
3131 : };
3132 :
3133 : /* display_mask has only three entries for the odd passes, so index by
3134 : * pass>>1.
3135 : */
3136 : static PNG_CONST png_uint_32 display_mask[2][3][3] =
3137 : {
3138 : /* Little-endian byte masks for PACKSWAP */
3139 : { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
3140 : /* Normal (big-endian byte) masks - PNG format */
3141 : { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
3142 : };
3143 :
3144 : # define MASK(pass,depth,display,png)\
3145 : ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
3146 : row_mask[png][DEPTH_INDEX(depth)][pass])
3147 :
3148 : #else /* !PNG_USE_COMPILE_TIME_MASKS */
3149 : /* This is the runtime alternative: it seems unlikely that this will
3150 : * ever be either smaller or faster than the compile time approach.
3151 : */
3152 : # define MASK(pass,depth,display,png)\
3153 : ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
3154 : #endif /* !PNG_USE_COMPILE_TIME_MASKS */
3155 :
3156 : /* Use the appropriate mask to copy the required bits. In some cases
3157 : * the byte mask will be 0 or 0xff, optimize these cases. row_width is
3158 : * the number of pixels, but the code copies bytes, so it is necessary
3159 : * to special case the end.
3160 : */
3161 0 : png_uint_32 pixels_per_byte = 8 / pixel_depth;
3162 : png_uint_32 mask;
3163 :
3164 : # ifdef PNG_READ_PACKSWAP_SUPPORTED
3165 : if (png_ptr->transformations & PNG_PACKSWAP)
3166 : mask = MASK(pass, pixel_depth, display, 0);
3167 :
3168 : else
3169 : # endif
3170 0 : mask = MASK(pass, pixel_depth, display, 1);
3171 :
3172 : for (;;)
3173 : {
3174 : png_uint_32 m;
3175 :
3176 : /* It doesn't matter in the following if png_uint_32 has more than
3177 : * 32 bits because the high bits always match those in m<<24; it is,
3178 : * however, essential to use OR here, not +, because of this.
3179 : */
3180 0 : m = mask;
3181 0 : mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
3182 0 : m &= 0xff;
3183 :
3184 0 : if (m != 0) /* something to copy */
3185 : {
3186 0 : if (m != 0xff)
3187 0 : *dp = (png_byte)((*dp & ~m) | (*sp & m));
3188 : else
3189 0 : *dp = *sp;
3190 : }
3191 :
3192 : /* NOTE: this may overwrite the last byte with garbage if the image
3193 : * is not an exact number of bytes wide; libpng has always done
3194 : * this.
3195 : */
3196 0 : if (row_width <= pixels_per_byte)
3197 : break; /* May need to restore part of the last byte */
3198 :
3199 0 : row_width -= pixels_per_byte;
3200 0 : ++dp;
3201 0 : ++sp;
3202 0 : }
3203 : }
3204 :
3205 : else /* pixel_depth >= 8 */
3206 : {
3207 : unsigned int bytes_to_copy, bytes_to_jump;
3208 :
3209 : /* Validate the depth - it must be a multiple of 8 */
3210 0 : if (pixel_depth & 7)
3211 0 : png_error(png_ptr, "invalid user transform pixel depth");
3212 :
3213 0 : pixel_depth >>= 3; /* now in bytes */
3214 0 : row_width *= pixel_depth;
3215 :
3216 : /* Regardless of pass number the Adam 7 interlace always results in a
3217 : * fixed number of pixels to copy then to skip. There may be a
3218 : * different number of pixels to skip at the start though.
3219 : */
3220 : {
3221 0 : unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
3222 :
3223 0 : row_width -= offset;
3224 0 : dp += offset;
3225 0 : sp += offset;
3226 : }
3227 :
3228 : /* Work out the bytes to copy. */
3229 0 : if (display)
3230 : {
3231 : /* When doing the 'block' algorithm the pixel in the pass gets
3232 : * replicated to adjacent pixels. This is why the even (0,2,4,6)
3233 : * passes are skipped above - the entire expanded row is copied.
3234 : */
3235 0 : bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
3236 :
3237 : /* But don't allow this number to exceed the actual row width. */
3238 0 : if (bytes_to_copy > row_width)
3239 0 : bytes_to_copy = row_width;
3240 : }
3241 :
3242 : else /* normal row; Adam7 only ever gives us one pixel to copy. */
3243 0 : bytes_to_copy = pixel_depth;
3244 :
3245 : /* In Adam7 there is a constant offset between where the pixels go. */
3246 0 : bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
3247 :
3248 : /* And simply copy these bytes. Some optimization is possible here,
3249 : * depending on the value of 'bytes_to_copy'. Special case the low
3250 : * byte counts, which we know to be frequent.
3251 : *
3252 : * Notice that these cases all 'return' rather than 'break' - this
3253 : * avoids an unnecessary test on whether to restore the last byte
3254 : * below.
3255 : */
3256 0 : switch (bytes_to_copy)
3257 : {
3258 : case 1:
3259 : for (;;)
3260 : {
3261 0 : *dp = *sp;
3262 :
3263 0 : if (row_width <= bytes_to_jump)
3264 0 : return;
3265 :
3266 0 : dp += bytes_to_jump;
3267 0 : sp += bytes_to_jump;
3268 0 : row_width -= bytes_to_jump;
3269 0 : }
3270 :
3271 : case 2:
3272 : /* There is a possibility of a partial copy at the end here; this
3273 : * slows the code down somewhat.
3274 : */
3275 : do
3276 : {
3277 0 : dp[0] = sp[0], dp[1] = sp[1];
3278 :
3279 0 : if (row_width <= bytes_to_jump)
3280 0 : return;
3281 :
3282 0 : sp += bytes_to_jump;
3283 0 : dp += bytes_to_jump;
3284 0 : row_width -= bytes_to_jump;
3285 : }
3286 0 : while (row_width > 1);
3287 :
3288 : /* And there can only be one byte left at this point: */
3289 0 : *dp = *sp;
3290 0 : return;
3291 :
3292 : case 3:
3293 : /* This can only be the RGB case, so each copy is exactly one
3294 : * pixel and it is not necessary to check for a partial copy.
3295 : */
3296 : for(;;)
3297 : {
3298 0 : dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
3299 :
3300 0 : if (row_width <= bytes_to_jump)
3301 0 : return;
3302 :
3303 0 : sp += bytes_to_jump;
3304 0 : dp += bytes_to_jump;
3305 0 : row_width -= bytes_to_jump;
3306 0 : }
3307 :
3308 : default:
3309 : #if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
3310 : /* Check for double byte alignment and, if possible, use a
3311 : * 16-bit copy. Don't attempt this for narrow images - ones that
3312 : * are less than an interlace panel wide. Don't attempt it for
3313 : * wide bytes_to_copy either - use the png_memcpy there.
3314 : */
3315 0 : if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
3316 0 : png_isaligned(dp, png_uint_16) &&
3317 0 : png_isaligned(sp, png_uint_16) &&
3318 0 : bytes_to_copy % sizeof (png_uint_16) == 0 &&
3319 0 : bytes_to_jump % sizeof (png_uint_16) == 0)
3320 : {
3321 : /* Everything is aligned for png_uint_16 copies, but try for
3322 : * png_uint_32 first.
3323 : */
3324 0 : if (png_isaligned(dp, png_uint_32) &&
3325 0 : png_isaligned(sp, png_uint_32) &&
3326 0 : bytes_to_copy % sizeof (png_uint_32) == 0 &&
3327 0 : bytes_to_jump % sizeof (png_uint_32) == 0)
3328 : {
3329 0 : png_uint_32p dp32 = (png_uint_32p)dp;
3330 0 : png_const_uint_32p sp32 = (png_const_uint_32p)sp;
3331 0 : unsigned int skip = (bytes_to_jump-bytes_to_copy) /
3332 : sizeof (png_uint_32);
3333 :
3334 : do
3335 : {
3336 0 : size_t c = bytes_to_copy;
3337 : do
3338 : {
3339 0 : *dp32++ = *sp32++;
3340 0 : c -= sizeof (png_uint_32);
3341 : }
3342 0 : while (c > 0);
3343 :
3344 0 : if (row_width <= bytes_to_jump)
3345 0 : return;
3346 :
3347 0 : dp32 += skip;
3348 0 : sp32 += skip;
3349 0 : row_width -= bytes_to_jump;
3350 : }
3351 0 : while (bytes_to_copy <= row_width);
3352 :
3353 : /* Get to here when the row_width truncates the final copy.
3354 : * There will be 1-3 bytes left to copy, so don't try the
3355 : * 16-bit loop below.
3356 : */
3357 0 : dp = (png_bytep)dp32;
3358 0 : sp = (png_const_bytep)sp32;
3359 : do
3360 0 : *dp++ = *sp++;
3361 0 : while (--row_width > 0);
3362 0 : return;
3363 : }
3364 :
3365 : /* Else do it in 16-bit quantities, but only if the size is
3366 : * not too large.
3367 : */
3368 : else
3369 : {
3370 0 : png_uint_16p dp16 = (png_uint_16p)dp;
3371 0 : png_const_uint_16p sp16 = (png_const_uint_16p)sp;
3372 0 : unsigned int skip = (bytes_to_jump-bytes_to_copy) /
3373 : sizeof (png_uint_16);
3374 :
3375 : do
3376 : {
3377 0 : size_t c = bytes_to_copy;
3378 : do
3379 : {
3380 0 : *dp16++ = *sp16++;
3381 0 : c -= sizeof (png_uint_16);
3382 : }
3383 0 : while (c > 0);
3384 :
3385 0 : if (row_width <= bytes_to_jump)
3386 0 : return;
3387 :
3388 0 : dp16 += skip;
3389 0 : sp16 += skip;
3390 0 : row_width -= bytes_to_jump;
3391 : }
3392 0 : while (bytes_to_copy <= row_width);
3393 :
3394 : /* End of row - 1 byte left, bytes_to_copy > row_width: */
3395 0 : dp = (png_bytep)dp16;
3396 0 : sp = (png_const_bytep)sp16;
3397 : do
3398 0 : *dp++ = *sp++;
3399 0 : while (--row_width > 0);
3400 0 : return;
3401 : }
3402 : }
3403 : #endif /* PNG_ALIGN_ code */
3404 :
3405 : /* The true default - use a png_memcpy: */
3406 : for (;;)
3407 : {
3408 0 : png_memcpy(dp, sp, bytes_to_copy);
3409 :
3410 0 : if (row_width <= bytes_to_jump)
3411 0 : return;
3412 :
3413 0 : sp += bytes_to_jump;
3414 0 : dp += bytes_to_jump;
3415 0 : row_width -= bytes_to_jump;
3416 0 : if (bytes_to_copy > row_width)
3417 0 : bytes_to_copy = row_width;
3418 0 : }
3419 : }
3420 :
3421 : /* NOT REACHED*/
3422 : } /* pixel_depth >= 8 */
3423 :
3424 : /* Here if pixel_depth < 8 to check 'end_ptr' below. */
3425 : }
3426 : else
3427 : #endif
3428 :
3429 : /* If here then the switch above wasn't used so just png_memcpy the whole row
3430 : * from the temporary row buffer (notice that this overwrites the end of the
3431 : * destination row if it is a partial byte.)
3432 : */
3433 0 : png_memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
3434 :
3435 : /* Restore the overwritten bits from the last byte if necessary. */
3436 0 : if (end_ptr != NULL)
3437 0 : *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
3438 : }
3439 :
3440 : #ifdef PNG_READ_INTERLACING_SUPPORTED
3441 : void /* PRIVATE */
3442 0 : png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
3443 : png_uint_32 transformations /* Because these may affect the byte layout */)
3444 : {
3445 : /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3446 : /* Offset to next interlace block */
3447 : static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3448 :
3449 : png_debug(1, "in png_do_read_interlace");
3450 0 : if (row != NULL && row_info != NULL)
3451 : {
3452 : png_uint_32 final_width;
3453 :
3454 0 : final_width = row_info->width * png_pass_inc[pass];
3455 :
3456 0 : switch (row_info->pixel_depth)
3457 : {
3458 : case 1:
3459 : {
3460 0 : png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
3461 0 : png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
3462 : int sshift, dshift;
3463 : int s_start, s_end, s_inc;
3464 0 : int jstop = png_pass_inc[pass];
3465 : png_byte v;
3466 : png_uint_32 i;
3467 : int j;
3468 :
3469 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
3470 : if (transformations & PNG_PACKSWAP)
3471 : {
3472 : sshift = (int)((row_info->width + 7) & 0x07);
3473 : dshift = (int)((final_width + 7) & 0x07);
3474 : s_start = 7;
3475 : s_end = 0;
3476 : s_inc = -1;
3477 : }
3478 :
3479 : else
3480 : #endif
3481 : {
3482 0 : sshift = 7 - (int)((row_info->width + 7) & 0x07);
3483 0 : dshift = 7 - (int)((final_width + 7) & 0x07);
3484 0 : s_start = 0;
3485 0 : s_end = 7;
3486 0 : s_inc = 1;
3487 : }
3488 :
3489 0 : for (i = 0; i < row_info->width; i++)
3490 : {
3491 0 : v = (png_byte)((*sp >> sshift) & 0x01);
3492 0 : for (j = 0; j < jstop; j++)
3493 : {
3494 0 : *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
3495 0 : *dp |= (png_byte)(v << dshift);
3496 :
3497 0 : if (dshift == s_end)
3498 : {
3499 0 : dshift = s_start;
3500 0 : dp--;
3501 : }
3502 :
3503 : else
3504 0 : dshift += s_inc;
3505 : }
3506 :
3507 0 : if (sshift == s_end)
3508 : {
3509 0 : sshift = s_start;
3510 0 : sp--;
3511 : }
3512 :
3513 : else
3514 0 : sshift += s_inc;
3515 : }
3516 0 : break;
3517 : }
3518 :
3519 : case 2:
3520 : {
3521 0 : png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
3522 0 : png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
3523 : int sshift, dshift;
3524 : int s_start, s_end, s_inc;
3525 0 : int jstop = png_pass_inc[pass];
3526 : png_uint_32 i;
3527 :
3528 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
3529 : if (transformations & PNG_PACKSWAP)
3530 : {
3531 : sshift = (int)(((row_info->width + 3) & 0x03) << 1);
3532 : dshift = (int)(((final_width + 3) & 0x03) << 1);
3533 : s_start = 6;
3534 : s_end = 0;
3535 : s_inc = -2;
3536 : }
3537 :
3538 : else
3539 : #endif
3540 : {
3541 0 : sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
3542 0 : dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
3543 0 : s_start = 0;
3544 0 : s_end = 6;
3545 0 : s_inc = 2;
3546 : }
3547 :
3548 0 : for (i = 0; i < row_info->width; i++)
3549 : {
3550 : png_byte v;
3551 : int j;
3552 :
3553 0 : v = (png_byte)((*sp >> sshift) & 0x03);
3554 0 : for (j = 0; j < jstop; j++)
3555 : {
3556 0 : *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
3557 0 : *dp |= (png_byte)(v << dshift);
3558 :
3559 0 : if (dshift == s_end)
3560 : {
3561 0 : dshift = s_start;
3562 0 : dp--;
3563 : }
3564 :
3565 : else
3566 0 : dshift += s_inc;
3567 : }
3568 :
3569 0 : if (sshift == s_end)
3570 : {
3571 0 : sshift = s_start;
3572 0 : sp--;
3573 : }
3574 :
3575 : else
3576 0 : sshift += s_inc;
3577 : }
3578 0 : break;
3579 : }
3580 :
3581 : case 4:
3582 : {
3583 0 : png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
3584 0 : png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
3585 : int sshift, dshift;
3586 : int s_start, s_end, s_inc;
3587 : png_uint_32 i;
3588 0 : int jstop = png_pass_inc[pass];
3589 :
3590 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
3591 : if (transformations & PNG_PACKSWAP)
3592 : {
3593 : sshift = (int)(((row_info->width + 1) & 0x01) << 2);
3594 : dshift = (int)(((final_width + 1) & 0x01) << 2);
3595 : s_start = 4;
3596 : s_end = 0;
3597 : s_inc = -4;
3598 : }
3599 :
3600 : else
3601 : #endif
3602 : {
3603 0 : sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
3604 0 : dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
3605 0 : s_start = 0;
3606 0 : s_end = 4;
3607 0 : s_inc = 4;
3608 : }
3609 :
3610 0 : for (i = 0; i < row_info->width; i++)
3611 : {
3612 0 : png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
3613 : int j;
3614 :
3615 0 : for (j = 0; j < jstop; j++)
3616 : {
3617 0 : *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
3618 0 : *dp |= (png_byte)(v << dshift);
3619 :
3620 0 : if (dshift == s_end)
3621 : {
3622 0 : dshift = s_start;
3623 0 : dp--;
3624 : }
3625 :
3626 : else
3627 0 : dshift += s_inc;
3628 : }
3629 :
3630 0 : if (sshift == s_end)
3631 : {
3632 0 : sshift = s_start;
3633 0 : sp--;
3634 : }
3635 :
3636 : else
3637 0 : sshift += s_inc;
3638 : }
3639 0 : break;
3640 : }
3641 :
3642 : default:
3643 : {
3644 0 : png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
3645 :
3646 0 : png_bytep sp = row + (png_size_t)(row_info->width - 1)
3647 : * pixel_bytes;
3648 :
3649 0 : png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
3650 :
3651 0 : int jstop = png_pass_inc[pass];
3652 : png_uint_32 i;
3653 :
3654 0 : for (i = 0; i < row_info->width; i++)
3655 : {
3656 : png_byte v[8];
3657 : int j;
3658 :
3659 0 : png_memcpy(v, sp, pixel_bytes);
3660 :
3661 0 : for (j = 0; j < jstop; j++)
3662 : {
3663 0 : png_memcpy(dp, v, pixel_bytes);
3664 0 : dp -= pixel_bytes;
3665 : }
3666 :
3667 0 : sp -= pixel_bytes;
3668 : }
3669 0 : break;
3670 : }
3671 : }
3672 :
3673 0 : row_info->width = final_width;
3674 0 : row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
3675 : }
3676 : #ifndef PNG_READ_PACKSWAP_SUPPORTED
3677 : PNG_UNUSED(transformations) /* Silence compiler warning */
3678 : #endif
3679 0 : }
3680 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
3681 :
3682 : static void
3683 28 : png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
3684 : png_const_bytep prev_row)
3685 : {
3686 : png_size_t i;
3687 28 : png_size_t istop = row_info->rowbytes;
3688 28 : unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
3689 28 : png_bytep rp = row + bpp;
3690 :
3691 : PNG_UNUSED(prev_row)
3692 :
3693 7084 : for (i = bpp; i < istop; i++)
3694 : {
3695 7056 : *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
3696 7056 : rp++;
3697 : }
3698 28 : }
3699 :
3700 : static void
3701 17 : png_read_filter_row_up(png_row_infop row_info, png_bytep row,
3702 : png_const_bytep prev_row)
3703 : {
3704 : png_size_t i;
3705 17 : png_size_t istop = row_info->rowbytes;
3706 17 : png_bytep rp = row;
3707 17 : png_const_bytep pp = prev_row;
3708 :
3709 4369 : for (i = 0; i < istop; i++)
3710 : {
3711 4352 : *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3712 4352 : rp++;
3713 : }
3714 17 : }
3715 :
3716 : static void
3717 69 : png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
3718 : png_const_bytep prev_row)
3719 : {
3720 : png_size_t i;
3721 69 : png_bytep rp = row;
3722 69 : png_const_bytep pp = prev_row;
3723 69 : unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
3724 69 : png_size_t istop = row_info->rowbytes - bpp;
3725 :
3726 345 : for (i = 0; i < bpp; i++)
3727 : {
3728 552 : *rp = (png_byte)(((int)(*rp) +
3729 552 : ((int)(*pp++) / 2 )) & 0xff);
3730 :
3731 276 : rp++;
3732 : }
3733 :
3734 17457 : for (i = 0; i < istop; i++)
3735 : {
3736 34776 : *rp = (png_byte)(((int)(*rp) +
3737 34776 : (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
3738 :
3739 17388 : rp++;
3740 : }
3741 69 : }
3742 :
3743 : static void
3744 0 : png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
3745 : png_const_bytep prev_row)
3746 : {
3747 0 : png_bytep rp_end = row + row_info->rowbytes;
3748 : int a, c;
3749 :
3750 : /* First pixel/byte */
3751 0 : c = *prev_row++;
3752 0 : a = *row + c;
3753 0 : *row++ = (png_byte)a;
3754 :
3755 : /* Remainder */
3756 0 : while (row < rp_end)
3757 : {
3758 : int b, pa, pb, pc, p;
3759 :
3760 0 : a &= 0xff; /* From previous iteration or start */
3761 0 : b = *prev_row++;
3762 :
3763 0 : p = b - c;
3764 0 : pc = a - c;
3765 :
3766 : # ifdef PNG_USE_ABS
3767 : pa = abs(p);
3768 : pb = abs(pc);
3769 : pc = abs(p + pc);
3770 : # else
3771 0 : pa = p < 0 ? -p : p;
3772 0 : pb = pc < 0 ? -pc : pc;
3773 0 : pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3774 : # endif
3775 :
3776 : /* Find the best predictor, the least of pa, pb, pc favoring the earlier
3777 : * ones in the case of a tie.
3778 : */
3779 0 : if (pb < pa) pa = pb, a = b;
3780 0 : if (pc < pa) a = c;
3781 :
3782 : /* Calculate the current pixel in a, and move the previous row pixel to c
3783 : * for the next time round the loop
3784 : */
3785 0 : c = b;
3786 0 : a += *row;
3787 0 : *row++ = (png_byte)a;
3788 : }
3789 0 : }
3790 :
3791 : static void
3792 78 : png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
3793 : png_const_bytep prev_row)
3794 : {
3795 78 : int bpp = (row_info->pixel_depth + 7) >> 3;
3796 78 : png_bytep rp_end = row + bpp;
3797 :
3798 : /* Process the first pixel in the row completely (this is the same as 'up'
3799 : * because there is only one candidate predictor for the first row).
3800 : */
3801 468 : while (row < rp_end)
3802 : {
3803 312 : int a = *row + *prev_row++;
3804 312 : *row++ = (png_byte)a;
3805 : }
3806 :
3807 : /* Remainder */
3808 78 : rp_end += row_info->rowbytes - bpp;
3809 :
3810 19812 : while (row < rp_end)
3811 : {
3812 : int a, b, c, pa, pb, pc, p;
3813 :
3814 19656 : c = *(prev_row - bpp);
3815 19656 : a = *(row - bpp);
3816 19656 : b = *prev_row++;
3817 :
3818 19656 : p = b - c;
3819 19656 : pc = a - c;
3820 :
3821 : # ifdef PNG_USE_ABS
3822 : pa = abs(p);
3823 : pb = abs(pc);
3824 : pc = abs(p + pc);
3825 : # else
3826 19656 : pa = p < 0 ? -p : p;
3827 19656 : pb = pc < 0 ? -pc : pc;
3828 19656 : pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3829 : # endif
3830 :
3831 19656 : if (pb < pa) pa = pb, a = b;
3832 19656 : if (pc < pa) a = c;
3833 :
3834 19656 : c = b;
3835 19656 : a += *row;
3836 19656 : *row++ = (png_byte)a;
3837 : }
3838 78 : }
3839 :
3840 : #ifdef PNG_ARM_NEON
3841 :
3842 : #ifdef __linux__
3843 : #include <stdio.h>
3844 : #include <elf.h>
3845 : #include <asm/hwcap.h>
3846 :
3847 : static int png_have_hwcap(unsigned cap)
3848 : {
3849 : FILE *f = fopen("/proc/self/auxv", "r");
3850 : Elf32_auxv_t aux;
3851 : int have_cap = 0;
3852 :
3853 : if (!f)
3854 : return 0;
3855 :
3856 : while (fread(&aux, sizeof(aux), 1, f) > 0)
3857 : {
3858 : if (aux.a_type == AT_HWCAP &&
3859 : aux.a_un.a_val & cap)
3860 : {
3861 : have_cap = 1;
3862 : break;
3863 : }
3864 : }
3865 :
3866 : fclose(f);
3867 :
3868 : return have_cap;
3869 : }
3870 : #endif /* __linux__ */
3871 :
3872 : static void
3873 : png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
3874 : {
3875 : #ifdef __linux__
3876 : if (!png_have_hwcap(HWCAP_NEON))
3877 : return;
3878 : #endif
3879 :
3880 : pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
3881 :
3882 : if (bpp == 3)
3883 : {
3884 : pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
3885 : pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
3886 : pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3887 : png_read_filter_row_paeth3_neon;
3888 : }
3889 :
3890 : else if (bpp == 4)
3891 : {
3892 : pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
3893 : pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
3894 : pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3895 : png_read_filter_row_paeth4_neon;
3896 : }
3897 : }
3898 : #endif /* PNG_ARM_NEON */
3899 :
3900 : static void
3901 3 : png_init_filter_functions(png_structp pp)
3902 : {
3903 3 : unsigned int bpp = (pp->pixel_depth + 7) >> 3;
3904 :
3905 3 : pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
3906 3 : pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
3907 3 : pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
3908 3 : if (bpp == 1)
3909 0 : pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3910 : png_read_filter_row_paeth_1byte_pixel;
3911 : else
3912 3 : pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
3913 : png_read_filter_row_paeth_multibyte_pixel;
3914 :
3915 : #ifdef PNG_ARM_NEON
3916 : png_init_filter_functions_neon(pp, bpp);
3917 : #endif
3918 3 : }
3919 :
3920 : void /* PRIVATE */
3921 192 : png_read_filter_row(png_structp pp, png_row_infop row_info, png_bytep row,
3922 : png_const_bytep prev_row, int filter)
3923 : {
3924 192 : if (pp->read_filter[0] == NULL)
3925 3 : png_init_filter_functions(pp);
3926 192 : if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
3927 192 : pp->read_filter[filter-1](row_info, row, prev_row);
3928 192 : }
3929 :
3930 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3931 : void /* PRIVATE */
3932 : png_read_finish_row(png_structp png_ptr)
3933 : {
3934 : #ifdef PNG_READ_INTERLACING_SUPPORTED
3935 : /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3936 :
3937 : /* Start of interlace block */
3938 : static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3939 :
3940 : /* Offset to next interlace block */
3941 : static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3942 :
3943 : /* Start of interlace block in the y direction */
3944 : static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3945 :
3946 : /* Offset to next interlace block in the y direction */
3947 : static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3948 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
3949 :
3950 : png_debug(1, "in png_read_finish_row");
3951 : png_ptr->row_number++;
3952 : if (png_ptr->row_number < png_ptr->num_rows)
3953 : return;
3954 :
3955 : #ifdef PNG_READ_INTERLACING_SUPPORTED
3956 : if (png_ptr->interlaced)
3957 : {
3958 : png_ptr->row_number = 0;
3959 :
3960 : /* TO DO: don't do this if prev_row isn't needed (requires
3961 : * read-ahead of the next row's filter byte.
3962 : */
3963 : png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
3964 :
3965 : do
3966 : {
3967 : png_ptr->pass++;
3968 :
3969 : if (png_ptr->pass >= 7)
3970 : break;
3971 :
3972 : png_ptr->iwidth = (png_ptr->width +
3973 : png_pass_inc[png_ptr->pass] - 1 -
3974 : png_pass_start[png_ptr->pass]) /
3975 : png_pass_inc[png_ptr->pass];
3976 :
3977 : if (!(png_ptr->transformations & PNG_INTERLACE))
3978 : {
3979 : png_ptr->num_rows = (png_ptr->height +
3980 : png_pass_yinc[png_ptr->pass] - 1 -
3981 : png_pass_ystart[png_ptr->pass]) /
3982 : png_pass_yinc[png_ptr->pass];
3983 : }
3984 :
3985 : else /* if (png_ptr->transformations & PNG_INTERLACE) */
3986 : break; /* libpng deinterlacing sees every row */
3987 :
3988 : } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
3989 :
3990 : if (png_ptr->pass < 7)
3991 : return;
3992 : }
3993 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
3994 :
3995 : if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3996 : {
3997 : char extra;
3998 : int ret;
3999 :
4000 : png_ptr->zstream.next_out = (Byte *)&extra;
4001 : png_ptr->zstream.avail_out = (uInt)1;
4002 :
4003 : for (;;)
4004 : {
4005 : if (!(png_ptr->zstream.avail_in))
4006 : {
4007 : while (!png_ptr->idat_size)
4008 : {
4009 : png_crc_finish(png_ptr, 0);
4010 : png_ptr->idat_size = png_read_chunk_header(png_ptr);
4011 : if (png_ptr->chunk_name != png_IDAT)
4012 : png_error(png_ptr, "Not enough image data");
4013 : }
4014 :
4015 : png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
4016 : png_ptr->zstream.next_in = png_ptr->zbuf;
4017 :
4018 : if (png_ptr->zbuf_size > png_ptr->idat_size)
4019 : png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
4020 :
4021 : png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
4022 : png_ptr->idat_size -= png_ptr->zstream.avail_in;
4023 : }
4024 :
4025 : ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
4026 :
4027 : if (ret == Z_STREAM_END)
4028 : {
4029 : if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
4030 : png_ptr->idat_size)
4031 : png_warning(png_ptr, "Extra compressed data");
4032 :
4033 : png_ptr->mode |= PNG_AFTER_IDAT;
4034 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
4035 : break;
4036 : }
4037 :
4038 : if (ret != Z_OK)
4039 : png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
4040 : "Decompression Error");
4041 :
4042 : if (!(png_ptr->zstream.avail_out))
4043 : {
4044 : png_warning(png_ptr, "Extra compressed data");
4045 : png_ptr->mode |= PNG_AFTER_IDAT;
4046 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
4047 : break;
4048 : }
4049 :
4050 : }
4051 : png_ptr->zstream.avail_out = 0;
4052 : }
4053 :
4054 : if (png_ptr->idat_size || png_ptr->zstream.avail_in)
4055 : png_warning(png_ptr, "Extra compression data");
4056 :
4057 : inflateReset(&png_ptr->zstream);
4058 :
4059 : png_ptr->mode |= PNG_AFTER_IDAT;
4060 : }
4061 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
4062 :
4063 : void /* PRIVATE */
4064 4 : png_read_start_row(png_structp png_ptr)
4065 : {
4066 : #ifdef PNG_READ_INTERLACING_SUPPORTED
4067 : /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
4068 :
4069 : /* Start of interlace block */
4070 : static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
4071 :
4072 : /* Offset to next interlace block */
4073 : static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
4074 :
4075 : /* Start of interlace block in the y direction */
4076 : static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
4077 :
4078 : /* Offset to next interlace block in the y direction */
4079 : static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
4080 : #endif
4081 :
4082 : int max_pixel_depth;
4083 : png_size_t row_bytes;
4084 :
4085 : png_debug(1, "in png_read_start_row");
4086 4 : png_ptr->zstream.avail_in = 0;
4087 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
4088 4 : png_init_read_transformations(png_ptr);
4089 : #endif
4090 : #ifdef PNG_READ_INTERLACING_SUPPORTED
4091 4 : if (png_ptr->interlaced)
4092 : {
4093 0 : if (!(png_ptr->transformations & PNG_INTERLACE))
4094 0 : png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
4095 0 : png_pass_ystart[0]) / png_pass_yinc[0];
4096 :
4097 : else
4098 0 : png_ptr->num_rows = png_ptr->height;
4099 :
4100 0 : png_ptr->iwidth = (png_ptr->width +
4101 0 : png_pass_inc[png_ptr->pass] - 1 -
4102 0 : png_pass_start[png_ptr->pass]) /
4103 0 : png_pass_inc[png_ptr->pass];
4104 : }
4105 :
4106 : else
4107 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
4108 : {
4109 4 : png_ptr->num_rows = png_ptr->height;
4110 4 : png_ptr->iwidth = png_ptr->width;
4111 : }
4112 :
4113 4 : max_pixel_depth = png_ptr->pixel_depth;
4114 :
4115 : /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
4116 : * calculations to calculate the final pixel depth, then
4117 : * png_do_read_transforms actually does the transforms. This means that the
4118 : * code which effectively calculates this value is actually repeated in three
4119 : * separate places. They must all match. Innocent changes to the order of
4120 : * transformations can and will break libpng in a way that causes memory
4121 : * overwrites.
4122 : *
4123 : * TODO: fix this.
4124 : */
4125 : #ifdef PNG_READ_PACK_SUPPORTED
4126 : if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
4127 : max_pixel_depth = 8;
4128 : #endif
4129 :
4130 : #ifdef PNG_READ_EXPAND_SUPPORTED
4131 4 : if (png_ptr->transformations & PNG_EXPAND)
4132 : {
4133 4 : if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4134 : {
4135 0 : if (png_ptr->num_trans)
4136 0 : max_pixel_depth = 32;
4137 :
4138 : else
4139 0 : max_pixel_depth = 24;
4140 : }
4141 :
4142 4 : else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4143 : {
4144 0 : if (max_pixel_depth < 8)
4145 0 : max_pixel_depth = 8;
4146 :
4147 0 : if (png_ptr->num_trans)
4148 0 : max_pixel_depth *= 2;
4149 : }
4150 :
4151 4 : else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
4152 : {
4153 1 : if (png_ptr->num_trans)
4154 : {
4155 0 : max_pixel_depth *= 4;
4156 0 : max_pixel_depth /= 3;
4157 : }
4158 : }
4159 : }
4160 : #endif
4161 :
4162 : #ifdef PNG_READ_EXPAND_16_SUPPORTED
4163 : if (png_ptr->transformations & PNG_EXPAND_16)
4164 : {
4165 : # ifdef PNG_READ_EXPAND_SUPPORTED
4166 : /* In fact it is an error if it isn't supported, but checking is
4167 : * the safe way.
4168 : */
4169 : if (png_ptr->transformations & PNG_EXPAND)
4170 : {
4171 : if (png_ptr->bit_depth < 16)
4172 : max_pixel_depth *= 2;
4173 : }
4174 : else
4175 : # endif
4176 : png_ptr->transformations &= ~PNG_EXPAND_16;
4177 : }
4178 : #endif
4179 :
4180 : #ifdef PNG_READ_FILLER_SUPPORTED
4181 : if (png_ptr->transformations & (PNG_FILLER))
4182 : {
4183 : if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
4184 : {
4185 : if (max_pixel_depth <= 8)
4186 : max_pixel_depth = 16;
4187 :
4188 : else
4189 : max_pixel_depth = 32;
4190 : }
4191 :
4192 : else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
4193 : png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
4194 : {
4195 : if (max_pixel_depth <= 32)
4196 : max_pixel_depth = 32;
4197 :
4198 : else
4199 : max_pixel_depth = 64;
4200 : }
4201 : }
4202 : #endif
4203 :
4204 : #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
4205 4 : if (png_ptr->transformations & PNG_GRAY_TO_RGB)
4206 : {
4207 4 : if (
4208 : #ifdef PNG_READ_EXPAND_SUPPORTED
4209 8 : (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
4210 : #endif
4211 : #ifdef PNG_READ_FILLER_SUPPORTED
4212 : (png_ptr->transformations & (PNG_FILLER)) ||
4213 : #endif
4214 4 : png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
4215 : {
4216 0 : if (max_pixel_depth <= 16)
4217 0 : max_pixel_depth = 32;
4218 :
4219 : else
4220 0 : max_pixel_depth = 64;
4221 : }
4222 :
4223 : else
4224 : {
4225 4 : if (max_pixel_depth <= 8)
4226 : {
4227 0 : if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4228 0 : max_pixel_depth = 32;
4229 :
4230 : else
4231 0 : max_pixel_depth = 24;
4232 : }
4233 :
4234 4 : else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
4235 3 : max_pixel_depth = 64;
4236 :
4237 : else
4238 1 : max_pixel_depth = 48;
4239 : }
4240 : }
4241 : #endif
4242 :
4243 : #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
4244 : defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
4245 : if (png_ptr->transformations & PNG_USER_TRANSFORM)
4246 : {
4247 : int user_pixel_depth = png_ptr->user_transform_depth *
4248 : png_ptr->user_transform_channels;
4249 :
4250 : if (user_pixel_depth > max_pixel_depth)
4251 : max_pixel_depth = user_pixel_depth;
4252 : }
4253 : #endif
4254 :
4255 : /* This value is stored in png_struct and double checked in the row read
4256 : * code.
4257 : */
4258 4 : png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
4259 4 : png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
4260 :
4261 : /* Align the width on the next larger 8 pixels. Mainly used
4262 : * for interlacing
4263 : */
4264 4 : row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
4265 : /* Calculate the maximum bytes needed, adding a byte and a pixel
4266 : * for safety's sake
4267 : */
4268 8 : row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
4269 4 : 1 + ((max_pixel_depth + 7) >> 3);
4270 :
4271 : #ifdef PNG_MAX_MALLOC_64K
4272 : if (row_bytes > (png_uint_32)65536L)
4273 : png_error(png_ptr, "This image requires a row greater than 64KB");
4274 : #endif
4275 :
4276 4 : if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
4277 : {
4278 4 : png_free(png_ptr, png_ptr->big_row_buf);
4279 4 : png_free(png_ptr, png_ptr->big_prev_row);
4280 :
4281 4 : if (png_ptr->interlaced)
4282 0 : png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
4283 : row_bytes + 48);
4284 :
4285 : else
4286 4 : png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4287 :
4288 4 : png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
4289 :
4290 : #ifdef PNG_ALIGNED_MEMORY_SUPPORTED
4291 : /* Use 16-byte aligned memory for row_buf with at least 16 bytes
4292 : * of padding before and after row_buf; treat prev_row similarly.
4293 : * NOTE: the alignment is to the start of the pixels, one beyond the start
4294 : * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
4295 : * was incorrect; the filter byte was aligned, which had the exact
4296 : * opposite effect of that intended.
4297 : */
4298 : {
4299 : png_bytep temp = png_ptr->big_row_buf + 32;
4300 : int extra = (int)((temp - (png_bytep)0) & 0x0f);
4301 : png_ptr->row_buf = temp - extra - 1/*filter byte*/;
4302 :
4303 : temp = png_ptr->big_prev_row + 32;
4304 : extra = (int)((temp - (png_bytep)0) & 0x0f);
4305 : png_ptr->prev_row = temp - extra - 1/*filter byte*/;
4306 : }
4307 :
4308 : #else
4309 : /* Use 31 bytes of padding before and 17 bytes after row_buf. */
4310 4 : png_ptr->row_buf = png_ptr->big_row_buf + 31;
4311 4 : png_ptr->prev_row = png_ptr->big_prev_row + 31;
4312 : #endif
4313 4 : png_ptr->old_big_row_buf_size = row_bytes + 48;
4314 : }
4315 :
4316 : #ifdef PNG_MAX_MALLOC_64K
4317 : if (png_ptr->rowbytes > 65535)
4318 : png_error(png_ptr, "This image requires a row greater than 64KB");
4319 :
4320 : #endif
4321 4 : if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
4322 0 : png_error(png_ptr, "Row has too many bytes to allocate in memory");
4323 :
4324 4 : png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
4325 :
4326 : png_debug1(3, "width = %u,", png_ptr->width);
4327 : png_debug1(3, "height = %u,", png_ptr->height);
4328 : png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
4329 : png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
4330 : png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
4331 : png_debug1(3, "irowbytes = %lu",
4332 : (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
4333 :
4334 4 : png_ptr->flags |= PNG_FLAG_ROW_INIT;
4335 4 : }
4336 :
4337 : #ifdef PNG_READ_APNG_SUPPORTED
4338 : /* This function is to be called after the main IDAT set has been read and
4339 : * before a new IDAT is read. It resets some parts of png_ptr
4340 : * to make them usable by the read functions again */
4341 : void /* PRIVATE */
4342 0 : png_read_reset(png_structp png_ptr)
4343 : {
4344 0 : png_ptr->mode &= ~PNG_HAVE_IDAT;
4345 0 : png_ptr->mode &= ~PNG_AFTER_IDAT;
4346 0 : png_ptr->row_number = 0;
4347 0 : png_ptr->pass = 0;
4348 0 : png_ptr->flags &= ~PNG_FLAG_ROW_INIT;
4349 0 : }
4350 :
4351 : void /* PRIVATE */
4352 0 : png_read_reinit(png_structp png_ptr, png_infop info_ptr)
4353 : {
4354 0 : png_ptr->width = info_ptr->next_frame_width;
4355 0 : png_ptr->height = info_ptr->next_frame_height;
4356 0 : png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
4357 0 : png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,
4358 : png_ptr->width);
4359 0 : if (png_ptr->prev_row)
4360 0 : png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
4361 0 : }
4362 :
4363 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
4364 : /* same as png_read_reset() but for the progressive reader */
4365 : void /* PRIVATE */
4366 0 : png_progressive_read_reset(png_structp png_ptr)
4367 : {
4368 : #ifdef PNG_READ_INTERLACING_SUPPORTED
4369 : /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
4370 :
4371 : /* Start of interlace block */
4372 0 : const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
4373 :
4374 : /* Offset to next interlace block */
4375 0 : const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
4376 :
4377 : /* Start of interlace block in the y direction */
4378 : const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
4379 :
4380 : /* Offset to next interlace block in the y direction */
4381 : const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
4382 :
4383 0 : if (png_ptr->interlaced)
4384 : {
4385 0 : if (!(png_ptr->transformations & PNG_INTERLACE))
4386 0 : png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
4387 0 : png_pass_ystart[0]) / png_pass_yinc[0];
4388 : else
4389 0 : png_ptr->num_rows = png_ptr->height;
4390 :
4391 0 : png_ptr->iwidth = (png_ptr->width +
4392 0 : png_pass_inc[png_ptr->pass] - 1 -
4393 0 : png_pass_start[png_ptr->pass]) /
4394 0 : png_pass_inc[png_ptr->pass];
4395 : }
4396 : else
4397 : #endif /* PNG_READ_INTERLACING_SUPPORTED */
4398 : {
4399 0 : png_ptr->num_rows = png_ptr->height;
4400 0 : png_ptr->iwidth = png_ptr->width;
4401 : }
4402 0 : png_ptr->flags &= ~PNG_FLAG_ZLIB_FINISHED;
4403 0 : if (inflateReset(&(png_ptr->zstream)) != Z_OK)
4404 0 : png_error(png_ptr, "inflateReset failed");
4405 0 : png_ptr->zstream.avail_in = 0;
4406 0 : png_ptr->zstream.next_in = 0;
4407 0 : png_ptr->zstream.next_out = png_ptr->row_buf;
4408 0 : png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth,
4409 0 : png_ptr->iwidth) + 1;
4410 0 : }
4411 : #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
4412 : #endif /* PNG_READ_APNG_SUPPORTED */
4413 : #endif /* PNG_READ_SUPPORTED */
|