diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/libpng/pngread.c')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/libpng/pngread.c | 1308 |
1 files changed, 0 insertions, 1308 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngread.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngread.c deleted file mode 100644 index 0643754..0000000 --- a/libraries/irrlicht-1.8/source/Irrlicht/libpng/pngread.c +++ /dev/null | |||
@@ -1,1308 +0,0 @@ | |||
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 | 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 | 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 | png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); | ||
61 | #endif | ||
62 | if (png_ptr == NULL) | ||
63 | 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 | if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ | ||
90 | #endif | ||
91 | 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 | 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 | if (!png_user_version_check(png_ptr, user_png_ver)) | ||
105 | png_cleanup_needed = 1; | ||
106 | |||
107 | if (!png_cleanup_needed) | ||
108 | { | ||
109 | /* Initialize zbuf - compression buffer */ | ||
110 | png_ptr->zbuf_size = PNG_ZBUF_SIZE; | ||
111 | png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); | ||
112 | |||
113 | if (png_ptr->zbuf == NULL) | ||
114 | png_cleanup_needed = 1; | ||
115 | } | ||
116 | |||
117 | png_ptr->zstream.zalloc = png_zalloc; | ||
118 | png_ptr->zstream.zfree = png_zfree; | ||
119 | png_ptr->zstream.opaque = (voidpf)png_ptr; | ||
120 | |||
121 | if (!png_cleanup_needed) | ||
122 | { | ||
123 | switch (inflateInit(&png_ptr->zstream)) | ||
124 | { | ||
125 | case Z_OK: | ||
126 | break; /* Do nothing */ | ||
127 | |||
128 | case Z_MEM_ERROR: | ||
129 | png_warning(png_ptr, "zlib memory error"); | ||
130 | png_cleanup_needed = 1; | ||
131 | break; | ||
132 | |||
133 | case Z_STREAM_ERROR: | ||
134 | png_warning(png_ptr, "zlib stream error"); | ||
135 | png_cleanup_needed = 1; | ||
136 | break; | ||
137 | |||
138 | case Z_VERSION_ERROR: | ||
139 | png_warning(png_ptr, "zlib version error"); | ||
140 | png_cleanup_needed = 1; | ||
141 | break; | ||
142 | |||
143 | default: png_warning(png_ptr, "Unknown zlib error"); | ||
144 | png_cleanup_needed = 1; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | if (png_cleanup_needed) | ||
149 | { | ||
150 | /* Clean up PNG structure and deallocate any memory. */ | ||
151 | png_free(png_ptr, png_ptr->zbuf); | ||
152 | 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 | png_destroy_struct((png_voidp)png_ptr); | ||
158 | #endif | ||
159 | return (NULL); | ||
160 | } | ||
161 | |||
162 | png_ptr->zstream.next_out = png_ptr->zbuf; | ||
163 | png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; | ||
164 | |||
165 | png_set_read_fn(png_ptr, NULL, NULL); | ||
166 | |||
167 | |||
168 | 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 | png_ptr->idat_size = length; | ||
248 | png_ptr->mode |= PNG_HAVE_IDAT; | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | #ifdef PNG_READ_bKGD_SUPPORTED | ||
253 | else if (chunk_name == png_bKGD) | ||
254 | png_handle_bKGD(png_ptr, info_ptr, length); | ||
255 | #endif | ||
256 | |||
257 | #ifdef PNG_READ_cHRM_SUPPORTED | ||
258 | else if (chunk_name == png_cHRM) | ||
259 | png_handle_cHRM(png_ptr, info_ptr, length); | ||
260 | #endif | ||
261 | |||
262 | #ifdef PNG_READ_gAMA_SUPPORTED | ||
263 | else if (chunk_name == png_gAMA) | ||
264 | png_handle_gAMA(png_ptr, info_ptr, length); | ||
265 | #endif | ||
266 | |||
267 | #ifdef PNG_READ_hIST_SUPPORTED | ||
268 | else if (chunk_name == png_hIST) | ||
269 | png_handle_hIST(png_ptr, info_ptr, length); | ||
270 | #endif | ||
271 | |||
272 | #ifdef PNG_READ_oFFs_SUPPORTED | ||
273 | else if (chunk_name == png_oFFs) | ||
274 | png_handle_oFFs(png_ptr, info_ptr, length); | ||
275 | #endif | ||
276 | |||
277 | #ifdef PNG_READ_pCAL_SUPPORTED | ||
278 | else if (chunk_name == png_pCAL) | ||
279 | png_handle_pCAL(png_ptr, info_ptr, length); | ||
280 | #endif | ||
281 | |||
282 | #ifdef PNG_READ_sCAL_SUPPORTED | ||
283 | else if (chunk_name == png_sCAL) | ||
284 | png_handle_sCAL(png_ptr, info_ptr, length); | ||
285 | #endif | ||
286 | |||
287 | #ifdef PNG_READ_pHYs_SUPPORTED | ||
288 | else if (chunk_name == png_pHYs) | ||
289 | png_handle_pHYs(png_ptr, info_ptr, length); | ||
290 | #endif | ||
291 | |||
292 | #ifdef PNG_READ_sBIT_SUPPORTED | ||
293 | else if (chunk_name == png_sBIT) | ||
294 | png_handle_sBIT(png_ptr, info_ptr, length); | ||
295 | #endif | ||
296 | |||
297 | #ifdef PNG_READ_sRGB_SUPPORTED | ||
298 | else if (chunk_name == png_sRGB) | ||
299 | png_handle_sRGB(png_ptr, info_ptr, length); | ||
300 | #endif | ||
301 | |||
302 | #ifdef PNG_READ_iCCP_SUPPORTED | ||
303 | else if (chunk_name == png_iCCP) | ||
304 | png_handle_iCCP(png_ptr, info_ptr, length); | ||
305 | #endif | ||
306 | |||
307 | #ifdef PNG_READ_sPLT_SUPPORTED | ||
308 | else if (chunk_name == png_sPLT) | ||
309 | png_handle_sPLT(png_ptr, info_ptr, length); | ||
310 | #endif | ||
311 | |||
312 | #ifdef PNG_READ_tEXt_SUPPORTED | ||
313 | else if (chunk_name == png_tEXt) | ||
314 | png_handle_tEXt(png_ptr, info_ptr, length); | ||
315 | #endif | ||
316 | |||
317 | #ifdef PNG_READ_tIME_SUPPORTED | ||
318 | else if (chunk_name == png_tIME) | ||
319 | png_handle_tIME(png_ptr, info_ptr, length); | ||
320 | #endif | ||
321 | |||
322 | #ifdef PNG_READ_tRNS_SUPPORTED | ||
323 | else if (chunk_name == png_tRNS) | ||
324 | png_handle_tRNS(png_ptr, info_ptr, length); | ||
325 | #endif | ||
326 | |||
327 | #ifdef PNG_READ_zTXt_SUPPORTED | ||
328 | else if (chunk_name == png_zTXt) | ||
329 | png_handle_zTXt(png_ptr, info_ptr, length); | ||
330 | #endif | ||
331 | |||
332 | #ifdef PNG_READ_iTXt_SUPPORTED | ||
333 | else if (chunk_name == png_iTXt) | ||
334 | png_handle_iTXt(png_ptr, info_ptr, length); | ||
335 | #endif | ||
336 | |||
337 | else | ||
338 | png_handle_unknown(png_ptr, info_ptr, length); | ||
339 | } | ||
340 | } | ||
341 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
342 | |||
343 | /* Optional call to update the users info_ptr structure */ | ||
344 | void PNGAPI | ||
345 | png_read_update_info(png_structp png_ptr, png_infop info_ptr) | ||
346 | { | ||
347 | png_debug(1, "in png_read_update_info"); | ||
348 | |||
349 | if (png_ptr == NULL) | ||
350 | return; | ||
351 | |||
352 | png_read_start_row(png_ptr); | ||
353 | |||
354 | #ifdef PNG_READ_TRANSFORMS_SUPPORTED | ||
355 | png_read_transform_info(png_ptr, info_ptr); | ||
356 | #else | ||
357 | PNG_UNUSED(info_ptr) | ||
358 | #endif | ||
359 | } | ||
360 | |||
361 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
362 | /* Initialize palette, background, etc, after transformations | ||
363 | * are set, but before any reading takes place. This allows | ||
364 | * the user to obtain a gamma-corrected palette, for example. | ||
365 | * If the user doesn't call this, we will do it ourselves. | ||
366 | */ | ||
367 | void PNGAPI | ||
368 | png_start_read_image(png_structp png_ptr) | ||
369 | { | ||
370 | png_debug(1, "in png_start_read_image"); | ||
371 | |||
372 | if (png_ptr != NULL) | ||
373 | png_read_start_row(png_ptr); | ||
374 | } | ||
375 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
376 | |||
377 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
378 | void PNGAPI | ||
379 | png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) | ||
380 | { | ||
381 | int ret; | ||
382 | |||
383 | png_row_info row_info; | ||
384 | |||
385 | if (png_ptr == NULL) | ||
386 | return; | ||
387 | |||
388 | png_debug2(1, "in png_read_row (row %lu, pass %d)", | ||
389 | (unsigned long)png_ptr->row_number, png_ptr->pass); | ||
390 | |||
391 | /* png_read_start_row sets the information (in particular iwidth) for this | ||
392 | * interlace pass. | ||
393 | */ | ||
394 | if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) | ||
395 | png_read_start_row(png_ptr); | ||
396 | |||
397 | /* 1.5.6: row_info moved out of png_struct to a local here. */ | ||
398 | row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ | ||
399 | row_info.color_type = png_ptr->color_type; | ||
400 | row_info.bit_depth = png_ptr->bit_depth; | ||
401 | row_info.channels = png_ptr->channels; | ||
402 | row_info.pixel_depth = png_ptr->pixel_depth; | ||
403 | row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); | ||
404 | |||
405 | if (png_ptr->row_number == 0 && png_ptr->pass == 0) | ||
406 | { | ||
407 | /* Check for transforms that have been set but were defined out */ | ||
408 | #if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) | ||
409 | if (png_ptr->transformations & PNG_INVERT_MONO) | ||
410 | png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); | ||
411 | #endif | ||
412 | |||
413 | #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) | ||
414 | if (png_ptr->transformations & PNG_FILLER) | ||
415 | png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); | ||
416 | #endif | ||
417 | |||
418 | #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ | ||
419 | !defined(PNG_READ_PACKSWAP_SUPPORTED) | ||
420 | if (png_ptr->transformations & PNG_PACKSWAP) | ||
421 | png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); | ||
422 | #endif | ||
423 | |||
424 | #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) | ||
425 | if (png_ptr->transformations & PNG_PACK) | ||
426 | png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); | ||
427 | #endif | ||
428 | |||
429 | #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) | ||
430 | if (png_ptr->transformations & PNG_SHIFT) | ||
431 | png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); | ||
432 | #endif | ||
433 | |||
434 | #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) | ||
435 | if (png_ptr->transformations & PNG_BGR) | ||
436 | png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); | ||
437 | #endif | ||
438 | |||
439 | #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) | ||
440 | if (png_ptr->transformations & PNG_SWAP_BYTES) | ||
441 | png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); | ||
442 | #endif | ||
443 | } | ||
444 | |||
445 | #ifdef PNG_READ_INTERLACING_SUPPORTED | ||
446 | /* If interlaced and we do not need a new row, combine row and return. | ||
447 | * Notice that the pixels we have from previous rows have been transformed | ||
448 | * already; we can only combine like with like (transformed or | ||
449 | * untransformed) and, because of the libpng API for interlaced images, this | ||
450 | * means we must transform before de-interlacing. | ||
451 | */ | ||
452 | if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) | ||
453 | { | ||
454 | switch (png_ptr->pass) | ||
455 | { | ||
456 | case 0: | ||
457 | if (png_ptr->row_number & 0x07) | ||
458 | { | ||
459 | if (dsp_row != NULL) | ||
460 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
461 | png_read_finish_row(png_ptr); | ||
462 | return; | ||
463 | } | ||
464 | break; | ||
465 | |||
466 | case 1: | ||
467 | if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) | ||
468 | { | ||
469 | if (dsp_row != NULL) | ||
470 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
471 | |||
472 | png_read_finish_row(png_ptr); | ||
473 | return; | ||
474 | } | ||
475 | break; | ||
476 | |||
477 | case 2: | ||
478 | if ((png_ptr->row_number & 0x07) != 4) | ||
479 | { | ||
480 | if (dsp_row != NULL && (png_ptr->row_number & 4)) | ||
481 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
482 | |||
483 | png_read_finish_row(png_ptr); | ||
484 | return; | ||
485 | } | ||
486 | break; | ||
487 | |||
488 | case 3: | ||
489 | if ((png_ptr->row_number & 3) || png_ptr->width < 3) | ||
490 | { | ||
491 | if (dsp_row != NULL) | ||
492 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
493 | |||
494 | png_read_finish_row(png_ptr); | ||
495 | return; | ||
496 | } | ||
497 | break; | ||
498 | |||
499 | case 4: | ||
500 | if ((png_ptr->row_number & 3) != 2) | ||
501 | { | ||
502 | if (dsp_row != NULL && (png_ptr->row_number & 2)) | ||
503 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
504 | |||
505 | png_read_finish_row(png_ptr); | ||
506 | return; | ||
507 | } | ||
508 | break; | ||
509 | case 5: | ||
510 | if ((png_ptr->row_number & 1) || png_ptr->width < 2) | ||
511 | { | ||
512 | if (dsp_row != NULL) | ||
513 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
514 | |||
515 | png_read_finish_row(png_ptr); | ||
516 | return; | ||
517 | } | ||
518 | break; | ||
519 | |||
520 | default: | ||
521 | case 6: | ||
522 | if (!(png_ptr->row_number & 1)) | ||
523 | { | ||
524 | png_read_finish_row(png_ptr); | ||
525 | return; | ||
526 | } | ||
527 | break; | ||
528 | } | ||
529 | } | ||
530 | #endif | ||
531 | |||
532 | if (!(png_ptr->mode & PNG_HAVE_IDAT)) | ||
533 | png_error(png_ptr, "Invalid attempt to read row data"); | ||
534 | |||
535 | png_ptr->zstream.next_out = png_ptr->row_buf; | ||
536 | png_ptr->zstream.avail_out = | ||
537 | (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, | ||
538 | png_ptr->iwidth) + 1); | ||
539 | |||
540 | do | ||
541 | { | ||
542 | if (!(png_ptr->zstream.avail_in)) | ||
543 | { | ||
544 | while (!png_ptr->idat_size) | ||
545 | { | ||
546 | png_crc_finish(png_ptr, 0); | ||
547 | |||
548 | png_ptr->idat_size = png_read_chunk_header(png_ptr); | ||
549 | if (png_ptr->chunk_name != png_IDAT) | ||
550 | png_error(png_ptr, "Not enough image data"); | ||
551 | } | ||
552 | png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; | ||
553 | png_ptr->zstream.next_in = png_ptr->zbuf; | ||
554 | if (png_ptr->zbuf_size > png_ptr->idat_size) | ||
555 | png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; | ||
556 | png_crc_read(png_ptr, png_ptr->zbuf, | ||
557 | (png_size_t)png_ptr->zstream.avail_in); | ||
558 | png_ptr->idat_size -= png_ptr->zstream.avail_in; | ||
559 | } | ||
560 | |||
561 | ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); | ||
562 | |||
563 | if (ret == Z_STREAM_END) | ||
564 | { | ||
565 | if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || | ||
566 | png_ptr->idat_size) | ||
567 | png_benign_error(png_ptr, "Extra compressed data"); | ||
568 | png_ptr->mode |= PNG_AFTER_IDAT; | ||
569 | png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | if (ret != Z_OK) | ||
574 | png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : | ||
575 | "Decompression error"); | ||
576 | |||
577 | } while (png_ptr->zstream.avail_out); | ||
578 | |||
579 | if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) | ||
580 | { | ||
581 | if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) | ||
582 | png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, | ||
583 | png_ptr->prev_row + 1, png_ptr->row_buf[0]); | ||
584 | else | ||
585 | png_error(png_ptr, "bad adaptive filter value"); | ||
586 | } | ||
587 | |||
588 | /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before | ||
589 | * 1.5.6, while the buffer really is this big in current versions of libpng | ||
590 | * it may not be in the future, so this was changed just to copy the | ||
591 | * interlaced count: | ||
592 | */ | ||
593 | png_memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); | ||
594 | |||
595 | #ifdef PNG_MNG_FEATURES_SUPPORTED | ||
596 | if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && | ||
597 | (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) | ||
598 | { | ||
599 | /* Intrapixel differencing */ | ||
600 | png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); | ||
601 | } | ||
602 | #endif | ||
603 | |||
604 | |||
605 | #ifdef PNG_READ_TRANSFORMS_SUPPORTED | ||
606 | if (png_ptr->transformations) | ||
607 | png_do_read_transformations(png_ptr, &row_info); | ||
608 | #endif | ||
609 | |||
610 | /* The transformed pixel depth should match the depth now in row_info. */ | ||
611 | if (png_ptr->transformed_pixel_depth == 0) | ||
612 | { | ||
613 | png_ptr->transformed_pixel_depth = row_info.pixel_depth; | ||
614 | if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) | ||
615 | png_error(png_ptr, "sequential row overflow"); | ||
616 | } | ||
617 | |||
618 | else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) | ||
619 | png_error(png_ptr, "internal sequential row size calculation error"); | ||
620 | |||
621 | #ifdef PNG_READ_INTERLACING_SUPPORTED | ||
622 | /* Blow up interlaced rows to full size */ | ||
623 | if (png_ptr->interlaced && | ||
624 | (png_ptr->transformations & PNG_INTERLACE)) | ||
625 | { | ||
626 | if (png_ptr->pass < 6) | ||
627 | png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, | ||
628 | png_ptr->transformations); | ||
629 | |||
630 | if (dsp_row != NULL) | ||
631 | png_combine_row(png_ptr, dsp_row, 1/*display*/); | ||
632 | |||
633 | if (row != NULL) | ||
634 | png_combine_row(png_ptr, row, 0/*row*/); | ||
635 | } | ||
636 | |||
637 | else | ||
638 | #endif | ||
639 | { | ||
640 | if (row != NULL) | ||
641 | png_combine_row(png_ptr, row, -1/*ignored*/); | ||
642 | |||
643 | if (dsp_row != NULL) | ||
644 | png_combine_row(png_ptr, dsp_row, -1/*ignored*/); | ||
645 | } | ||
646 | png_read_finish_row(png_ptr); | ||
647 | |||
648 | if (png_ptr->read_row_fn != NULL) | ||
649 | (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); | ||
650 | } | ||
651 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
652 | |||
653 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
654 | /* Read one or more rows of image data. If the image is interlaced, | ||
655 | * and png_set_interlace_handling() has been called, the rows need to | ||
656 | * contain the contents of the rows from the previous pass. If the | ||
657 | * image has alpha or transparency, and png_handle_alpha()[*] has been | ||
658 | * called, the rows contents must be initialized to the contents of the | ||
659 | * screen. | ||
660 | * | ||
661 | * "row" holds the actual image, and pixels are placed in it | ||
662 | * as they arrive. If the image is displayed after each pass, it will | ||
663 | * appear to "sparkle" in. "display_row" can be used to display a | ||
664 | * "chunky" progressive image, with finer detail added as it becomes | ||
665 | * available. If you do not want this "chunky" display, you may pass | ||
666 | * NULL for display_row. If you do not want the sparkle display, and | ||
667 | * you have not called png_handle_alpha(), you may pass NULL for rows. | ||
668 | * If you have called png_handle_alpha(), and the image has either an | ||
669 | * alpha channel or a transparency chunk, you must provide a buffer for | ||
670 | * rows. In this case, you do not have to provide a display_row buffer | ||
671 | * also, but you may. If the image is not interlaced, or if you have | ||
672 | * not called png_set_interlace_handling(), the display_row buffer will | ||
673 | * be ignored, so pass NULL to it. | ||
674 | * | ||
675 | * [*] png_handle_alpha() does not exist yet, as of this version of libpng | ||
676 | */ | ||
677 | |||
678 | void PNGAPI | ||
679 | png_read_rows(png_structp png_ptr, png_bytepp row, | ||
680 | png_bytepp display_row, png_uint_32 num_rows) | ||
681 | { | ||
682 | png_uint_32 i; | ||
683 | png_bytepp rp; | ||
684 | png_bytepp dp; | ||
685 | |||
686 | png_debug(1, "in png_read_rows"); | ||
687 | |||
688 | if (png_ptr == NULL) | ||
689 | return; | ||
690 | |||
691 | rp = row; | ||
692 | dp = display_row; | ||
693 | if (rp != NULL && dp != NULL) | ||
694 | for (i = 0; i < num_rows; i++) | ||
695 | { | ||
696 | png_bytep rptr = *rp++; | ||
697 | png_bytep dptr = *dp++; | ||
698 | |||
699 | png_read_row(png_ptr, rptr, dptr); | ||
700 | } | ||
701 | |||
702 | else if (rp != NULL) | ||
703 | for (i = 0; i < num_rows; i++) | ||
704 | { | ||
705 | png_bytep rptr = *rp; | ||
706 | png_read_row(png_ptr, rptr, NULL); | ||
707 | rp++; | ||
708 | } | ||
709 | |||
710 | else if (dp != NULL) | ||
711 | for (i = 0; i < num_rows; i++) | ||
712 | { | ||
713 | png_bytep dptr = *dp; | ||
714 | png_read_row(png_ptr, NULL, dptr); | ||
715 | dp++; | ||
716 | } | ||
717 | } | ||
718 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
719 | |||
720 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
721 | /* Read the entire image. If the image has an alpha channel or a tRNS | ||
722 | * chunk, and you have called png_handle_alpha()[*], you will need to | ||
723 | * initialize the image to the current image that PNG will be overlaying. | ||
724 | * We set the num_rows again here, in case it was incorrectly set in | ||
725 | * png_read_start_row() by a call to png_read_update_info() or | ||
726 | * png_start_read_image() if png_set_interlace_handling() wasn't called | ||
727 | * prior to either of these functions like it should have been. You can | ||
728 | * only call this function once. If you desire to have an image for | ||
729 | * each pass of a interlaced image, use png_read_rows() instead. | ||
730 | * | ||
731 | * [*] png_handle_alpha() does not exist yet, as of this version of libpng | ||
732 | */ | ||
733 | void PNGAPI | ||
734 | png_read_image(png_structp png_ptr, png_bytepp image) | ||
735 | { | ||
736 | png_uint_32 i, image_height; | ||
737 | int pass, j; | ||
738 | png_bytepp rp; | ||
739 | |||
740 | png_debug(1, "in png_read_image"); | ||
741 | |||
742 | if (png_ptr == NULL) | ||
743 | return; | ||
744 | |||
745 | #ifdef PNG_READ_INTERLACING_SUPPORTED | ||
746 | if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) | ||
747 | { | ||
748 | pass = png_set_interlace_handling(png_ptr); | ||
749 | /* And make sure transforms are initialized. */ | ||
750 | png_start_read_image(png_ptr); | ||
751 | } | ||
752 | else | ||
753 | { | ||
754 | if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) | ||
755 | { | ||
756 | /* Caller called png_start_read_image or png_read_update_info without | ||
757 | * first turning on the PNG_INTERLACE transform. We can fix this here, | ||
758 | * but the caller should do it! | ||
759 | */ | ||
760 | png_warning(png_ptr, "Interlace handling should be turned on when " | ||
761 | "using png_read_image"); | ||
762 | /* Make sure this is set correctly */ | ||
763 | png_ptr->num_rows = png_ptr->height; | ||
764 | } | ||
765 | |||
766 | /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in | ||
767 | * the above error case. | ||
768 | */ | ||
769 | pass = png_set_interlace_handling(png_ptr); | ||
770 | } | ||
771 | #else | ||
772 | if (png_ptr->interlaced) | ||
773 | png_error(png_ptr, | ||
774 | "Cannot read interlaced image -- interlace handler disabled"); | ||
775 | |||
776 | pass = 1; | ||
777 | #endif | ||
778 | |||
779 | image_height=png_ptr->height; | ||
780 | |||
781 | for (j = 0; j < pass; j++) | ||
782 | { | ||
783 | rp = image; | ||
784 | for (i = 0; i < image_height; i++) | ||
785 | { | ||
786 | png_read_row(png_ptr, *rp, NULL); | ||
787 | rp++; | ||
788 | } | ||
789 | } | ||
790 | } | ||
791 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
792 | |||
793 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
794 | /* Read the end of the PNG file. Will not read past the end of the | ||
795 | * file, will verify the end is accurate, and will read any comments | ||
796 | * or time information at the end of the file, if info is not NULL. | ||
797 | */ | ||
798 | void PNGAPI | ||
799 | png_read_end(png_structp png_ptr, png_infop info_ptr) | ||
800 | { | ||
801 | png_debug(1, "in png_read_end"); | ||
802 | |||
803 | if (png_ptr == NULL) | ||
804 | return; | ||
805 | |||
806 | png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ | ||
807 | |||
808 | do | ||
809 | { | ||
810 | png_uint_32 length = png_read_chunk_header(png_ptr); | ||
811 | png_uint_32 chunk_name = png_ptr->chunk_name; | ||
812 | |||
813 | if (chunk_name == png_IHDR) | ||
814 | png_handle_IHDR(png_ptr, info_ptr, length); | ||
815 | |||
816 | else if (chunk_name == png_IEND) | ||
817 | png_handle_IEND(png_ptr, info_ptr, length); | ||
818 | |||
819 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED | ||
820 | else if (png_chunk_unknown_handling(png_ptr, chunk_name) != | ||
821 | PNG_HANDLE_CHUNK_AS_DEFAULT) | ||
822 | { | ||
823 | if (chunk_name == png_IDAT) | ||
824 | { | ||
825 | if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) | ||
826 | png_benign_error(png_ptr, "Too many IDATs found"); | ||
827 | } | ||
828 | png_handle_unknown(png_ptr, info_ptr, length); | ||
829 | if (chunk_name == png_PLTE) | ||
830 | png_ptr->mode |= PNG_HAVE_PLTE; | ||
831 | } | ||
832 | #endif | ||
833 | |||
834 | else if (chunk_name == png_IDAT) | ||
835 | { | ||
836 | /* Zero length IDATs are legal after the last IDAT has been | ||
837 | * read, but not after other chunks have been read. | ||
838 | */ | ||
839 | if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) | ||
840 | png_benign_error(png_ptr, "Too many IDATs found"); | ||
841 | |||
842 | png_crc_finish(png_ptr, length); | ||
843 | } | ||
844 | else if (chunk_name == png_PLTE) | ||
845 | png_handle_PLTE(png_ptr, info_ptr, length); | ||
846 | |||
847 | #ifdef PNG_READ_bKGD_SUPPORTED | ||
848 | else if (chunk_name == png_bKGD) | ||
849 | png_handle_bKGD(png_ptr, info_ptr, length); | ||
850 | #endif | ||
851 | |||
852 | #ifdef PNG_READ_cHRM_SUPPORTED | ||
853 | else if (chunk_name == png_cHRM) | ||
854 | png_handle_cHRM(png_ptr, info_ptr, length); | ||
855 | #endif | ||
856 | |||
857 | #ifdef PNG_READ_gAMA_SUPPORTED | ||
858 | else if (chunk_name == png_gAMA) | ||
859 | png_handle_gAMA(png_ptr, info_ptr, length); | ||
860 | #endif | ||
861 | |||
862 | #ifdef PNG_READ_hIST_SUPPORTED | ||
863 | else if (chunk_name == png_hIST) | ||
864 | png_handle_hIST(png_ptr, info_ptr, length); | ||
865 | #endif | ||
866 | |||
867 | #ifdef PNG_READ_oFFs_SUPPORTED | ||
868 | else if (chunk_name == png_oFFs) | ||
869 | png_handle_oFFs(png_ptr, info_ptr, length); | ||
870 | #endif | ||
871 | |||
872 | #ifdef PNG_READ_pCAL_SUPPORTED | ||
873 | else if (chunk_name == png_pCAL) | ||
874 | png_handle_pCAL(png_ptr, info_ptr, length); | ||
875 | #endif | ||
876 | |||
877 | #ifdef PNG_READ_sCAL_SUPPORTED | ||
878 | else if (chunk_name == png_sCAL) | ||
879 | png_handle_sCAL(png_ptr, info_ptr, length); | ||
880 | #endif | ||
881 | |||
882 | #ifdef PNG_READ_pHYs_SUPPORTED | ||
883 | else if (chunk_name == png_pHYs) | ||
884 | png_handle_pHYs(png_ptr, info_ptr, length); | ||
885 | #endif | ||
886 | |||
887 | #ifdef PNG_READ_sBIT_SUPPORTED | ||
888 | else if (chunk_name == png_sBIT) | ||
889 | png_handle_sBIT(png_ptr, info_ptr, length); | ||
890 | #endif | ||
891 | |||
892 | #ifdef PNG_READ_sRGB_SUPPORTED | ||
893 | else if (chunk_name == png_sRGB) | ||
894 | png_handle_sRGB(png_ptr, info_ptr, length); | ||
895 | #endif | ||
896 | |||
897 | #ifdef PNG_READ_iCCP_SUPPORTED | ||
898 | else if (chunk_name == png_iCCP) | ||
899 | png_handle_iCCP(png_ptr, info_ptr, length); | ||
900 | #endif | ||
901 | |||
902 | #ifdef PNG_READ_sPLT_SUPPORTED | ||
903 | else if (chunk_name == png_sPLT) | ||
904 | png_handle_sPLT(png_ptr, info_ptr, length); | ||
905 | #endif | ||
906 | |||
907 | #ifdef PNG_READ_tEXt_SUPPORTED | ||
908 | else if (chunk_name == png_tEXt) | ||
909 | png_handle_tEXt(png_ptr, info_ptr, length); | ||
910 | #endif | ||
911 | |||
912 | #ifdef PNG_READ_tIME_SUPPORTED | ||
913 | else if (chunk_name == png_tIME) | ||
914 | png_handle_tIME(png_ptr, info_ptr, length); | ||
915 | #endif | ||
916 | |||
917 | #ifdef PNG_READ_tRNS_SUPPORTED | ||
918 | else if (chunk_name == png_tRNS) | ||
919 | png_handle_tRNS(png_ptr, info_ptr, length); | ||
920 | #endif | ||
921 | |||
922 | #ifdef PNG_READ_zTXt_SUPPORTED | ||
923 | else if (chunk_name == png_zTXt) | ||
924 | png_handle_zTXt(png_ptr, info_ptr, length); | ||
925 | #endif | ||
926 | |||
927 | #ifdef PNG_READ_iTXt_SUPPORTED | ||
928 | else if (chunk_name == png_iTXt) | ||
929 | png_handle_iTXt(png_ptr, info_ptr, length); | ||
930 | #endif | ||
931 | |||
932 | else | ||
933 | png_handle_unknown(png_ptr, info_ptr, length); | ||
934 | } while (!(png_ptr->mode & PNG_HAVE_IEND)); | ||
935 | } | ||
936 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
937 | |||
938 | /* Free all memory used by the read */ | ||
939 | void PNGAPI | ||
940 | png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, | ||
941 | png_infopp end_info_ptr_ptr) | ||
942 | { | ||
943 | png_structp png_ptr = NULL; | ||
944 | png_infop info_ptr = NULL, end_info_ptr = NULL; | ||
945 | #ifdef PNG_USER_MEM_SUPPORTED | ||
946 | png_free_ptr free_fn = NULL; | ||
947 | png_voidp mem_ptr = NULL; | ||
948 | #endif | ||
949 | |||
950 | png_debug(1, "in png_destroy_read_struct"); | ||
951 | |||
952 | if (png_ptr_ptr != NULL) | ||
953 | png_ptr = *png_ptr_ptr; | ||
954 | if (png_ptr == NULL) | ||
955 | return; | ||
956 | |||
957 | #ifdef PNG_USER_MEM_SUPPORTED | ||
958 | free_fn = png_ptr->free_fn; | ||
959 | mem_ptr = png_ptr->mem_ptr; | ||
960 | #endif | ||
961 | |||
962 | if (info_ptr_ptr != NULL) | ||
963 | info_ptr = *info_ptr_ptr; | ||
964 | |||
965 | if (end_info_ptr_ptr != NULL) | ||
966 | end_info_ptr = *end_info_ptr_ptr; | ||
967 | |||
968 | png_read_destroy(png_ptr, info_ptr, end_info_ptr); | ||
969 | |||
970 | if (info_ptr != NULL) | ||
971 | { | ||
972 | #ifdef PNG_TEXT_SUPPORTED | ||
973 | png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1); | ||
974 | #endif | ||
975 | |||
976 | #ifdef PNG_USER_MEM_SUPPORTED | ||
977 | png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, | ||
978 | (png_voidp)mem_ptr); | ||
979 | #else | ||
980 | png_destroy_struct((png_voidp)info_ptr); | ||
981 | #endif | ||
982 | *info_ptr_ptr = NULL; | ||
983 | } | ||
984 | |||
985 | if (end_info_ptr != NULL) | ||
986 | { | ||
987 | #ifdef PNG_READ_TEXT_SUPPORTED | ||
988 | png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1); | ||
989 | #endif | ||
990 | #ifdef PNG_USER_MEM_SUPPORTED | ||
991 | png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, | ||
992 | (png_voidp)mem_ptr); | ||
993 | #else | ||
994 | png_destroy_struct((png_voidp)end_info_ptr); | ||
995 | #endif | ||
996 | *end_info_ptr_ptr = NULL; | ||
997 | } | ||
998 | |||
999 | if (png_ptr != NULL) | ||
1000 | { | ||
1001 | #ifdef PNG_USER_MEM_SUPPORTED | ||
1002 | png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, | ||
1003 | (png_voidp)mem_ptr); | ||
1004 | #else | ||
1005 | png_destroy_struct((png_voidp)png_ptr); | ||
1006 | #endif | ||
1007 | *png_ptr_ptr = NULL; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | /* Free all memory used by the read (old method) */ | ||
1012 | void /* PRIVATE */ | ||
1013 | png_read_destroy(png_structp png_ptr, png_infop info_ptr, | ||
1014 | png_infop end_info_ptr) | ||
1015 | { | ||
1016 | #ifdef PNG_SETJMP_SUPPORTED | ||
1017 | jmp_buf tmp_jmp; | ||
1018 | #endif | ||
1019 | png_error_ptr error_fn; | ||
1020 | #ifdef PNG_WARNINGS_SUPPORTED | ||
1021 | png_error_ptr warning_fn; | ||
1022 | #endif | ||
1023 | png_voidp error_ptr; | ||
1024 | #ifdef PNG_USER_MEM_SUPPORTED | ||
1025 | png_free_ptr free_fn; | ||
1026 | #endif | ||
1027 | |||
1028 | png_debug(1, "in png_read_destroy"); | ||
1029 | |||
1030 | if (info_ptr != NULL) | ||
1031 | png_info_destroy(png_ptr, info_ptr); | ||
1032 | |||
1033 | if (end_info_ptr != NULL) | ||
1034 | png_info_destroy(png_ptr, end_info_ptr); | ||
1035 | |||
1036 | #ifdef PNG_READ_GAMMA_SUPPORTED | ||
1037 | png_destroy_gamma_table(png_ptr); | ||
1038 | #endif | ||
1039 | |||
1040 | png_free(png_ptr, png_ptr->zbuf); | ||
1041 | png_free(png_ptr, png_ptr->big_row_buf); | ||
1042 | png_free(png_ptr, png_ptr->big_prev_row); | ||
1043 | png_free(png_ptr, png_ptr->chunkdata); | ||
1044 | |||
1045 | #ifdef PNG_READ_QUANTIZE_SUPPORTED | ||
1046 | png_free(png_ptr, png_ptr->palette_lookup); | ||
1047 | png_free(png_ptr, png_ptr->quantize_index); | ||
1048 | #endif | ||
1049 | |||
1050 | if (png_ptr->free_me & PNG_FREE_PLTE) | ||
1051 | png_zfree(png_ptr, png_ptr->palette); | ||
1052 | png_ptr->free_me &= ~PNG_FREE_PLTE; | ||
1053 | |||
1054 | #if defined(PNG_tRNS_SUPPORTED) || \ | ||
1055 | defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) | ||
1056 | if (png_ptr->free_me & PNG_FREE_TRNS) | ||
1057 | png_free(png_ptr, png_ptr->trans_alpha); | ||
1058 | png_ptr->free_me &= ~PNG_FREE_TRNS; | ||
1059 | #endif | ||
1060 | |||
1061 | #ifdef PNG_READ_hIST_SUPPORTED | ||
1062 | if (png_ptr->free_me & PNG_FREE_HIST) | ||
1063 | png_free(png_ptr, png_ptr->hist); | ||
1064 | png_ptr->free_me &= ~PNG_FREE_HIST; | ||
1065 | #endif | ||
1066 | |||
1067 | inflateEnd(&png_ptr->zstream); | ||
1068 | |||
1069 | #ifdef PNG_PROGRESSIVE_READ_SUPPORTED | ||
1070 | png_free(png_ptr, png_ptr->save_buffer); | ||
1071 | #endif | ||
1072 | |||
1073 | #ifdef PNG_PROGRESSIVE_READ_SUPPORTED | ||
1074 | #ifdef PNG_TEXT_SUPPORTED | ||
1075 | png_free(png_ptr, png_ptr->current_text); | ||
1076 | #endif /* PNG_TEXT_SUPPORTED */ | ||
1077 | #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ | ||
1078 | |||
1079 | /* Save the important info out of the png_struct, in case it is | ||
1080 | * being used again. | ||
1081 | */ | ||
1082 | #ifdef PNG_SETJMP_SUPPORTED | ||
1083 | png_memcpy(tmp_jmp, png_ptr->longjmp_buffer, png_sizeof(jmp_buf)); | ||
1084 | #endif | ||
1085 | |||
1086 | error_fn = png_ptr->error_fn; | ||
1087 | #ifdef PNG_WARNINGS_SUPPORTED | ||
1088 | warning_fn = png_ptr->warning_fn; | ||
1089 | #endif | ||
1090 | error_ptr = png_ptr->error_ptr; | ||
1091 | #ifdef PNG_USER_MEM_SUPPORTED | ||
1092 | free_fn = png_ptr->free_fn; | ||
1093 | #endif | ||
1094 | |||
1095 | png_memset(png_ptr, 0, png_sizeof(png_struct)); | ||
1096 | |||
1097 | png_ptr->error_fn = error_fn; | ||
1098 | #ifdef PNG_WARNINGS_SUPPORTED | ||
1099 | png_ptr->warning_fn = warning_fn; | ||
1100 | #endif | ||
1101 | png_ptr->error_ptr = error_ptr; | ||
1102 | #ifdef PNG_USER_MEM_SUPPORTED | ||
1103 | png_ptr->free_fn = free_fn; | ||
1104 | #endif | ||
1105 | |||
1106 | #ifdef PNG_SETJMP_SUPPORTED | ||
1107 | png_memcpy(png_ptr->longjmp_buffer, tmp_jmp, png_sizeof(jmp_buf)); | ||
1108 | #endif | ||
1109 | |||
1110 | } | ||
1111 | |||
1112 | void PNGAPI | ||
1113 | png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) | ||
1114 | { | ||
1115 | if (png_ptr == NULL) | ||
1116 | return; | ||
1117 | |||
1118 | png_ptr->read_row_fn = read_row_fn; | ||
1119 | } | ||
1120 | |||
1121 | |||
1122 | #ifdef PNG_SEQUENTIAL_READ_SUPPORTED | ||
1123 | #ifdef PNG_INFO_IMAGE_SUPPORTED | ||
1124 | void PNGAPI | ||
1125 | png_read_png(png_structp png_ptr, png_infop info_ptr, | ||
1126 | int transforms, | ||
1127 | voidp params) | ||
1128 | { | ||
1129 | int row; | ||
1130 | |||
1131 | if (png_ptr == NULL || info_ptr == NULL) | ||
1132 | return; | ||
1133 | |||
1134 | /* png_read_info() gives us all of the information from the | ||
1135 | * PNG file before the first IDAT (image data chunk). | ||
1136 | */ | ||
1137 | png_read_info(png_ptr, info_ptr); | ||
1138 | if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) | ||
1139 | png_error(png_ptr, "Image is too high to process with png_read_png()"); | ||
1140 | |||
1141 | /* -------------- image transformations start here ------------------- */ | ||
1142 | |||
1143 | #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED | ||
1144 | /* Tell libpng to strip 16-bit/color files down to 8 bits per color. | ||
1145 | */ | ||
1146 | if (transforms & PNG_TRANSFORM_SCALE_16) | ||
1147 | { | ||
1148 | /* Added at libpng-1.5.4. "strip_16" produces the same result that it | ||
1149 | * did in earlier versions, while "scale_16" is now more accurate. | ||
1150 | */ | ||
1151 | png_set_scale_16(png_ptr); | ||
1152 | } | ||
1153 | #endif | ||
1154 | |||
1155 | #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED | ||
1156 | /* If both SCALE and STRIP are required pngrtran will effectively cancel the | ||
1157 | * latter by doing SCALE first. This is ok and allows apps not to check for | ||
1158 | * which is supported to get the right answer. | ||
1159 | */ | ||
1160 | if (transforms & PNG_TRANSFORM_STRIP_16) | ||
1161 | png_set_strip_16(png_ptr); | ||
1162 | #endif | ||
1163 | |||
1164 | #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED | ||
1165 | /* Strip alpha bytes from the input data without combining with | ||
1166 | * the background (not recommended). | ||
1167 | */ | ||
1168 | if (transforms & PNG_TRANSFORM_STRIP_ALPHA) | ||
1169 | png_set_strip_alpha(png_ptr); | ||
1170 | #endif | ||
1171 | |||
1172 | #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) | ||
1173 | /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single | ||
1174 | * byte into separate bytes (useful for paletted and grayscale images). | ||
1175 | */ | ||
1176 | if (transforms & PNG_TRANSFORM_PACKING) | ||
1177 | png_set_packing(png_ptr); | ||
1178 | #endif | ||
1179 | |||
1180 | #ifdef PNG_READ_PACKSWAP_SUPPORTED | ||
1181 | /* Change the order of packed pixels to least significant bit first | ||
1182 | * (not useful if you are using png_set_packing). | ||
1183 | */ | ||
1184 | if (transforms & PNG_TRANSFORM_PACKSWAP) | ||
1185 | png_set_packswap(png_ptr); | ||
1186 | #endif | ||
1187 | |||
1188 | #ifdef PNG_READ_EXPAND_SUPPORTED | ||
1189 | /* Expand paletted colors into true RGB triplets | ||
1190 | * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel | ||
1191 | * Expand paletted or RGB images with transparency to full alpha | ||
1192 | * channels so the data will be available as RGBA quartets. | ||
1193 | */ | ||
1194 | if (transforms & PNG_TRANSFORM_EXPAND) | ||
1195 | if ((png_ptr->bit_depth < 8) || | ||
1196 | (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || | ||
1197 | (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) | ||
1198 | png_set_expand(png_ptr); | ||
1199 | #endif | ||
1200 | |||
1201 | /* We don't handle background color or gamma transformation or quantizing. | ||
1202 | */ | ||
1203 | |||
1204 | #ifdef PNG_READ_INVERT_SUPPORTED | ||
1205 | /* Invert monochrome files to have 0 as white and 1 as black | ||
1206 | */ | ||
1207 | if (transforms & PNG_TRANSFORM_INVERT_MONO) | ||
1208 | png_set_invert_mono(png_ptr); | ||
1209 | #endif | ||
1210 | |||
1211 | #ifdef PNG_READ_SHIFT_SUPPORTED | ||
1212 | /* If you want to shift the pixel values from the range [0,255] or | ||
1213 | * [0,65535] to the original [0,7] or [0,31], or whatever range the | ||
1214 | * colors were originally in: | ||
1215 | */ | ||
1216 | if ((transforms & PNG_TRANSFORM_SHIFT) | ||
1217 | && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT)) | ||
1218 | { | ||
1219 | png_color_8p sig_bit; | ||
1220 | |||
1221 | png_get_sBIT(png_ptr, info_ptr, &sig_bit); | ||
1222 | png_set_shift(png_ptr, sig_bit); | ||
1223 | } | ||
1224 | #endif | ||
1225 | |||
1226 | #ifdef PNG_READ_BGR_SUPPORTED | ||
1227 | /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ | ||
1228 | if (transforms & PNG_TRANSFORM_BGR) | ||
1229 | png_set_bgr(png_ptr); | ||
1230 | #endif | ||
1231 | |||
1232 | #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED | ||
1233 | /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ | ||
1234 | if (transforms & PNG_TRANSFORM_SWAP_ALPHA) | ||
1235 | png_set_swap_alpha(png_ptr); | ||
1236 | #endif | ||
1237 | |||
1238 | #ifdef PNG_READ_SWAP_SUPPORTED | ||
1239 | /* Swap bytes of 16-bit files to least significant byte first */ | ||
1240 | if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) | ||
1241 | png_set_swap(png_ptr); | ||
1242 | #endif | ||
1243 | |||
1244 | /* Added at libpng-1.2.41 */ | ||
1245 | #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED | ||
1246 | /* Invert the alpha channel from opacity to transparency */ | ||
1247 | if (transforms & PNG_TRANSFORM_INVERT_ALPHA) | ||
1248 | png_set_invert_alpha(png_ptr); | ||
1249 | #endif | ||
1250 | |||
1251 | /* Added at libpng-1.2.41 */ | ||
1252 | #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED | ||
1253 | /* Expand grayscale image to RGB */ | ||
1254 | if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) | ||
1255 | png_set_gray_to_rgb(png_ptr); | ||
1256 | #endif | ||
1257 | |||
1258 | /* Added at libpng-1.5.4 */ | ||
1259 | #ifdef PNG_READ_EXPAND_16_SUPPORTED | ||
1260 | if (transforms & PNG_TRANSFORM_EXPAND_16) | ||
1261 | png_set_expand_16(png_ptr); | ||
1262 | #endif | ||
1263 | |||
1264 | /* We don't handle adding filler bytes */ | ||
1265 | |||
1266 | /* We use png_read_image and rely on that for interlace handling, but we also | ||
1267 | * call png_read_update_info therefore must turn on interlace handling now: | ||
1268 | */ | ||
1269 | (void)png_set_interlace_handling(png_ptr); | ||
1270 | |||
1271 | /* Optional call to gamma correct and add the background to the palette | ||
1272 | * and update info structure. REQUIRED if you are expecting libpng to | ||
1273 | * update the palette for you (i.e., you selected such a transform above). | ||
1274 | */ | ||
1275 | png_read_update_info(png_ptr, info_ptr); | ||
1276 | |||
1277 | /* -------------- image transformations end here ------------------- */ | ||
1278 | |||
1279 | png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); | ||
1280 | if (info_ptr->row_pointers == NULL) | ||
1281 | { | ||
1282 | png_uint_32 iptr; | ||
1283 | |||
1284 | info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, | ||
1285 | info_ptr->height * png_sizeof(png_bytep)); | ||
1286 | for (iptr=0; iptr<info_ptr->height; iptr++) | ||
1287 | info_ptr->row_pointers[iptr] = NULL; | ||
1288 | |||
1289 | info_ptr->free_me |= PNG_FREE_ROWS; | ||
1290 | |||
1291 | for (row = 0; row < (int)info_ptr->height; row++) | ||
1292 | info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, | ||
1293 | png_get_rowbytes(png_ptr, info_ptr)); | ||
1294 | } | ||
1295 | |||
1296 | png_read_image(png_ptr, info_ptr->row_pointers); | ||
1297 | info_ptr->valid |= PNG_INFO_IDAT; | ||
1298 | |||
1299 | /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ | ||
1300 | png_read_end(png_ptr, info_ptr); | ||
1301 | |||
1302 | PNG_UNUSED(transforms) /* Quiet compiler warnings */ | ||
1303 | PNG_UNUSED(params) | ||
1304 | |||
1305 | } | ||
1306 | #endif /* PNG_INFO_IMAGE_SUPPORTED */ | ||
1307 | #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ | ||
1308 | #endif /* PNG_READ_SUPPORTED */ | ||