/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngread.c
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/png/pngread.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22