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