1 :
2 : /* pngread.c - read a PNG file
3 : *
4 : * Last changed in libpng 1.5.7 [December 15, 2011]
5 : * Copyright (c) 1998-2011 Glenn Randers-Pehrson
6 : * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
7 : * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
8 : *
9 : * This code is released under the libpng license.
10 : * For conditions of distribution and use, see the disclaimer
11 : * and license in png.h
12 : *
13 : * This file contains routines that an application calls directly to
14 : * read a PNG file or stream.
15 : */
16 :
17 : #include "pngpriv.h"
18 :
19 : #ifdef PNG_READ_SUPPORTED
20 :
21 : /* Create a PNG structure for reading, and allocate any memory needed. */
22 4 : PNG_FUNCTION(png_structp,PNGAPI
23 : png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
24 : png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
25 : {
26 :
27 : #ifdef PNG_USER_MEM_SUPPORTED
28 : return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
29 : warn_fn, NULL, NULL, NULL));
30 : }
31 :
32 : /* Alternate create PNG structure for reading, and allocate any memory
33 : * needed.
34 : */
35 : PNG_FUNCTION(png_structp,PNGAPI
36 : png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
37 : png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
38 : png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
39 : {
40 : #endif /* PNG_USER_MEM_SUPPORTED */
41 :
42 : #ifdef PNG_SETJMP_SUPPORTED
43 : volatile
44 : #endif
45 : png_structp png_ptr;
46 4 : volatile int png_cleanup_needed = 0;
47 :
48 : #ifdef PNG_SETJMP_SUPPORTED
49 : #ifdef USE_FAR_KEYWORD
50 : jmp_buf tmp_jmpbuf;
51 : #endif
52 : #endif
53 :
54 : png_debug(1, "in png_create_read_struct");
55 :
56 : #ifdef PNG_USER_MEM_SUPPORTED
57 : png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
58 : malloc_fn, mem_ptr);
59 : #else
60 4 : png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
61 : #endif
62 4 : if (png_ptr == NULL)
63 0 : return (NULL);
64 :
65 : /* Added at libpng-1.2.6 */
66 : #ifdef PNG_USER_LIMITS_SUPPORTED
67 : png_ptr->user_width_max = PNG_USER_WIDTH_MAX;
68 : png_ptr->user_height_max = PNG_USER_HEIGHT_MAX;
69 :
70 : # ifdef PNG_USER_CHUNK_CACHE_MAX
71 : /* Added at libpng-1.2.43 and 1.4.0 */
72 : png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
73 : # endif
74 :
75 : # ifdef PNG_SET_USER_CHUNK_MALLOC_MAX
76 : /* Added at libpng-1.2.43 and 1.4.1 */
77 : png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
78 : # endif
79 : #endif
80 :
81 : #ifdef PNG_SETJMP_SUPPORTED
82 : /* Applications that neglect to set up their own setjmp() and then
83 : * encounter a png_error() will longjmp here. Since the jmpbuf is
84 : * then meaningless we abort instead of returning.
85 : */
86 : #ifdef USE_FAR_KEYWORD
87 : if (setjmp(tmp_jmpbuf))
88 : #else
89 4 : if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */
90 : #endif
91 0 : PNG_ABORT();
92 : #ifdef USE_FAR_KEYWORD
93 : png_memcpy(png_jmpbuf(png_ptr), tmp_jmpbuf, png_sizeof(jmp_buf));
94 : #endif
95 : #endif /* PNG_SETJMP_SUPPORTED */
96 :
97 : #ifdef PNG_USER_MEM_SUPPORTED
98 : png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
99 : #endif
100 :
101 4 : png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
102 :
103 : /* Call the general version checker (shared with read and write code): */
104 4 : if (!png_user_version_check(png_ptr, user_png_ver))
105 0 : png_cleanup_needed = 1;
106 :
107 4 : if (!png_cleanup_needed)
108 : {
109 : /* Initialize zbuf - compression buffer */
110 4 : png_ptr->zbuf_size = PNG_ZBUF_SIZE;
111 4 : png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size);
112 :
113 4 : if (png_ptr->zbuf == NULL)
114 0 : png_cleanup_needed = 1;
115 : }
116 :
117 4 : png_ptr->zstream.zalloc = png_zalloc;
118 4 : png_ptr->zstream.zfree = png_zfree;
119 4 : png_ptr->zstream.opaque = (voidpf)png_ptr;
120 :
121 4 : if (!png_cleanup_needed)
122 : {
123 4 : switch (inflateInit(&png_ptr->zstream))
124 : {
125 : case Z_OK:
126 4 : break; /* Do nothing */
127 :
128 : case Z_MEM_ERROR:
129 0 : png_warning(png_ptr, "zlib memory error");
130 0 : png_cleanup_needed = 1;
131 0 : break;
132 :
133 : case Z_STREAM_ERROR:
134 0 : png_warning(png_ptr, "zlib stream error");
135 0 : png_cleanup_needed = 1;
136 0 : break;
137 :
138 : case Z_VERSION_ERROR:
139 0 : png_warning(png_ptr, "zlib version error");
140 0 : png_cleanup_needed = 1;
141 0 : break;
142 :
143 0 : default: png_warning(png_ptr, "Unknown zlib error");
144 0 : png_cleanup_needed = 1;
145 : }
146 : }
147 :
148 4 : if (png_cleanup_needed)
149 : {
150 : /* Clean up PNG structure and deallocate any memory. */
151 0 : png_free(png_ptr, png_ptr->zbuf);
152 0 : png_ptr->zbuf = NULL;
153 : #ifdef PNG_USER_MEM_SUPPORTED
154 : png_destroy_struct_2((png_voidp)png_ptr,
155 : (png_free_ptr)free_fn, (png_voidp)mem_ptr);
156 : #else
157 0 : png_destroy_struct((png_voidp)png_ptr);
158 : #endif
159 0 : return (NULL);
160 : }
161 :
162 4 : png_ptr->zstream.next_out = png_ptr->zbuf;
163 4 : png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
164 :
165 4 : png_set_read_fn(png_ptr, NULL, NULL);
166 :
167 :
168 4 : return (png_ptr);
169 : }
170 :
171 :
172 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
173 : /* Read the information before the actual image data. This has been
174 : * changed in v0.90 to allow reading a file that already has the magic
175 : * bytes read from the stream. You can tell libpng how many bytes have
176 : * been read from the beginning of the stream (up to the maximum of 8)
177 : * via png_set_sig_bytes(), and we will only check the remaining bytes
178 : * here. The application can then have access to the signature bytes we
179 : * read if it is determined that this isn't a valid PNG file.
180 : */
181 : void PNGAPI
182 : png_read_info(png_structp png_ptr, png_infop info_ptr)
183 : {
184 : png_debug(1, "in png_read_info");
185 :
186 : if (png_ptr == NULL || info_ptr == NULL)
187 : return;
188 :
189 : /* Read and check the PNG file signature. */
190 : png_read_sig(png_ptr, info_ptr);
191 :
192 : for (;;)
193 : {
194 : png_uint_32 length = png_read_chunk_header(png_ptr);
195 : png_uint_32 chunk_name = png_ptr->chunk_name;
196 :
197 : /* This should be a binary subdivision search or a hash for
198 : * matching the chunk name rather than a linear search.
199 : */
200 : if (chunk_name == png_IDAT)
201 : if (png_ptr->mode & PNG_AFTER_IDAT)
202 : png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
203 :
204 : if (chunk_name == png_IHDR)
205 : png_handle_IHDR(png_ptr, info_ptr, length);
206 :
207 : else if (chunk_name == png_IEND)
208 : png_handle_IEND(png_ptr, info_ptr, length);
209 :
210 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
211 : else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
212 : PNG_HANDLE_CHUNK_AS_DEFAULT)
213 : {
214 : if (chunk_name == png_IDAT)
215 : png_ptr->mode |= PNG_HAVE_IDAT;
216 :
217 : png_handle_unknown(png_ptr, info_ptr, length);
218 :
219 : if (chunk_name == png_PLTE)
220 : png_ptr->mode |= PNG_HAVE_PLTE;
221 :
222 : else if (chunk_name == png_IDAT)
223 : {
224 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
225 : png_error(png_ptr, "Missing IHDR before IDAT");
226 :
227 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
228 : !(png_ptr->mode & PNG_HAVE_PLTE))
229 : png_error(png_ptr, "Missing PLTE before IDAT");
230 :
231 : break;
232 : }
233 : }
234 : #endif
235 : else if (chunk_name == png_PLTE)
236 : png_handle_PLTE(png_ptr, info_ptr, length);
237 :
238 : else if (chunk_name == png_IDAT)
239 : {
240 : if (!(png_ptr->mode & PNG_HAVE_IHDR))
241 : png_error(png_ptr, "Missing IHDR before IDAT");
242 :
243 : else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
244 : !(png_ptr->mode & PNG_HAVE_PLTE))
245 : png_error(png_ptr, "Missing PLTE before IDAT");
246 :
247 : #ifdef PNG_READ_APNG_SUPPORTED
248 : png_have_info(png_ptr, info_ptr);
249 : #endif
250 : png_ptr->idat_size = length;
251 : png_ptr->mode |= PNG_HAVE_IDAT;
252 : break;
253 : }
254 :
255 : #ifdef PNG_READ_bKGD_SUPPORTED
256 : else if (chunk_name == png_bKGD)
257 : png_handle_bKGD(png_ptr, info_ptr, length);
258 : #endif
259 :
260 : #ifdef PNG_READ_cHRM_SUPPORTED
261 : else if (chunk_name == png_cHRM)
262 : png_handle_cHRM(png_ptr, info_ptr, length);
263 : #endif
264 :
265 : #ifdef PNG_READ_gAMA_SUPPORTED
266 : else if (chunk_name == png_gAMA)
267 : png_handle_gAMA(png_ptr, info_ptr, length);
268 : #endif
269 :
270 : #ifdef PNG_READ_hIST_SUPPORTED
271 : else if (chunk_name == png_hIST)
272 : png_handle_hIST(png_ptr, info_ptr, length);
273 : #endif
274 :
275 : #ifdef PNG_READ_oFFs_SUPPORTED
276 : else if (chunk_name == png_oFFs)
277 : png_handle_oFFs(png_ptr, info_ptr, length);
278 : #endif
279 :
280 : #ifdef PNG_READ_pCAL_SUPPORTED
281 : else if (chunk_name == png_pCAL)
282 : png_handle_pCAL(png_ptr, info_ptr, length);
283 : #endif
284 :
285 : #ifdef PNG_READ_sCAL_SUPPORTED
286 : else if (chunk_name == png_sCAL)
287 : png_handle_sCAL(png_ptr, info_ptr, length);
288 : #endif
289 :
290 : #ifdef PNG_READ_pHYs_SUPPORTED
291 : else if (chunk_name == png_pHYs)
292 : png_handle_pHYs(png_ptr, info_ptr, length);
293 : #endif
294 :
295 : #ifdef PNG_READ_sBIT_SUPPORTED
296 : else if (chunk_name == png_sBIT)
297 : png_handle_sBIT(png_ptr, info_ptr, length);
298 : #endif
299 :
300 : #ifdef PNG_READ_sRGB_SUPPORTED
301 : else if (chunk_name == png_sRGB)
302 : png_handle_sRGB(png_ptr, info_ptr, length);
303 : #endif
304 :
305 : #ifdef PNG_READ_iCCP_SUPPORTED
306 : else if (chunk_name == png_iCCP)
307 : png_handle_iCCP(png_ptr, info_ptr, length);
308 : #endif
309 :
310 : #ifdef PNG_READ_sPLT_SUPPORTED
311 : else if (chunk_name == png_sPLT)
312 : png_handle_sPLT(png_ptr, info_ptr, length);
313 : #endif
314 :
315 : #ifdef PNG_READ_tEXt_SUPPORTED
316 : else if (chunk_name == png_tEXt)
317 : png_handle_tEXt(png_ptr, info_ptr, length);
318 : #endif
319 :
320 : #ifdef PNG_READ_tIME_SUPPORTED
321 : else if (chunk_name == png_tIME)
322 : png_handle_tIME(png_ptr, info_ptr, length);
323 : #endif
324 :
325 : #ifdef PNG_READ_tRNS_SUPPORTED
326 : else if (chunk_name == png_tRNS)
327 : png_handle_tRNS(png_ptr, info_ptr, length);
328 : #endif
329 :
330 : #ifdef PNG_READ_zTXt_SUPPORTED
331 : else if (chunk_name == png_zTXt)
332 : png_handle_zTXt(png_ptr, info_ptr, length);
333 : #endif
334 :
335 : #ifdef PNG_READ_iTXt_SUPPORTED
336 : else if (chunk_name == png_iTXt)
337 : png_handle_iTXt(png_ptr, info_ptr, length);
338 : #endif
339 :
340 : #ifdef PNG_READ_APNG_SUPPORTED
341 : else if (chunk_name == png_acTL)
342 : png_handle_acTL(png_ptr, info_ptr, length);
343 :
344 : else if (chunk_name == png_fcTL)
345 : png_handle_fcTL(png_ptr, info_ptr, length);
346 :
347 : else if (chunk_name == png_fdAT)
348 : png_handle_fdAT(png_ptr, info_ptr, length);
349 : #endif
350 :
351 : else
352 : png_handle_unknown(png_ptr, info_ptr, length);
353 : }
354 : }
355 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
356 :
357 : #ifdef PNG_READ_APNG_SUPPORTED
358 : void PNGAPI
359 0 : png_read_frame_head(png_structp png_ptr, png_infop info_ptr)
360 : {
361 : png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */
362 :
363 : png_debug(0, "Reading frame head");
364 :
365 0 : if (!(png_ptr->mode & PNG_HAVE_acTL))
366 0 : png_error(png_ptr, "attempt to png_read_frame_head() but "
367 : "no acTL present");
368 :
369 : /* do nothing for the main IDAT */
370 0 : if (png_ptr->num_frames_read == 0)
371 0 : return;
372 :
373 0 : png_crc_finish(png_ptr, 0); /* CRC from last IDAT or fdAT chunk */
374 :
375 0 : png_read_reset(png_ptr);
376 0 : png_ptr->mode &= ~PNG_HAVE_fcTL;
377 :
378 0 : have_chunk_after_DAT = 0;
379 : for (;;)
380 : {
381 0 : png_uint_32 length = png_read_chunk_header(png_ptr);
382 :
383 0 : if (png_ptr->chunk_name == png_IDAT)
384 : {
385 : /* discard trailing IDATs for the first frame */
386 0 : if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
387 0 : png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
388 0 : png_crc_finish(png_ptr, length);
389 : }
390 :
391 0 : else if (png_ptr->chunk_name == png_fcTL)
392 : {
393 0 : png_handle_fcTL(png_ptr, info_ptr, length);
394 0 : have_chunk_after_DAT = 1;
395 : }
396 :
397 0 : else if (png_ptr->chunk_name == png_fdAT)
398 : {
399 0 : png_ensure_sequence_number(png_ptr, length);
400 :
401 : /* discard trailing fdATs for frames other than the first */
402 0 : if (!have_chunk_after_DAT && png_ptr->num_frames_read > 1)
403 0 : png_crc_finish(png_ptr, length - 4);
404 0 : else if(png_ptr->mode & PNG_HAVE_fcTL)
405 : {
406 0 : png_ptr->idat_size = length - 4;
407 0 : png_ptr->mode |= PNG_HAVE_IDAT;
408 :
409 0 : break;
410 : }
411 : else
412 0 : png_error(png_ptr, "png_read_frame_head(): out of place fdAT");
413 : }
414 : else
415 : {
416 : png_warning(png_ptr, "Skipped (ignored) a chunk "
417 : "between APNG chunks");
418 0 : png_crc_finish(png_ptr, length);
419 : }
420 0 : }
421 : }
422 : #endif /* PNG_READ_APNG_SUPPORTED */
423 :
424 : /* Optional call to update the users info_ptr structure */
425 : void PNGAPI
426 4 : png_read_update_info(png_structp png_ptr, png_infop info_ptr)
427 : {
428 : png_debug(1, "in png_read_update_info");
429 :
430 4 : if (png_ptr == NULL)
431 0 : return;
432 :
433 4 : png_read_start_row(png_ptr);
434 :
435 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
436 4 : png_read_transform_info(png_ptr, info_ptr);
437 : #else
438 : PNG_UNUSED(info_ptr)
439 : #endif
440 : }
441 :
442 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
443 : /* Initialize palette, background, etc, after transformations
444 : * are set, but before any reading takes place. This allows
445 : * the user to obtain a gamma-corrected palette, for example.
446 : * If the user doesn't call this, we will do it ourselves.
447 : */
448 : void PNGAPI
449 : png_start_read_image(png_structp png_ptr)
450 : {
451 : png_debug(1, "in png_start_read_image");
452 :
453 : if (png_ptr != NULL)
454 : png_read_start_row(png_ptr);
455 : }
456 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
457 :
458 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
459 : void PNGAPI
460 : png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
461 : {
462 : int ret;
463 :
464 : png_row_info row_info;
465 :
466 : if (png_ptr == NULL)
467 : return;
468 :
469 : png_debug2(1, "in png_read_row (row %lu, pass %d)",
470 : (unsigned long)png_ptr->row_number, png_ptr->pass);
471 :
472 : /* png_read_start_row sets the information (in particular iwidth) for this
473 : * interlace pass.
474 : */
475 : if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
476 : png_read_start_row(png_ptr);
477 :
478 : /* 1.5.6: row_info moved out of png_struct to a local here. */
479 : row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
480 : row_info.color_type = png_ptr->color_type;
481 : row_info.bit_depth = png_ptr->bit_depth;
482 : row_info.channels = png_ptr->channels;
483 : row_info.pixel_depth = png_ptr->pixel_depth;
484 : row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
485 :
486 : if (png_ptr->row_number == 0 && png_ptr->pass == 0)
487 : {
488 : /* Check for transforms that have been set but were defined out */
489 : #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
490 : if (png_ptr->transformations & PNG_INVERT_MONO)
491 : png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
492 : #endif
493 :
494 : #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
495 : if (png_ptr->transformations & PNG_FILLER)
496 : png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
497 : #endif
498 :
499 : #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
500 : !defined(PNG_READ_PACKSWAP_SUPPORTED)
501 : if (png_ptr->transformations & PNG_PACKSWAP)
502 : png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
503 : #endif
504 :
505 : #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
506 : if (png_ptr->transformations & PNG_PACK)
507 : png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
508 : #endif
509 :
510 : #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
511 : if (png_ptr->transformations & PNG_SHIFT)
512 : png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
513 : #endif
514 :
515 : #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
516 : if (png_ptr->transformations & PNG_BGR)
517 : png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
518 : #endif
519 :
520 : #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
521 : if (png_ptr->transformations & PNG_SWAP_BYTES)
522 : png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
523 : #endif
524 : }
525 :
526 : #ifdef PNG_READ_INTERLACING_SUPPORTED
527 : /* If interlaced and we do not need a new row, combine row and return.
528 : * Notice that the pixels we have from previous rows have been transformed
529 : * already; we can only combine like with like (transformed or
530 : * untransformed) and, because of the libpng API for interlaced images, this
531 : * means we must transform before de-interlacing.
532 : */
533 : if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
534 : {
535 : switch (png_ptr->pass)
536 : {
537 : case 0:
538 : if (png_ptr->row_number & 0x07)
539 : {
540 : if (dsp_row != NULL)
541 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
542 : png_read_finish_row(png_ptr);
543 : return;
544 : }
545 : break;
546 :
547 : case 1:
548 : if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
549 : {
550 : if (dsp_row != NULL)
551 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
552 :
553 : png_read_finish_row(png_ptr);
554 : return;
555 : }
556 : break;
557 :
558 : case 2:
559 : if ((png_ptr->row_number & 0x07) != 4)
560 : {
561 : if (dsp_row != NULL && (png_ptr->row_number & 4))
562 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
563 :
564 : png_read_finish_row(png_ptr);
565 : return;
566 : }
567 : break;
568 :
569 : case 3:
570 : if ((png_ptr->row_number & 3) || png_ptr->width < 3)
571 : {
572 : if (dsp_row != NULL)
573 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
574 :
575 : png_read_finish_row(png_ptr);
576 : return;
577 : }
578 : break;
579 :
580 : case 4:
581 : if ((png_ptr->row_number & 3) != 2)
582 : {
583 : if (dsp_row != NULL && (png_ptr->row_number & 2))
584 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
585 :
586 : png_read_finish_row(png_ptr);
587 : return;
588 : }
589 : break;
590 : case 5:
591 : if ((png_ptr->row_number & 1) || png_ptr->width < 2)
592 : {
593 : if (dsp_row != NULL)
594 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
595 :
596 : png_read_finish_row(png_ptr);
597 : return;
598 : }
599 : break;
600 :
601 : default:
602 : case 6:
603 : if (!(png_ptr->row_number & 1))
604 : {
605 : png_read_finish_row(png_ptr);
606 : return;
607 : }
608 : break;
609 : }
610 : }
611 : #endif
612 :
613 : if (!(png_ptr->mode & PNG_HAVE_IDAT))
614 : png_error(png_ptr, "Invalid attempt to read row data");
615 :
616 : png_ptr->zstream.next_out = png_ptr->row_buf;
617 : png_ptr->zstream.avail_out =
618 : (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
619 : png_ptr->iwidth) + 1);
620 :
621 : do
622 : {
623 : if (!(png_ptr->zstream.avail_in))
624 : {
625 : #ifdef PNG_READ_APNG_SUPPORTED
626 : png_uint_32 bytes_to_skip = 0;
627 :
628 : while (!png_ptr->idat_size || bytes_to_skip != 0)
629 : {
630 : png_crc_finish(png_ptr, bytes_to_skip);
631 : bytes_to_skip = 0;
632 :
633 : png_ptr->idat_size = png_read_chunk_header(png_ptr);
634 : if (png_ptr->num_frames_read == 0)
635 : {
636 : if (png_ptr->chunk_name != png_IDAT)
637 : png_error(png_ptr, "Not enough image data");
638 : }
639 : else
640 : {
641 : if (png_ptr->chunk_name == png_IEND)
642 : png_error(png_ptr, "Not enough image data");
643 : if (png_ptr->chunk_name != png_fdAT)
644 : {
645 : png_warning(png_ptr, "Skipped (ignored) a chunk "
646 : "between APNG chunks");
647 : bytes_to_skip = png_ptr->idat_size;
648 : continue;
649 : }
650 :
651 : png_ensure_sequence_number(png_ptr, png_ptr->idat_size);
652 :
653 : png_ptr->idat_size -= 4;
654 : }
655 : }
656 : #else
657 : while (!png_ptr->idat_size)
658 : {
659 : png_crc_finish(png_ptr, 0);
660 :
661 : png_ptr->idat_size = png_read_chunk_header(png_ptr);
662 : if (png_ptr->chunk_name != png_IDAT)
663 : png_error(png_ptr, "Not enough image data");
664 : }
665 : #endif
666 : png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
667 : png_ptr->zstream.next_in = png_ptr->zbuf;
668 : if (png_ptr->zbuf_size > png_ptr->idat_size)
669 : png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
670 : png_crc_read(png_ptr, png_ptr->zbuf,
671 : (png_size_t)png_ptr->zstream.avail_in);
672 : png_ptr->idat_size -= png_ptr->zstream.avail_in;
673 : }
674 :
675 : ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
676 :
677 : if (ret == Z_STREAM_END)
678 : {
679 : if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
680 : png_ptr->idat_size)
681 : png_benign_error(png_ptr, "Extra compressed data");
682 : png_ptr->mode |= PNG_AFTER_IDAT;
683 : png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
684 : #ifdef PNG_READ_APNG_SUPPORTED
685 : png_ptr->num_frames_read++;
686 : #endif
687 : break;
688 : }
689 :
690 : if (ret != Z_OK)
691 : png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
692 : "Decompression error");
693 :
694 : } while (png_ptr->zstream.avail_out);
695 :
696 : if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
697 : {
698 : if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
699 : png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
700 : png_ptr->prev_row + 1, png_ptr->row_buf[0]);
701 : else
702 : png_error(png_ptr, "bad adaptive filter value");
703 : }
704 :
705 : /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
706 : * 1.5.6, while the buffer really is this big in current versions of libpng
707 : * it may not be in the future, so this was changed just to copy the
708 : * interlaced count:
709 : */
710 : png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
711 :
712 : #ifdef PNG_MNG_FEATURES_SUPPORTED
713 : if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
714 : (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
715 : {
716 : /* Intrapixel differencing */
717 : png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
718 : }
719 : #endif
720 :
721 :
722 : #ifdef PNG_READ_TRANSFORMS_SUPPORTED
723 : if (png_ptr->transformations)
724 : png_do_read_transformations(png_ptr, &row_info);
725 : #endif
726 :
727 : /* The transformed pixel depth should match the depth now in row_info. */
728 : if (png_ptr->transformed_pixel_depth == 0)
729 : {
730 : png_ptr->transformed_pixel_depth = row_info.pixel_depth;
731 : if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
732 : png_error(png_ptr, "sequential row overflow");
733 : }
734 :
735 : else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
736 : png_error(png_ptr, "internal sequential row size calculation error");
737 :
738 : #ifdef PNG_READ_INTERLACING_SUPPORTED
739 : /* Blow up interlaced rows to full size */
740 : if (png_ptr->interlaced &&
741 : (png_ptr->transformations & PNG_INTERLACE))
742 : {
743 : if (png_ptr->pass < 6)
744 : png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
745 : png_ptr->transformations);
746 :
747 : if (dsp_row != NULL)
748 : png_combine_row(png_ptr, dsp_row, 1/*display*/);
749 :
750 : if (row != NULL)
751 : png_combine_row(png_ptr, row, 0/*row*/);
752 : }
753 :
754 : else
755 : #endif
756 : {
757 : if (row != NULL)
758 : png_combine_row(png_ptr, row, -1/*ignored*/);
759 :
760 : if (dsp_row != NULL)
761 : png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
762 : }
763 : png_read_finish_row(png_ptr);
764 :
765 : if (png_ptr->read_row_fn != NULL)
766 : (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
767 : }
768 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
769 :
770 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
771 : /* Read one or more rows of image data. If the image is interlaced,
772 : * and png_set_interlace_handling() has been called, the rows need to
773 : * contain the contents of the rows from the previous pass. If the
774 : * image has alpha or transparency, and png_handle_alpha()[*] has been
775 : * called, the rows contents must be initialized to the contents of the
776 : * screen.
777 : *
778 : * "row" holds the actual image, and pixels are placed in it
779 : * as they arrive. If the image is displayed after each pass, it will
780 : * appear to "sparkle" in. "display_row" can be used to display a
781 : * "chunky" progressive image, with finer detail added as it becomes
782 : * available. If you do not want this "chunky" display, you may pass
783 : * NULL for display_row. If you do not want the sparkle display, and
784 : * you have not called png_handle_alpha(), you may pass NULL for rows.
785 : * If you have called png_handle_alpha(), and the image has either an
786 : * alpha channel or a transparency chunk, you must provide a buffer for
787 : * rows. In this case, you do not have to provide a display_row buffer
788 : * also, but you may. If the image is not interlaced, or if you have
789 : * not called png_set_interlace_handling(), the display_row buffer will
790 : * be ignored, so pass NULL to it.
791 : *
792 : * [*] png_handle_alpha() does not exist yet, as of this version of libpng
793 : */
794 :
795 : void PNGAPI
796 : png_read_rows(png_structp png_ptr, png_bytepp row,
797 : png_bytepp display_row, png_uint_32 num_rows)
798 : {
799 : png_uint_32 i;
800 : png_bytepp rp;
801 : png_bytepp dp;
802 :
803 : png_debug(1, "in png_read_rows");
804 :
805 : if (png_ptr == NULL)
806 : return;
807 :
808 : rp = row;
809 : dp = display_row;
810 : if (rp != NULL && dp != NULL)
811 : for (i = 0; i < num_rows; i++)
812 : {
813 : png_bytep rptr = *rp++;
814 : png_bytep dptr = *dp++;
815 :
816 : png_read_row(png_ptr, rptr, dptr);
817 : }
818 :
819 : else if (rp != NULL)
820 : for (i = 0; i < num_rows; i++)
821 : {
822 : png_bytep rptr = *rp;
823 : png_read_row(png_ptr, rptr, NULL);
824 : rp++;
825 : }
826 :
827 : else if (dp != NULL)
828 : for (i = 0; i < num_rows; i++)
829 : {
830 : png_bytep dptr = *dp;
831 : png_read_row(png_ptr, NULL, dptr);
832 : dp++;
833 : }
834 : }
835 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
836 :
837 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
838 : /* Read the entire image. If the image has an alpha channel or a tRNS
839 : * chunk, and you have called png_handle_alpha()[*], you will need to
840 : * initialize the image to the current image that PNG will be overlaying.
841 : * We set the num_rows again here, in case it was incorrectly set in
842 : * png_read_start_row() by a call to png_read_update_info() or
843 : * png_start_read_image() if png_set_interlace_handling() wasn't called
844 : * prior to either of these functions like it should have been. You can
845 : * only call this function once. If you desire to have an image for
846 : * each pass of a interlaced image, use png_read_rows() instead.
847 : *
848 : * [*] png_handle_alpha() does not exist yet, as of this version of libpng
849 : */
850 : void PNGAPI
851 : png_read_image(png_structp png_ptr, png_bytepp image)
852 : {
853 : png_uint_32 i, image_height;
854 : int pass, j;
855 : png_bytepp rp;
856 :
857 : png_debug(1, "in png_read_image");
858 :
859 : if (png_ptr == NULL)
860 : return;
861 :
862 : #ifdef PNG_READ_INTERLACING_SUPPORTED
863 : if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
864 : {
865 : pass = png_set_interlace_handling(png_ptr);
866 : /* And make sure transforms are initialized. */
867 : png_start_read_image(png_ptr);
868 : }
869 : else
870 : {
871 : if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
872 : {
873 : /* Caller called png_start_read_image or png_read_update_info without
874 : * first turning on the PNG_INTERLACE transform. We can fix this here,
875 : * but the caller should do it!
876 : */
877 : png_warning(png_ptr, "Interlace handling should be turned on when "
878 : "using png_read_image");
879 : /* Make sure this is set correctly */
880 : png_ptr->num_rows = png_ptr->height;
881 : }
882 :
883 : /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
884 : * the above error case.
885 : */
886 : pass = png_set_interlace_handling(png_ptr);
887 : }
888 : #else
889 : if (png_ptr->interlaced)
890 : png_error(png_ptr,
891 : "Cannot read interlaced image -- interlace handler disabled");
892 :
893 : pass = 1;
894 : #endif
895 :
896 : image_height=png_ptr->height;
897 :
898 : for (j = 0; j < pass; j++)
899 : {
900 : rp = image;
901 : for (i = 0; i < image_height; i++)
902 : {
903 : png_read_row(png_ptr, *rp, NULL);
904 : rp++;
905 : }
906 : }
907 : }
908 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
909 :
910 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
911 : /* Read the end of the PNG file. Will not read past the end of the
912 : * file, will verify the end is accurate, and will read any comments
913 : * or time information at the end of the file, if info is not NULL.
914 : */
915 : void PNGAPI
916 : png_read_end(png_structp png_ptr, png_infop info_ptr)
917 : {
918 : png_debug(1, "in png_read_end");
919 :
920 : if (png_ptr == NULL)
921 : return;
922 :
923 : png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
924 :
925 : do
926 : {
927 : png_uint_32 length = png_read_chunk_header(png_ptr);
928 : png_uint_32 chunk_name = png_ptr->chunk_name;
929 :
930 : if (chunk_name == png_IHDR)
931 : png_handle_IHDR(png_ptr, info_ptr, length);
932 :
933 : else if (chunk_name == png_IEND)
934 : png_handle_IEND(png_ptr, info_ptr, length);
935 :
936 : #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
937 : else if (png_chunk_unknown_handling(png_ptr, chunk_name) !=
938 : PNG_HANDLE_CHUNK_AS_DEFAULT)
939 : {
940 : if (chunk_name == png_IDAT)
941 : {
942 : if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
943 : png_benign_error(png_ptr, "Too many IDATs found");
944 : }
945 : png_handle_unknown(png_ptr, info_ptr, length);
946 : if (chunk_name == png_PLTE)
947 : png_ptr->mode |= PNG_HAVE_PLTE;
948 : }
949 : #endif
950 :
951 : else if (chunk_name == png_IDAT)
952 : {
953 : /* Zero length IDATs are legal after the last IDAT has been
954 : * read, but not after other chunks have been read.
955 : */
956 : if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
957 : png_benign_error(png_ptr, "Too many IDATs found");
958 :
959 : png_crc_finish(png_ptr, length);
960 : }
961 : else if (chunk_name == png_PLTE)
962 : png_handle_PLTE(png_ptr, info_ptr, length);
963 :
964 : #ifdef PNG_READ_bKGD_SUPPORTED
965 : else if (chunk_name == png_bKGD)
966 : png_handle_bKGD(png_ptr, info_ptr, length);
967 : #endif
968 :
969 : #ifdef PNG_READ_cHRM_SUPPORTED
970 : else if (chunk_name == png_cHRM)
971 : png_handle_cHRM(png_ptr, info_ptr, length);
972 : #endif
973 :
974 : #ifdef PNG_READ_gAMA_SUPPORTED
975 : else if (chunk_name == png_gAMA)
976 : png_handle_gAMA(png_ptr, info_ptr, length);
977 : #endif
978 :
979 : #ifdef PNG_READ_hIST_SUPPORTED
980 : else if (chunk_name == png_hIST)
981 : png_handle_hIST(png_ptr, info_ptr, length);
982 : #endif
983 :
984 : #ifdef PNG_READ_oFFs_SUPPORTED
985 : else if (chunk_name == png_oFFs)
986 : png_handle_oFFs(png_ptr, info_ptr, length);
987 : #endif
988 :
989 : #ifdef PNG_READ_pCAL_SUPPORTED
990 : else if (chunk_name == png_pCAL)
991 : png_handle_pCAL(png_ptr, info_ptr, length);
992 : #endif
993 :
994 : #ifdef PNG_READ_sCAL_SUPPORTED
995 : else if (chunk_name == png_sCAL)
996 : png_handle_sCAL(png_ptr, info_ptr, length);
997 : #endif
998 :
999 : #ifdef PNG_READ_pHYs_SUPPORTED
1000 : else if (chunk_name == png_pHYs)
1001 : png_handle_pHYs(png_ptr, info_ptr, length);
1002 : #endif
1003 :
1004 : #ifdef PNG_READ_sBIT_SUPPORTED
1005 : else if (chunk_name == png_sBIT)
1006 : png_handle_sBIT(png_ptr, info_ptr, length);
1007 : #endif
1008 :
1009 : #ifdef PNG_READ_sRGB_SUPPORTED
1010 : else if (chunk_name == png_sRGB)
1011 : png_handle_sRGB(png_ptr, info_ptr, length);
1012 : #endif
1013 :
1014 : #ifdef PNG_READ_iCCP_SUPPORTED
1015 : else if (chunk_name == png_iCCP)
1016 : png_handle_iCCP(png_ptr, info_ptr, length);
1017 : #endif
1018 :
1019 : #ifdef PNG_READ_sPLT_SUPPORTED
1020 : else if (chunk_name == png_sPLT)
1021 : png_handle_sPLT(png_ptr, info_ptr, length);
1022 : #endif
1023 :
1024 : #ifdef PNG_READ_tEXt_SUPPORTED
1025 : else if (chunk_name == png_tEXt)
1026 : png_handle_tEXt(png_ptr, info_ptr, length);
1027 : #endif
1028 :
1029 : #ifdef PNG_READ_tIME_SUPPORTED
1030 : else if (chunk_name == png_tIME)
1031 : png_handle_tIME(png_ptr, info_ptr, length);
1032 : #endif
1033 :
1034 : #ifdef PNG_READ_tRNS_SUPPORTED
1035 : else if (chunk_name == png_tRNS)
1036 : png_handle_tRNS(png_ptr, info_ptr, length);
1037 : #endif
1038 :
1039 : #ifdef PNG_READ_zTXt_SUPPORTED
1040 : else if (chunk_name == png_zTXt)
1041 : png_handle_zTXt(png_ptr, info_ptr, length);
1042 : #endif
1043 :
1044 : #ifdef PNG_READ_iTXt_SUPPORTED
1045 : else if (chunk_name == png_iTXt)
1046 : png_handle_iTXt(png_ptr, info_ptr, length);
1047 : #endif
1048 :
1049 : #ifdef PNG_READ_APNG_SUPPORTED
1050 : else if (chunk_name == png_acTL)
1051 : png_handle_acTL(png_ptr, info_ptr, length);
1052 : else if (chunk_name == png_fcTL)
1053 : png_handle_fcTL(png_ptr, info_ptr, length);
1054 : else if (chunk_name == png_fdAT)
1055 : png_handle_fdAT(png_ptr, info_ptr, length);
1056 : #endif
1057 :
1058 : else
1059 : png_handle_unknown(png_ptr, info_ptr, length);
1060 : } while (!(png_ptr->mode & PNG_HAVE_IEND));
1061 : }
1062 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1063 :
1064 : /* Free all memory used by the read */
1065 : void PNGAPI
1066 4 : png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
1067 : png_infopp end_info_ptr_ptr)
1068 : {
1069 4 : png_structp png_ptr = NULL;
1070 4 : png_infop info_ptr = NULL, end_info_ptr = NULL;
1071 : #ifdef PNG_USER_MEM_SUPPORTED
1072 : png_free_ptr free_fn = NULL;
1073 : png_voidp mem_ptr = NULL;
1074 : #endif
1075 :
1076 : png_debug(1, "in png_destroy_read_struct");
1077 :
1078 4 : if (png_ptr_ptr != NULL)
1079 4 : png_ptr = *png_ptr_ptr;
1080 4 : if (png_ptr == NULL)
1081 0 : return;
1082 :
1083 : #ifdef PNG_USER_MEM_SUPPORTED
1084 : free_fn = png_ptr->free_fn;
1085 : mem_ptr = png_ptr->mem_ptr;
1086 : #endif
1087 :
1088 4 : if (info_ptr_ptr != NULL)
1089 4 : info_ptr = *info_ptr_ptr;
1090 :
1091 4 : if (end_info_ptr_ptr != NULL)
1092 0 : end_info_ptr = *end_info_ptr_ptr;
1093 :
1094 4 : png_read_destroy(png_ptr, info_ptr, end_info_ptr);
1095 :
1096 4 : if (info_ptr != NULL)
1097 : {
1098 : #ifdef PNG_TEXT_SUPPORTED
1099 4 : png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
1100 : #endif
1101 :
1102 : #ifdef PNG_USER_MEM_SUPPORTED
1103 : png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
1104 : (png_voidp)mem_ptr);
1105 : #else
1106 4 : png_destroy_struct((png_voidp)info_ptr);
1107 : #endif
1108 4 : *info_ptr_ptr = NULL;
1109 : }
1110 :
1111 4 : if (end_info_ptr != NULL)
1112 : {
1113 : #ifdef PNG_READ_TEXT_SUPPORTED
1114 0 : png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
1115 : #endif
1116 : #ifdef PNG_USER_MEM_SUPPORTED
1117 : png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
1118 : (png_voidp)mem_ptr);
1119 : #else
1120 0 : png_destroy_struct((png_voidp)end_info_ptr);
1121 : #endif
1122 0 : *end_info_ptr_ptr = NULL;
1123 : }
1124 :
1125 4 : if (png_ptr != NULL)
1126 : {
1127 : #ifdef PNG_USER_MEM_SUPPORTED
1128 : png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
1129 : (png_voidp)mem_ptr);
1130 : #else
1131 4 : png_destroy_struct((png_voidp)png_ptr);
1132 : #endif
1133 4 : *png_ptr_ptr = NULL;
1134 : }
1135 : }
1136 :
1137 : /* Free all memory used by the read (old method) */
1138 : void /* PRIVATE */
1139 4 : png_read_destroy(png_structp png_ptr, png_infop info_ptr,
1140 : png_infop end_info_ptr)
1141 : {
1142 : #ifdef PNG_SETJMP_SUPPORTED
1143 : jmp_buf tmp_jmp;
1144 : #endif
1145 : png_error_ptr error_fn;
1146 : #ifdef PNG_WARNINGS_SUPPORTED
1147 : png_error_ptr warning_fn;
1148 : #endif
1149 : png_voidp error_ptr;
1150 : #ifdef PNG_USER_MEM_SUPPORTED
1151 : png_free_ptr free_fn;
1152 : #endif
1153 :
1154 : png_debug(1, "in png_read_destroy");
1155 :
1156 4 : if (info_ptr != NULL)
1157 4 : png_info_destroy(png_ptr, info_ptr);
1158 :
1159 4 : if (end_info_ptr != NULL)
1160 0 : png_info_destroy(png_ptr, end_info_ptr);
1161 :
1162 : #ifdef PNG_READ_GAMMA_SUPPORTED
1163 4 : png_destroy_gamma_table(png_ptr);
1164 : #endif
1165 :
1166 4 : png_free(png_ptr, png_ptr->zbuf);
1167 4 : png_free(png_ptr, png_ptr->big_row_buf);
1168 4 : png_free(png_ptr, png_ptr->big_prev_row);
1169 4 : png_free(png_ptr, png_ptr->chunkdata);
1170 :
1171 : #ifdef PNG_READ_QUANTIZE_SUPPORTED
1172 : png_free(png_ptr, png_ptr->palette_lookup);
1173 : png_free(png_ptr, png_ptr->quantize_index);
1174 : #endif
1175 :
1176 4 : if (png_ptr->free_me & PNG_FREE_PLTE)
1177 0 : png_zfree(png_ptr, png_ptr->palette);
1178 4 : png_ptr->free_me &= ~PNG_FREE_PLTE;
1179 :
1180 : #if defined(PNG_tRNS_SUPPORTED) || \
1181 : defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
1182 4 : if (png_ptr->free_me & PNG_FREE_TRNS)
1183 0 : png_free(png_ptr, png_ptr->trans_alpha);
1184 4 : png_ptr->free_me &= ~PNG_FREE_TRNS;
1185 : #endif
1186 :
1187 : #ifdef PNG_READ_hIST_SUPPORTED
1188 : if (png_ptr->free_me & PNG_FREE_HIST)
1189 : png_free(png_ptr, png_ptr->hist);
1190 : png_ptr->free_me &= ~PNG_FREE_HIST;
1191 : #endif
1192 :
1193 4 : inflateEnd(&png_ptr->zstream);
1194 :
1195 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1196 4 : png_free(png_ptr, png_ptr->save_buffer);
1197 : #endif
1198 :
1199 : #ifdef PNG_PROGRESSIVE_READ_SUPPORTED
1200 : #ifdef PNG_TEXT_SUPPORTED
1201 4 : png_free(png_ptr, png_ptr->current_text);
1202 : #endif /* PNG_TEXT_SUPPORTED */
1203 : #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
1204 :
1205 : /* Save the important info out of the png_struct, in case it is
1206 : * being used again.
1207 : */
1208 : #ifdef PNG_SETJMP_SUPPORTED
1209 4 : png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf));
1210 : #endif
1211 :
1212 4 : error_fn = png_ptr->error_fn;
1213 : #ifdef PNG_WARNINGS_SUPPORTED
1214 : warning_fn = png_ptr->warning_fn;
1215 : #endif
1216 4 : error_ptr = png_ptr->error_ptr;
1217 : #ifdef PNG_USER_MEM_SUPPORTED
1218 : free_fn = png_ptr->free_fn;
1219 : #endif
1220 :
1221 4 : png_memset(png_ptr, 0, png_sizeof(png_struct));
1222 :
1223 4 : png_ptr->error_fn = error_fn;
1224 : #ifdef PNG_WARNINGS_SUPPORTED
1225 : png_ptr->warning_fn = warning_fn;
1226 : #endif
1227 4 : png_ptr->error_ptr = error_ptr;
1228 : #ifdef PNG_USER_MEM_SUPPORTED
1229 : png_ptr->free_fn = free_fn;
1230 : #endif
1231 :
1232 : #ifdef PNG_SETJMP_SUPPORTED
1233 4 : png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf));
1234 : #endif
1235 :
1236 4 : }
1237 :
1238 : void PNGAPI
1239 0 : png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
1240 : {
1241 0 : if (png_ptr == NULL)
1242 0 : return;
1243 :
1244 0 : png_ptr->read_row_fn = read_row_fn;
1245 : }
1246 :
1247 :
1248 : #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
1249 : #ifdef PNG_INFO_IMAGE_SUPPORTED
1250 : void PNGAPI
1251 : png_read_png(png_structp png_ptr, png_infop info_ptr,
1252 : int transforms,
1253 : voidp params)
1254 : {
1255 : int row;
1256 :
1257 : if (png_ptr == NULL || info_ptr == NULL)
1258 : return;
1259 :
1260 : /* png_read_info() gives us all of the information from the
1261 : * PNG file before the first IDAT (image data chunk).
1262 : */
1263 : png_read_info(png_ptr, info_ptr);
1264 : if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
1265 : png_error(png_ptr, "Image is too high to process with png_read_png()");
1266 :
1267 : /* -------------- image transformations start here ------------------- */
1268 :
1269 : #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
1270 : /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
1271 : */
1272 : if (transforms & PNG_TRANSFORM_SCALE_16)
1273 : {
1274 : /* Added at libpng-1.5.4. "strip_16" produces the same result that it
1275 : * did in earlier versions, while "scale_16" is now more accurate.
1276 : */
1277 : png_set_scale_16(png_ptr);
1278 : }
1279 : #endif
1280 :
1281 : #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
1282 : /* If both SCALE and STRIP are required pngrtran will effectively cancel the
1283 : * latter by doing SCALE first. This is ok and allows apps not to check for
1284 : * which is supported to get the right answer.
1285 : */
1286 : if (transforms & PNG_TRANSFORM_STRIP_16)
1287 : png_set_strip_16(png_ptr);
1288 : #endif
1289 :
1290 : #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
1291 : /* Strip alpha bytes from the input data without combining with
1292 : * the background (not recommended).
1293 : */
1294 : if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
1295 : png_set_strip_alpha(png_ptr);
1296 : #endif
1297 :
1298 : #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
1299 : /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
1300 : * byte into separate bytes (useful for paletted and grayscale images).
1301 : */
1302 : if (transforms & PNG_TRANSFORM_PACKING)
1303 : png_set_packing(png_ptr);
1304 : #endif
1305 :
1306 : #ifdef PNG_READ_PACKSWAP_SUPPORTED
1307 : /* Change the order of packed pixels to least significant bit first
1308 : * (not useful if you are using png_set_packing).
1309 : */
1310 : if (transforms & PNG_TRANSFORM_PACKSWAP)
1311 : png_set_packswap(png_ptr);
1312 : #endif
1313 :
1314 : #ifdef PNG_READ_EXPAND_SUPPORTED
1315 : /* Expand paletted colors into true RGB triplets
1316 : * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
1317 : * Expand paletted or RGB images with transparency to full alpha
1318 : * channels so the data will be available as RGBA quartets.
1319 : */
1320 : if (transforms & PNG_TRANSFORM_EXPAND)
1321 : if ((png_ptr->bit_depth < 8) ||
1322 : (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
1323 : (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
1324 : png_set_expand(png_ptr);
1325 : #endif
1326 :
1327 : /* We don't handle background color or gamma transformation or quantizing.
1328 : */
1329 :
1330 : #ifdef PNG_READ_INVERT_SUPPORTED
1331 : /* Invert monochrome files to have 0 as white and 1 as black
1332 : */
1333 : if (transforms & PNG_TRANSFORM_INVERT_MONO)
1334 : png_set_invert_mono(png_ptr);
1335 : #endif
1336 :
1337 : #ifdef PNG_READ_SHIFT_SUPPORTED
1338 : /* If you want to shift the pixel values from the range [0,255] or
1339 : * [0,65535] to the original [0,7] or [0,31], or whatever range the
1340 : * colors were originally in:
1341 : */
1342 : if ((transforms & PNG_TRANSFORM_SHIFT)
1343 : && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
1344 : {
1345 : png_color_8p sig_bit;
1346 :
1347 : png_get_sBIT(png_ptr, info_ptr, &sig_bit);
1348 : png_set_shift(png_ptr, sig_bit);
1349 : }
1350 : #endif
1351 :
1352 : #ifdef PNG_READ_BGR_SUPPORTED
1353 : /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
1354 : if (transforms & PNG_TRANSFORM_BGR)
1355 : png_set_bgr(png_ptr);
1356 : #endif
1357 :
1358 : #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
1359 : /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
1360 : if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
1361 : png_set_swap_alpha(png_ptr);
1362 : #endif
1363 :
1364 : #ifdef PNG_READ_SWAP_SUPPORTED
1365 : /* Swap bytes of 16-bit files to least significant byte first */
1366 : if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
1367 : png_set_swap(png_ptr);
1368 : #endif
1369 :
1370 : /* Added at libpng-1.2.41 */
1371 : #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
1372 : /* Invert the alpha channel from opacity to transparency */
1373 : if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
1374 : png_set_invert_alpha(png_ptr);
1375 : #endif
1376 :
1377 : /* Added at libpng-1.2.41 */
1378 : #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
1379 : /* Expand grayscale image to RGB */
1380 : if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
1381 : png_set_gray_to_rgb(png_ptr);
1382 : #endif
1383 :
1384 : /* Added at libpng-1.5.4 */
1385 : #ifdef PNG_READ_EXPAND_16_SUPPORTED
1386 : if (transforms & PNG_TRANSFORM_EXPAND_16)
1387 : png_set_expand_16(png_ptr);
1388 : #endif
1389 :
1390 : /* We don't handle adding filler bytes */
1391 :
1392 : /* We use png_read_image and rely on that for interlace handling, but we also
1393 : * call png_read_update_info therefore must turn on interlace handling now:
1394 : */
1395 : (void)png_set_interlace_handling(png_ptr);
1396 :
1397 : /* Optional call to gamma correct and add the background to the palette
1398 : * and update info structure. REQUIRED if you are expecting libpng to
1399 : * update the palette for you (i.e., you selected such a transform above).
1400 : */
1401 : png_read_update_info(png_ptr, info_ptr);
1402 :
1403 : /* -------------- image transformations end here ------------------- */
1404 :
1405 : png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
1406 : if (info_ptr->row_pointers == NULL)
1407 : {
1408 : png_uint_32 iptr;
1409 :
1410 : info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
1411 : info_ptr->height * png_sizeof(png_bytep));
1412 : for (iptr=0; iptr<info_ptr->height; iptr++)
1413 : info_ptr->row_pointers[iptr] = NULL;
1414 :
1415 : info_ptr->free_me |= PNG_FREE_ROWS;
1416 :
1417 : for (row = 0; row < (int)info_ptr->height; row++)
1418 : info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
1419 : png_get_rowbytes(png_ptr, info_ptr));
1420 : }
1421 :
1422 : png_read_image(png_ptr, info_ptr->row_pointers);
1423 : info_ptr->valid |= PNG_INFO_IDAT;
1424 :
1425 : /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
1426 : png_read_end(png_ptr, info_ptr);
1427 :
1428 : PNG_UNUSED(transforms) /* Quiet compiler warnings */
1429 : PNG_UNUSED(params)
1430 :
1431 : }
1432 : #endif /* PNG_INFO_IMAGE_SUPPORTED */
1433 : #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
1434 : #endif /* PNG_READ_SUPPORTED */
|