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