VirtualBox

source: vbox/trunk/src/libs/libpng-1.6.45/pngpread.c@ 107935

Last change on this file since 107935 was 107813, checked in by vboxsync, 3 weeks ago

libpng-1.6.45: Applied and adjusted our libpng changes to 1.6.45. bugref:8515

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette