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