1 | /* |
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. Oracle designates this |
7 | * particular file as subject to the "Classpath" exception as provided |
8 | * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
21 | * or visit www.oracle.com if you need additional information or have any |
22 | * questions. |
23 | */ |
24 | |
25 | /* pngpread.c - read a png file in push mode |
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.6.35 [July 15, 2018] |
33 | * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson |
34 | * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
35 | * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
36 | * |
37 | * This code is released under the libpng license. |
38 | * For conditions of distribution and use, see the disclaimer |
39 | * and license in png.h |
40 | */ |
41 | |
42 | #include "pngpriv.h" |
43 | |
44 | #ifdef PNG_PROGRESSIVE_READ_SUPPORTED |
45 | |
46 | /* Push model modes */ |
47 | #define PNG_READ_SIG_MODE 0 |
48 | #define PNG_READ_CHUNK_MODE 1 |
49 | #define PNG_READ_IDAT_MODE 2 |
50 | #define PNG_READ_tEXt_MODE 4 |
51 | #define PNG_READ_zTXt_MODE 5 |
52 | #define PNG_READ_DONE_MODE 6 |
53 | #define PNG_READ_iTXt_MODE 7 |
54 | #define PNG_ERROR_MODE 8 |
55 | |
56 | #define PNG_PUSH_SAVE_BUFFER_IF_FULL \ |
57 | if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ |
58 | { png_push_save_buffer(png_ptr); return; } |
59 | #define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ |
60 | if (png_ptr->buffer_size < N) \ |
61 | { png_push_save_buffer(png_ptr); return; } |
62 | |
63 | void PNGAPI |
64 | png_process_data(png_structrp png_ptr, png_inforp info_ptr, |
65 | png_bytep buffer, size_t buffer_size) |
66 | { |
67 | if (png_ptr == NULL || info_ptr == NULL) |
68 | return; |
69 | |
70 | png_push_restore_buffer(png_ptr, buffer, buffer_size); |
71 | |
72 | while (png_ptr->buffer_size) |
73 | { |
74 | png_process_some_data(png_ptr, info_ptr); |
75 | } |
76 | } |
77 | |
78 | size_t PNGAPI |
79 | png_process_data_pause(png_structrp png_ptr, int save) |
80 | { |
81 | if (png_ptr != NULL) |
82 | { |
83 | /* It's easiest for the caller if we do the save; then the caller doesn't |
84 | * have to supply the same data again: |
85 | */ |
86 | if (save != 0) |
87 | png_push_save_buffer(png_ptr); |
88 | else |
89 | { |
90 | /* This includes any pending saved bytes: */ |
91 | size_t remaining = png_ptr->buffer_size; |
92 | png_ptr->buffer_size = 0; |
93 | |
94 | /* So subtract the saved buffer size, unless all the data |
95 | * is actually 'saved', in which case we just return 0 |
96 | */ |
97 | if (png_ptr->save_buffer_size < remaining) |
98 | return remaining - png_ptr->save_buffer_size; |
99 | } |
100 | } |
101 | |
102 | return 0; |
103 | } |
104 | |
105 | png_uint_32 PNGAPI |
106 | png_process_data_skip(png_structrp png_ptr) |
107 | { |
108 | /* TODO: Deprecate and remove this API. |
109 | * Somewhere the implementation of this seems to have been lost, |
110 | * or abandoned. It was only to support some internal back-door access |
111 | * to png_struct) in libpng-1.4.x. |
112 | */ |
113 | png_app_warning(png_ptr, |
114 | "png_process_data_skip is not implemented in any current version of libpng" ); |
115 | return 0; |
116 | } |
117 | |
118 | /* What we do with the incoming data depends on what we were previously |
119 | * doing before we ran out of data... |
120 | */ |
121 | void /* PRIVATE */ |
122 | png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) |
123 | { |
124 | if (png_ptr == NULL) |
125 | return; |
126 | |
127 | switch (png_ptr->process_mode) |
128 | { |
129 | case PNG_READ_SIG_MODE: |
130 | { |
131 | png_push_read_sig(png_ptr, info_ptr); |
132 | break; |
133 | } |
134 | |
135 | case PNG_READ_CHUNK_MODE: |
136 | { |
137 | png_push_read_chunk(png_ptr, info_ptr); |
138 | break; |
139 | } |
140 | |
141 | case PNG_READ_IDAT_MODE: |
142 | { |
143 | png_push_read_IDAT(png_ptr); |
144 | break; |
145 | } |
146 | |
147 | default: |
148 | { |
149 | png_ptr->buffer_size = 0; |
150 | break; |
151 | } |
152 | } |
153 | } |
154 | |
155 | /* Read any remaining signature bytes from the stream and compare them with |
156 | * the correct PNG signature. It is possible that this routine is called |
157 | * with bytes already read from the signature, either because they have been |
158 | * checked by the calling application, or because of multiple calls to this |
159 | * routine. |
160 | */ |
161 | void /* PRIVATE */ |
162 | png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) |
163 | { |
164 | size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */ |
165 | size_t num_to_check = 8 - num_checked; |
166 | |
167 | if (png_ptr->buffer_size < num_to_check) |
168 | { |
169 | num_to_check = png_ptr->buffer_size; |
170 | } |
171 | |
172 | png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), |
173 | num_to_check); |
174 | png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); |
175 | |
176 | if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) |
177 | { |
178 | if (num_checked < 4 && |
179 | png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) |
180 | png_error(png_ptr, "Not a PNG file" ); |
181 | |
182 | else |
183 | png_error(png_ptr, "PNG file corrupted by ASCII conversion" ); |
184 | } |
185 | else |
186 | { |
187 | if (png_ptr->sig_bytes >= 8) |
188 | { |
189 | png_ptr->process_mode = PNG_READ_CHUNK_MODE; |
190 | } |
191 | } |
192 | } |
193 | |
194 | void /* PRIVATE */ |
195 | png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) |
196 | { |
197 | png_uint_32 chunk_name; |
198 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
199 | int keep; /* unknown handling method */ |
200 | #endif |
201 | |
202 | /* First we make sure we have enough data for the 4-byte chunk name |
203 | * and the 4-byte chunk length before proceeding with decoding the |
204 | * chunk data. To fully decode each of these chunks, we also make |
205 | * sure we have enough data in the buffer for the 4-byte CRC at the |
206 | * end of every chunk (except IDAT, which is handled separately). |
207 | */ |
208 | if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) |
209 | { |
210 | png_byte chunk_length[4]; |
211 | png_byte chunk_tag[4]; |
212 | |
213 | PNG_PUSH_SAVE_BUFFER_IF_LT(8) |
214 | png_push_fill_buffer(png_ptr, chunk_length, 4); |
215 | png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); |
216 | png_reset_crc(png_ptr); |
217 | png_crc_read(png_ptr, chunk_tag, 4); |
218 | png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); |
219 | png_check_chunk_name(png_ptr, png_ptr->chunk_name); |
220 | png_check_chunk_length(png_ptr, png_ptr->push_length); |
221 | png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; |
222 | } |
223 | |
224 | chunk_name = png_ptr->chunk_name; |
225 | |
226 | if (chunk_name == png_IDAT) |
227 | { |
228 | if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) |
229 | png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; |
230 | |
231 | /* If we reach an IDAT chunk, this means we have read all of the |
232 | * header chunks, and we can start reading the image (or if this |
233 | * is called after the image has been read - we have an error). |
234 | */ |
235 | if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) |
236 | png_error(png_ptr, "Missing IHDR before IDAT" ); |
237 | |
238 | else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && |
239 | (png_ptr->mode & PNG_HAVE_PLTE) == 0) |
240 | png_error(png_ptr, "Missing PLTE before IDAT" ); |
241 | |
242 | png_ptr->process_mode = PNG_READ_IDAT_MODE; |
243 | |
244 | if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) |
245 | if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) |
246 | if (png_ptr->push_length == 0) |
247 | return; |
248 | |
249 | png_ptr->mode |= PNG_HAVE_IDAT; |
250 | |
251 | if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) |
252 | png_benign_error(png_ptr, "Too many IDATs found" ); |
253 | } |
254 | |
255 | if (chunk_name == png_IHDR) |
256 | { |
257 | if (png_ptr->push_length != 13) |
258 | png_error(png_ptr, "Invalid IHDR length" ); |
259 | |
260 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
261 | png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); |
262 | } |
263 | |
264 | else if (chunk_name == png_IEND) |
265 | { |
266 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
267 | png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); |
268 | |
269 | png_ptr->process_mode = PNG_READ_DONE_MODE; |
270 | png_push_have_end(png_ptr, info_ptr); |
271 | } |
272 | |
273 | #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED |
274 | else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) |
275 | { |
276 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
277 | png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); |
278 | |
279 | if (chunk_name == png_PLTE) |
280 | png_ptr->mode |= PNG_HAVE_PLTE; |
281 | } |
282 | #endif |
283 | |
284 | else if (chunk_name == png_PLTE) |
285 | { |
286 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
287 | png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); |
288 | } |
289 | |
290 | else if (chunk_name == png_IDAT) |
291 | { |
292 | png_ptr->idat_size = png_ptr->push_length; |
293 | png_ptr->process_mode = PNG_READ_IDAT_MODE; |
294 | png_push_have_info(png_ptr, info_ptr); |
295 | png_ptr->zstream.avail_out = |
296 | (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, |
297 | png_ptr->iwidth) + 1; |
298 | png_ptr->zstream.next_out = png_ptr->row_buf; |
299 | return; |
300 | } |
301 | |
302 | #ifdef PNG_READ_gAMA_SUPPORTED |
303 | else if (png_ptr->chunk_name == png_gAMA) |
304 | { |
305 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
306 | png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); |
307 | } |
308 | |
309 | #endif |
310 | #ifdef PNG_READ_sBIT_SUPPORTED |
311 | else if (png_ptr->chunk_name == png_sBIT) |
312 | { |
313 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
314 | png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); |
315 | } |
316 | |
317 | #endif |
318 | #ifdef PNG_READ_cHRM_SUPPORTED |
319 | else if (png_ptr->chunk_name == png_cHRM) |
320 | { |
321 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
322 | png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); |
323 | } |
324 | |
325 | #endif |
326 | #ifdef PNG_READ_sRGB_SUPPORTED |
327 | else if (chunk_name == png_sRGB) |
328 | { |
329 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
330 | png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); |
331 | } |
332 | |
333 | #endif |
334 | #ifdef PNG_READ_iCCP_SUPPORTED |
335 | else if (png_ptr->chunk_name == png_iCCP) |
336 | { |
337 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
338 | png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); |
339 | } |
340 | |
341 | #endif |
342 | #ifdef PNG_READ_sPLT_SUPPORTED |
343 | else if (chunk_name == png_sPLT) |
344 | { |
345 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
346 | png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); |
347 | } |
348 | |
349 | #endif |
350 | #ifdef PNG_READ_tRNS_SUPPORTED |
351 | else if (chunk_name == png_tRNS) |
352 | { |
353 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
354 | png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); |
355 | } |
356 | |
357 | #endif |
358 | #ifdef PNG_READ_bKGD_SUPPORTED |
359 | else if (chunk_name == png_bKGD) |
360 | { |
361 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
362 | png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); |
363 | } |
364 | |
365 | #endif |
366 | #ifdef PNG_READ_hIST_SUPPORTED |
367 | else if (chunk_name == png_hIST) |
368 | { |
369 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
370 | png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); |
371 | } |
372 | |
373 | #endif |
374 | #ifdef PNG_READ_pHYs_SUPPORTED |
375 | else if (chunk_name == png_pHYs) |
376 | { |
377 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
378 | png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); |
379 | } |
380 | |
381 | #endif |
382 | #ifdef PNG_READ_oFFs_SUPPORTED |
383 | else if (chunk_name == png_oFFs) |
384 | { |
385 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
386 | png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); |
387 | } |
388 | #endif |
389 | |
390 | #ifdef PNG_READ_pCAL_SUPPORTED |
391 | else if (chunk_name == png_pCAL) |
392 | { |
393 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
394 | png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); |
395 | } |
396 | |
397 | #endif |
398 | #ifdef PNG_READ_sCAL_SUPPORTED |
399 | else if (chunk_name == png_sCAL) |
400 | { |
401 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
402 | png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); |
403 | } |
404 | |
405 | #endif |
406 | #ifdef PNG_READ_tIME_SUPPORTED |
407 | else if (chunk_name == png_tIME) |
408 | { |
409 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
410 | png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); |
411 | } |
412 | |
413 | #endif |
414 | #ifdef PNG_READ_tEXt_SUPPORTED |
415 | else if (chunk_name == png_tEXt) |
416 | { |
417 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
418 | png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); |
419 | } |
420 | |
421 | #endif |
422 | #ifdef PNG_READ_zTXt_SUPPORTED |
423 | else if (chunk_name == png_zTXt) |
424 | { |
425 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
426 | png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); |
427 | } |
428 | |
429 | #endif |
430 | #ifdef PNG_READ_iTXt_SUPPORTED |
431 | else if (chunk_name == png_iTXt) |
432 | { |
433 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
434 | png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); |
435 | } |
436 | #endif |
437 | |
438 | else |
439 | { |
440 | PNG_PUSH_SAVE_BUFFER_IF_FULL |
441 | png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, |
442 | PNG_HANDLE_CHUNK_AS_DEFAULT); |
443 | } |
444 | |
445 | png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; |
446 | } |
447 | |
448 | void PNGCBAPI |
449 | png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length) |
450 | { |
451 | png_bytep ptr; |
452 | |
453 | if (png_ptr == NULL) |
454 | return; |
455 | |
456 | ptr = buffer; |
457 | if (png_ptr->save_buffer_size != 0) |
458 | { |
459 | size_t save_size; |
460 | |
461 | if (length < png_ptr->save_buffer_size) |
462 | save_size = length; |
463 | |
464 | else |
465 | save_size = png_ptr->save_buffer_size; |
466 | |
467 | memcpy(ptr, png_ptr->save_buffer_ptr, save_size); |
468 | length -= save_size; |
469 | ptr += save_size; |
470 | png_ptr->buffer_size -= save_size; |
471 | png_ptr->save_buffer_size -= save_size; |
472 | png_ptr->save_buffer_ptr += save_size; |
473 | } |
474 | if (length != 0 && png_ptr->current_buffer_size != 0) |
475 | { |
476 | size_t save_size; |
477 | |
478 | if (length < png_ptr->current_buffer_size) |
479 | save_size = length; |
480 | |
481 | else |
482 | save_size = png_ptr->current_buffer_size; |
483 | |
484 | memcpy(ptr, png_ptr->current_buffer_ptr, save_size); |
485 | png_ptr->buffer_size -= save_size; |
486 | png_ptr->current_buffer_size -= save_size; |
487 | png_ptr->current_buffer_ptr += save_size; |
488 | } |
489 | } |
490 | |
491 | void /* PRIVATE */ |
492 | png_push_save_buffer(png_structrp png_ptr) |
493 | { |
494 | if (png_ptr->save_buffer_size != 0) |
495 | { |
496 | if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) |
497 | { |
498 | size_t i, istop; |
499 | png_bytep sp; |
500 | png_bytep dp; |
501 | |
502 | istop = png_ptr->save_buffer_size; |
503 | for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; |
504 | i < istop; i++, sp++, dp++) |
505 | { |
506 | *dp = *sp; |
507 | } |
508 | } |
509 | } |
510 | if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > |
511 | png_ptr->save_buffer_max) |
512 | { |
513 | size_t new_max; |
514 | png_bytep old_buffer; |
515 | |
516 | if (png_ptr->save_buffer_size > PNG_SIZE_MAX - |
517 | (png_ptr->current_buffer_size + 256)) |
518 | { |
519 | png_error(png_ptr, "Potential overflow of save_buffer" ); |
520 | } |
521 | |
522 | new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; |
523 | old_buffer = png_ptr->save_buffer; |
524 | png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, |
525 | (size_t)new_max); |
526 | |
527 | if (png_ptr->save_buffer == NULL) |
528 | { |
529 | png_free(png_ptr, old_buffer); |
530 | png_error(png_ptr, "Insufficient memory for save_buffer" ); |
531 | } |
532 | |
533 | if (old_buffer) |
534 | memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); |
535 | else if (png_ptr->save_buffer_size) |
536 | png_error(png_ptr, "save_buffer error" ); |
537 | png_free(png_ptr, old_buffer); |
538 | png_ptr->save_buffer_max = new_max; |
539 | } |
540 | if (png_ptr->current_buffer_size) |
541 | { |
542 | memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, |
543 | png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); |
544 | png_ptr->save_buffer_size += png_ptr->current_buffer_size; |
545 | png_ptr->current_buffer_size = 0; |
546 | } |
547 | png_ptr->save_buffer_ptr = png_ptr->save_buffer; |
548 | png_ptr->buffer_size = 0; |
549 | } |
550 | |
551 | void /* PRIVATE */ |
552 | png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, |
553 | size_t buffer_length) |
554 | { |
555 | png_ptr->current_buffer = buffer; |
556 | png_ptr->current_buffer_size = buffer_length; |
557 | png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; |
558 | png_ptr->current_buffer_ptr = png_ptr->current_buffer; |
559 | } |
560 | |
561 | void /* PRIVATE */ |
562 | png_push_read_IDAT(png_structrp png_ptr) |
563 | { |
564 | if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) |
565 | { |
566 | png_byte chunk_length[4]; |
567 | png_byte chunk_tag[4]; |
568 | |
569 | /* TODO: this code can be commoned up with the same code in push_read */ |
570 | PNG_PUSH_SAVE_BUFFER_IF_LT(8) |
571 | png_push_fill_buffer(png_ptr, chunk_length, 4); |
572 | png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); |
573 | png_reset_crc(png_ptr); |
574 | png_crc_read(png_ptr, chunk_tag, 4); |
575 | png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); |
576 | png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; |
577 | |
578 | if (png_ptr->chunk_name != png_IDAT) |
579 | { |
580 | png_ptr->process_mode = PNG_READ_CHUNK_MODE; |
581 | |
582 | if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) |
583 | png_error(png_ptr, "Not enough compressed data" ); |
584 | |
585 | return; |
586 | } |
587 | |
588 | png_ptr->idat_size = png_ptr->push_length; |
589 | } |
590 | |
591 | if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) |
592 | { |
593 | size_t save_size = png_ptr->save_buffer_size; |
594 | png_uint_32 idat_size = png_ptr->idat_size; |
595 | |
596 | /* We want the smaller of 'idat_size' and 'current_buffer_size', but they |
597 | * are of different types and we don't know which variable has the fewest |
598 | * bits. Carefully select the smaller and cast it to the type of the |
599 | * larger - this cannot overflow. Do not cast in the following test - it |
600 | * will break on either 16-bit or 64-bit platforms. |
601 | */ |
602 | if (idat_size < save_size) |
603 | save_size = (size_t)idat_size; |
604 | |
605 | else |
606 | idat_size = (png_uint_32)save_size; |
607 | |
608 | png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); |
609 | |
610 | png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); |
611 | |
612 | png_ptr->idat_size -= idat_size; |
613 | png_ptr->buffer_size -= save_size; |
614 | png_ptr->save_buffer_size -= save_size; |
615 | png_ptr->save_buffer_ptr += save_size; |
616 | } |
617 | |
618 | if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) |
619 | { |
620 | size_t save_size = png_ptr->current_buffer_size; |
621 | png_uint_32 idat_size = png_ptr->idat_size; |
622 | |
623 | /* We want the smaller of 'idat_size' and 'current_buffer_size', but they |
624 | * are of different types and we don't know which variable has the fewest |
625 | * bits. Carefully select the smaller and cast it to the type of the |
626 | * larger - this cannot overflow. |
627 | */ |
628 | if (idat_size < save_size) |
629 | save_size = (size_t)idat_size; |
630 | |
631 | else |
632 | idat_size = (png_uint_32)save_size; |
633 | |
634 | png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); |
635 | |
636 | png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); |
637 | |
638 | png_ptr->idat_size -= idat_size; |
639 | png_ptr->buffer_size -= save_size; |
640 | png_ptr->current_buffer_size -= save_size; |
641 | png_ptr->current_buffer_ptr += save_size; |
642 | } |
643 | |
644 | if (png_ptr->idat_size == 0) |
645 | { |
646 | PNG_PUSH_SAVE_BUFFER_IF_LT(4) |
647 | png_crc_finish(png_ptr, 0); |
648 | png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; |
649 | png_ptr->mode |= PNG_AFTER_IDAT; |
650 | png_ptr->zowner = 0; |
651 | } |
652 | } |
653 | |
654 | void /* PRIVATE */ |
655 | png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, |
656 | size_t buffer_length) |
657 | { |
658 | /* The caller checks for a non-zero buffer length. */ |
659 | if (!(buffer_length > 0) || buffer == NULL) |
660 | png_error(png_ptr, "No IDAT data (internal error)" ); |
661 | |
662 | /* This routine must process all the data it has been given |
663 | * before returning, calling the row callback as required to |
664 | * handle the uncompressed results. |
665 | */ |
666 | png_ptr->zstream.next_in = buffer; |
667 | /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ |
668 | png_ptr->zstream.avail_in = (uInt)buffer_length; |
669 | |
670 | /* Keep going until the decompressed data is all processed |
671 | * or the stream marked as finished. |
672 | */ |
673 | while (png_ptr->zstream.avail_in > 0 && |
674 | (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) |
675 | { |
676 | int ret; |
677 | |
678 | /* We have data for zlib, but we must check that zlib |
679 | * has someplace to put the results. It doesn't matter |
680 | * if we don't expect any results -- it may be the input |
681 | * data is just the LZ end code. |
682 | */ |
683 | if (!(png_ptr->zstream.avail_out > 0)) |
684 | { |
685 | /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ |
686 | png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, |
687 | png_ptr->iwidth) + 1); |
688 | |
689 | png_ptr->zstream.next_out = png_ptr->row_buf; |
690 | } |
691 | |
692 | /* Using Z_SYNC_FLUSH here means that an unterminated |
693 | * LZ stream (a stream with a missing end code) can still |
694 | * be handled, otherwise (Z_NO_FLUSH) a future zlib |
695 | * implementation might defer output and therefore |
696 | * change the current behavior (see comments in inflate.c |
697 | * for why this doesn't happen at present with zlib 1.2.5). |
698 | */ |
699 | ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); |
700 | |
701 | /* Check for any failure before proceeding. */ |
702 | if (ret != Z_OK && ret != Z_STREAM_END) |
703 | { |
704 | /* Terminate the decompression. */ |
705 | png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; |
706 | png_ptr->zowner = 0; |
707 | |
708 | /* This may be a truncated stream (missing or |
709 | * damaged end code). Treat that as a warning. |
710 | */ |
711 | if (png_ptr->row_number >= png_ptr->num_rows || |
712 | png_ptr->pass > 6) |
713 | png_warning(png_ptr, "Truncated compressed data in IDAT" ); |
714 | |
715 | else |
716 | { |
717 | if (ret == Z_DATA_ERROR) |
718 | png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch" ); |
719 | else |
720 | png_error(png_ptr, "Decompression error in IDAT" ); |
721 | } |
722 | |
723 | /* Skip the check on unprocessed input */ |
724 | return; |
725 | } |
726 | |
727 | /* Did inflate output any data? */ |
728 | if (png_ptr->zstream.next_out != png_ptr->row_buf) |
729 | { |
730 | /* Is this unexpected data after the last row? |
731 | * If it is, artificially terminate the LZ output |
732 | * here. |
733 | */ |
734 | if (png_ptr->row_number >= png_ptr->num_rows || |
735 | png_ptr->pass > 6) |
736 | { |
737 | /* Extra data. */ |
738 | png_warning(png_ptr, "Extra compressed data in IDAT" ); |
739 | png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; |
740 | png_ptr->zowner = 0; |
741 | |
742 | /* Do no more processing; skip the unprocessed |
743 | * input check below. |
744 | */ |
745 | return; |
746 | } |
747 | |
748 | /* Do we have a complete row? */ |
749 | if (png_ptr->zstream.avail_out == 0) |
750 | png_push_process_row(png_ptr); |
751 | } |
752 | |
753 | /* And check for the end of the stream. */ |
754 | if (ret == Z_STREAM_END) |
755 | png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; |
756 | } |
757 | |
758 | /* All the data should have been processed, if anything |
759 | * is left at this point we have bytes of IDAT data |
760 | * after the zlib end code. |
761 | */ |
762 | if (png_ptr->zstream.avail_in > 0) |
763 | png_warning(png_ptr, "Extra compression data in IDAT" ); |
764 | } |
765 | |
766 | void /* PRIVATE */ |
767 | png_push_process_row(png_structrp png_ptr) |
768 | { |
769 | /* 1.5.6: row_info moved out of png_struct to a local here. */ |
770 | png_row_info row_info; |
771 | |
772 | row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ |
773 | row_info.color_type = png_ptr->color_type; |
774 | row_info.bit_depth = png_ptr->bit_depth; |
775 | row_info.channels = png_ptr->channels; |
776 | row_info.pixel_depth = png_ptr->pixel_depth; |
777 | row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); |
778 | |
779 | if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) |
780 | { |
781 | if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) |
782 | png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, |
783 | png_ptr->prev_row + 1, png_ptr->row_buf[0]); |
784 | else |
785 | png_error(png_ptr, "bad adaptive filter value" ); |
786 | } |
787 | |
788 | /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before |
789 | * 1.5.6, while the buffer really is this big in current versions of libpng |
790 | * it may not be in the future, so this was changed just to copy the |
791 | * interlaced row count: |
792 | */ |
793 | memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); |
794 | |
795 | #ifdef PNG_READ_TRANSFORMS_SUPPORTED |
796 | if (png_ptr->transformations != 0) |
797 | png_do_read_transformations(png_ptr, &row_info); |
798 | #endif |
799 | |
800 | /* The transformed pixel depth should match the depth now in row_info. */ |
801 | if (png_ptr->transformed_pixel_depth == 0) |
802 | { |
803 | png_ptr->transformed_pixel_depth = row_info.pixel_depth; |
804 | if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) |
805 | png_error(png_ptr, "progressive row overflow" ); |
806 | } |
807 | |
808 | else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) |
809 | png_error(png_ptr, "internal progressive row size calculation error" ); |
810 | |
811 | |
812 | #ifdef PNG_READ_INTERLACING_SUPPORTED |
813 | /* Expand interlaced rows to full size */ |
814 | if (png_ptr->interlaced != 0 && |
815 | (png_ptr->transformations & PNG_INTERLACE) != 0) |
816 | { |
817 | if (png_ptr->pass < 6) |
818 | png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, |
819 | png_ptr->transformations); |
820 | |
821 | switch (png_ptr->pass) |
822 | { |
823 | case 0: |
824 | { |
825 | int i; |
826 | for (i = 0; i < 8 && png_ptr->pass == 0; i++) |
827 | { |
828 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
829 | png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ |
830 | } |
831 | |
832 | if (png_ptr->pass == 2) /* Pass 1 might be empty */ |
833 | { |
834 | for (i = 0; i < 4 && png_ptr->pass == 2; i++) |
835 | { |
836 | png_push_have_row(png_ptr, NULL); |
837 | png_read_push_finish_row(png_ptr); |
838 | } |
839 | } |
840 | |
841 | if (png_ptr->pass == 4 && png_ptr->height <= 4) |
842 | { |
843 | for (i = 0; i < 2 && png_ptr->pass == 4; i++) |
844 | { |
845 | png_push_have_row(png_ptr, NULL); |
846 | png_read_push_finish_row(png_ptr); |
847 | } |
848 | } |
849 | |
850 | if (png_ptr->pass == 6 && png_ptr->height <= 4) |
851 | { |
852 | png_push_have_row(png_ptr, NULL); |
853 | png_read_push_finish_row(png_ptr); |
854 | } |
855 | |
856 | break; |
857 | } |
858 | |
859 | case 1: |
860 | { |
861 | int i; |
862 | for (i = 0; i < 8 && png_ptr->pass == 1; i++) |
863 | { |
864 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
865 | png_read_push_finish_row(png_ptr); |
866 | } |
867 | |
868 | if (png_ptr->pass == 2) /* Skip top 4 generated rows */ |
869 | { |
870 | for (i = 0; i < 4 && png_ptr->pass == 2; i++) |
871 | { |
872 | png_push_have_row(png_ptr, NULL); |
873 | png_read_push_finish_row(png_ptr); |
874 | } |
875 | } |
876 | |
877 | break; |
878 | } |
879 | |
880 | case 2: |
881 | { |
882 | int i; |
883 | |
884 | for (i = 0; i < 4 && png_ptr->pass == 2; i++) |
885 | { |
886 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
887 | png_read_push_finish_row(png_ptr); |
888 | } |
889 | |
890 | for (i = 0; i < 4 && png_ptr->pass == 2; i++) |
891 | { |
892 | png_push_have_row(png_ptr, NULL); |
893 | png_read_push_finish_row(png_ptr); |
894 | } |
895 | |
896 | if (png_ptr->pass == 4) /* Pass 3 might be empty */ |
897 | { |
898 | for (i = 0; i < 2 && png_ptr->pass == 4; i++) |
899 | { |
900 | png_push_have_row(png_ptr, NULL); |
901 | png_read_push_finish_row(png_ptr); |
902 | } |
903 | } |
904 | |
905 | break; |
906 | } |
907 | |
908 | case 3: |
909 | { |
910 | int i; |
911 | |
912 | for (i = 0; i < 4 && png_ptr->pass == 3; i++) |
913 | { |
914 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
915 | png_read_push_finish_row(png_ptr); |
916 | } |
917 | |
918 | if (png_ptr->pass == 4) /* Skip top two generated rows */ |
919 | { |
920 | for (i = 0; i < 2 && png_ptr->pass == 4; i++) |
921 | { |
922 | png_push_have_row(png_ptr, NULL); |
923 | png_read_push_finish_row(png_ptr); |
924 | } |
925 | } |
926 | |
927 | break; |
928 | } |
929 | |
930 | case 4: |
931 | { |
932 | int i; |
933 | |
934 | for (i = 0; i < 2 && png_ptr->pass == 4; i++) |
935 | { |
936 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
937 | png_read_push_finish_row(png_ptr); |
938 | } |
939 | |
940 | for (i = 0; i < 2 && png_ptr->pass == 4; i++) |
941 | { |
942 | png_push_have_row(png_ptr, NULL); |
943 | png_read_push_finish_row(png_ptr); |
944 | } |
945 | |
946 | if (png_ptr->pass == 6) /* Pass 5 might be empty */ |
947 | { |
948 | png_push_have_row(png_ptr, NULL); |
949 | png_read_push_finish_row(png_ptr); |
950 | } |
951 | |
952 | break; |
953 | } |
954 | |
955 | case 5: |
956 | { |
957 | int i; |
958 | |
959 | for (i = 0; i < 2 && png_ptr->pass == 5; i++) |
960 | { |
961 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
962 | png_read_push_finish_row(png_ptr); |
963 | } |
964 | |
965 | if (png_ptr->pass == 6) /* Skip top generated row */ |
966 | { |
967 | png_push_have_row(png_ptr, NULL); |
968 | png_read_push_finish_row(png_ptr); |
969 | } |
970 | |
971 | break; |
972 | } |
973 | |
974 | default: |
975 | case 6: |
976 | { |
977 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
978 | png_read_push_finish_row(png_ptr); |
979 | |
980 | if (png_ptr->pass != 6) |
981 | break; |
982 | |
983 | png_push_have_row(png_ptr, NULL); |
984 | png_read_push_finish_row(png_ptr); |
985 | } |
986 | } |
987 | } |
988 | else |
989 | #endif |
990 | { |
991 | png_push_have_row(png_ptr, png_ptr->row_buf + 1); |
992 | png_read_push_finish_row(png_ptr); |
993 | } |
994 | } |
995 | |
996 | void /* PRIVATE */ |
997 | png_read_push_finish_row(png_structrp png_ptr) |
998 | { |
999 | #ifdef PNG_READ_INTERLACING_SUPPORTED |
1000 | /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ |
1001 | |
1002 | /* Start of interlace block */ |
1003 | static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; |
1004 | |
1005 | /* Offset to next interlace block */ |
1006 | static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; |
1007 | |
1008 | /* Start of interlace block in the y direction */ |
1009 | static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; |
1010 | |
1011 | /* Offset to next interlace block in the y direction */ |
1012 | static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; |
1013 | |
1014 | /* Height of interlace block. This is not currently used - if you need |
1015 | * it, uncomment it here and in png.h |
1016 | static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; |
1017 | */ |
1018 | #endif |
1019 | |
1020 | png_ptr->row_number++; |
1021 | if (png_ptr->row_number < png_ptr->num_rows) |
1022 | return; |
1023 | |
1024 | #ifdef PNG_READ_INTERLACING_SUPPORTED |
1025 | if (png_ptr->interlaced != 0) |
1026 | { |
1027 | png_ptr->row_number = 0; |
1028 | memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); |
1029 | |
1030 | do |
1031 | { |
1032 | png_ptr->pass++; |
1033 | if ((png_ptr->pass == 1 && png_ptr->width < 5) || |
1034 | (png_ptr->pass == 3 && png_ptr->width < 3) || |
1035 | (png_ptr->pass == 5 && png_ptr->width < 2)) |
1036 | png_ptr->pass++; |
1037 | |
1038 | if (png_ptr->pass > 7) |
1039 | png_ptr->pass--; |
1040 | |
1041 | if (png_ptr->pass >= 7) |
1042 | break; |
1043 | |
1044 | png_ptr->iwidth = (png_ptr->width + |
1045 | png_pass_inc[png_ptr->pass] - 1 - |
1046 | png_pass_start[png_ptr->pass]) / |
1047 | png_pass_inc[png_ptr->pass]; |
1048 | |
1049 | if ((png_ptr->transformations & PNG_INTERLACE) != 0) |
1050 | break; |
1051 | |
1052 | png_ptr->num_rows = (png_ptr->height + |
1053 | png_pass_yinc[png_ptr->pass] - 1 - |
1054 | png_pass_ystart[png_ptr->pass]) / |
1055 | png_pass_yinc[png_ptr->pass]; |
1056 | |
1057 | } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); |
1058 | } |
1059 | #endif /* READ_INTERLACING */ |
1060 | } |
1061 | |
1062 | void /* PRIVATE */ |
1063 | png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) |
1064 | { |
1065 | if (png_ptr->info_fn != NULL) |
1066 | (*(png_ptr->info_fn))(png_ptr, info_ptr); |
1067 | } |
1068 | |
1069 | void /* PRIVATE */ |
1070 | png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) |
1071 | { |
1072 | if (png_ptr->end_fn != NULL) |
1073 | (*(png_ptr->end_fn))(png_ptr, info_ptr); |
1074 | } |
1075 | |
1076 | void /* PRIVATE */ |
1077 | png_push_have_row(png_structrp png_ptr, png_bytep row) |
1078 | { |
1079 | if (png_ptr->row_fn != NULL) |
1080 | (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, |
1081 | (int)png_ptr->pass); |
1082 | } |
1083 | |
1084 | #ifdef PNG_READ_INTERLACING_SUPPORTED |
1085 | void PNGAPI |
1086 | png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, |
1087 | png_const_bytep new_row) |
1088 | { |
1089 | if (png_ptr == NULL) |
1090 | return; |
1091 | |
1092 | /* new_row is a flag here - if it is NULL then the app callback was called |
1093 | * from an empty row (see the calls to png_struct::row_fn below), otherwise |
1094 | * it must be png_ptr->row_buf+1 |
1095 | */ |
1096 | if (new_row != NULL) |
1097 | png_combine_row(png_ptr, old_row, 1/*blocky display*/); |
1098 | } |
1099 | #endif /* READ_INTERLACING */ |
1100 | |
1101 | void PNGAPI |
1102 | png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, |
1103 | png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, |
1104 | png_progressive_end_ptr end_fn) |
1105 | { |
1106 | if (png_ptr == NULL) |
1107 | return; |
1108 | |
1109 | png_ptr->info_fn = info_fn; |
1110 | png_ptr->row_fn = row_fn; |
1111 | png_ptr->end_fn = end_fn; |
1112 | |
1113 | png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); |
1114 | } |
1115 | |
1116 | png_voidp PNGAPI |
1117 | png_get_progressive_ptr(png_const_structrp png_ptr) |
1118 | { |
1119 | if (png_ptr == NULL) |
1120 | return (NULL); |
1121 | |
1122 | return png_ptr->io_ptr; |
1123 | } |
1124 | #endif /* PROGRESSIVE_READ */ |
1125 | |