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