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