VirtualBox

source: vbox/trunk/src/libs/libpng-1.2.54/pngpread.c@ 62162

最後變更 在這個檔案從62162是 58796,由 vboxsync 提交於 9 年 前

libpng 1.2.54 unmodified

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

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