/[pcsx2_0.9.7]/trunk/3rdparty/wxWidgets/src/png/pngpread.c
ViewVC logotype

Annotation of /trunk/3rdparty/wxWidgets/src/png/pngpread.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 4 months ago) by william
File MIME type: text/plain
File size: 47458 byte(s)
committing r3113 initial commit again...
1 william 31
2     /* pngpread.c - read a png file in push mode
3     *
4     * Last changed in libpng 1.2.38 [July 16, 2009]
5     * Copyright (c) 1998-2009 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     #include "png.h"
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_SKIP_MODE 3
23     #define PNG_READ_tEXt_MODE 4
24     #define PNG_READ_zTXt_MODE 5
25     #define PNG_READ_DONE_MODE 6
26     #define PNG_READ_iTXt_MODE 7
27     #define PNG_ERROR_MODE 8
28    
29     void PNGAPI
30     png_process_data(png_structp png_ptr, png_infop info_ptr,
31     png_bytep buffer, png_size_t buffer_size)
32     {
33     if (png_ptr == NULL || info_ptr == NULL)
34     return;
35    
36     png_push_restore_buffer(png_ptr, buffer, buffer_size);
37    
38     while (png_ptr->buffer_size)
39     {
40     png_process_some_data(png_ptr, info_ptr);
41     }
42     }
43    
44     /* What we do with the incoming data depends on what we were previously
45     * doing before we ran out of data...
46     */
47     void /* PRIVATE */
48     png_process_some_data(png_structp png_ptr, png_infop info_ptr)
49     {
50     if (png_ptr == NULL)
51     return;
52    
53     switch (png_ptr->process_mode)
54     {
55     case PNG_READ_SIG_MODE:
56     {
57     png_push_read_sig(png_ptr, info_ptr);
58     break;
59     }
60    
61     case PNG_READ_CHUNK_MODE:
62     {
63     png_push_read_chunk(png_ptr, info_ptr);
64     break;
65     }
66    
67     case PNG_READ_IDAT_MODE:
68     {
69     png_push_read_IDAT(png_ptr);
70     break;
71     }
72    
73     #if defined(PNG_READ_tEXt_SUPPORTED)
74     case PNG_READ_tEXt_MODE:
75     {
76     png_push_read_tEXt(png_ptr, info_ptr);
77     break;
78     }
79    
80     #endif
81     #if defined(PNG_READ_zTXt_SUPPORTED)
82     case PNG_READ_zTXt_MODE:
83     {
84     png_push_read_zTXt(png_ptr, info_ptr);
85     break;
86     }
87    
88     #endif
89     #if defined(PNG_READ_iTXt_SUPPORTED)
90     case PNG_READ_iTXt_MODE:
91     {
92     png_push_read_iTXt(png_ptr, info_ptr);
93     break;
94     }
95    
96     #endif
97     case PNG_SKIP_MODE:
98     {
99     png_push_crc_finish(png_ptr);
100     break;
101     }
102    
103     default:
104     {
105     png_ptr->buffer_size = 0;
106     break;
107     }
108     }
109     }
110    
111     /* Read any remaining signature bytes from the stream and compare them with
112     * the correct PNG signature. It is possible that this routine is called
113     * with bytes already read from the signature, either because they have been
114     * checked by the calling application, or because of multiple calls to this
115     * routine.
116     */
117     void /* PRIVATE */
118     png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
119     {
120     png_size_t num_checked = png_ptr->sig_bytes,
121     num_to_check = 8 - num_checked;
122    
123     if (png_ptr->buffer_size < num_to_check)
124     {
125     num_to_check = png_ptr->buffer_size;
126     }
127    
128     png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
129     num_to_check);
130     png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
131    
132     if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
133     {
134     if (num_checked < 4 &&
135     png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
136     png_error(png_ptr, "Not a PNG file");
137     else
138     png_error(png_ptr, "PNG file corrupted by ASCII conversion");
139     }
140     else
141     {
142     if (png_ptr->sig_bytes >= 8)
143     {
144     png_ptr->process_mode = PNG_READ_CHUNK_MODE;
145     }
146     }
147     }
148    
149     void /* PRIVATE */
150     png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
151     {
152     #ifdef PNG_USE_LOCAL_ARRAYS
153     PNG_CONST PNG_IHDR;
154     PNG_CONST PNG_IDAT;
155     PNG_CONST PNG_IEND;
156     PNG_CONST PNG_PLTE;
157     #if defined(PNG_READ_bKGD_SUPPORTED)
158     PNG_CONST PNG_bKGD;
159     #endif
160     #if defined(PNG_READ_cHRM_SUPPORTED)
161     PNG_CONST PNG_cHRM;
162     #endif
163     #if defined(PNG_READ_gAMA_SUPPORTED)
164     PNG_CONST PNG_gAMA;
165     #endif
166     #if defined(PNG_READ_hIST_SUPPORTED)
167     PNG_CONST PNG_hIST;
168     #endif
169     #if defined(PNG_READ_iCCP_SUPPORTED)
170     PNG_CONST PNG_iCCP;
171     #endif
172     #if defined(PNG_READ_iTXt_SUPPORTED)
173     PNG_CONST PNG_iTXt;
174     #endif
175     #if defined(PNG_READ_oFFs_SUPPORTED)
176     PNG_CONST PNG_oFFs;
177     #endif
178     #if defined(PNG_READ_pCAL_SUPPORTED)
179     PNG_CONST PNG_pCAL;
180     #endif
181     #if defined(PNG_READ_pHYs_SUPPORTED)
182     PNG_CONST PNG_pHYs;
183     #endif
184     #if defined(PNG_READ_sBIT_SUPPORTED)
185     PNG_CONST PNG_sBIT;
186     #endif
187     #if defined(PNG_READ_sCAL_SUPPORTED)
188     PNG_CONST PNG_sCAL;
189     #endif
190     #if defined(PNG_READ_sRGB_SUPPORTED)
191     PNG_CONST PNG_sRGB;
192     #endif
193     #if defined(PNG_READ_sPLT_SUPPORTED)
194     PNG_CONST PNG_sPLT;
195     #endif
196     #if defined(PNG_READ_tEXt_SUPPORTED)
197     PNG_CONST PNG_tEXt;
198     #endif
199     #if defined(PNG_READ_tIME_SUPPORTED)
200     PNG_CONST PNG_tIME;
201     #endif
202     #if defined(PNG_READ_tRNS_SUPPORTED)
203     PNG_CONST PNG_tRNS;
204     #endif
205     #if defined(PNG_READ_zTXt_SUPPORTED)
206     PNG_CONST PNG_zTXt;
207     #endif
208     #endif /* PNG_USE_LOCAL_ARRAYS */
209     /* First we make sure we have enough data for the 4 byte chunk name
210     * and the 4 byte chunk length before proceeding with decoding the
211     * chunk data. To fully decode each of these chunks, we also make
212     * sure we have enough data in the buffer for the 4 byte CRC at the
213     * end of every chunk (except IDAT, which is handled separately).
214     */
215     if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
216     {
217     png_byte chunk_length[4];
218    
219     if (png_ptr->buffer_size < 8)
220     {
221     png_push_save_buffer(png_ptr);
222     return;
223     }
224    
225     png_push_fill_buffer(png_ptr, chunk_length, 4);
226     png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
227     png_reset_crc(png_ptr);
228     png_crc_read(png_ptr, png_ptr->chunk_name, 4);
229     png_check_chunk_name(png_ptr, png_ptr->chunk_name);
230     png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
231     }
232    
233     if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
234     if (png_ptr->mode & PNG_AFTER_IDAT)
235     png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
236    
237     if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
238     {
239     if (png_ptr->push_length != 13)
240     png_error(png_ptr, "Invalid IHDR length");
241    
242     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
243     {
244     png_push_save_buffer(png_ptr);
245     return;
246     }
247    
248     png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
249     }
250    
251     else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
252     {
253     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
254     {
255     png_push_save_buffer(png_ptr);
256     return;
257     }
258    
259     png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
260    
261     png_ptr->process_mode = PNG_READ_DONE_MODE;
262     png_push_have_end(png_ptr, info_ptr);
263     }
264    
265     #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
266     else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
267     {
268     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
269     {
270     png_push_save_buffer(png_ptr);
271     return;
272     }
273    
274     if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
275     png_ptr->mode |= PNG_HAVE_IDAT;
276    
277     png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
278    
279     if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
280     png_ptr->mode |= PNG_HAVE_PLTE;
281    
282     else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
283     {
284     if (!(png_ptr->mode & PNG_HAVE_IHDR))
285     png_error(png_ptr, "Missing IHDR before IDAT");
286    
287     else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
288     !(png_ptr->mode & PNG_HAVE_PLTE))
289     png_error(png_ptr, "Missing PLTE before IDAT");
290     }
291     }
292    
293     #endif
294     else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
295     {
296     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
297     {
298     png_push_save_buffer(png_ptr);
299     return;
300     }
301     png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
302     }
303    
304     else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
305     {
306     /* If we reach an IDAT chunk, this means we have read all of the
307     * header chunks, and we can start reading the image (or if this
308     * is called after the image has been read - we have an error).
309     */
310    
311     if (!(png_ptr->mode & PNG_HAVE_IHDR))
312     png_error(png_ptr, "Missing IHDR before IDAT");
313    
314     else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
315     !(png_ptr->mode & PNG_HAVE_PLTE))
316     png_error(png_ptr, "Missing PLTE before IDAT");
317    
318     if (png_ptr->mode & PNG_HAVE_IDAT)
319     {
320     if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
321     if (png_ptr->push_length == 0)
322     return;
323    
324     if (png_ptr->mode & PNG_AFTER_IDAT)
325     png_error(png_ptr, "Too many IDAT's found");
326     }
327    
328     png_ptr->idat_size = png_ptr->push_length;
329     png_ptr->mode |= PNG_HAVE_IDAT;
330     png_ptr->process_mode = PNG_READ_IDAT_MODE;
331     png_push_have_info(png_ptr, info_ptr);
332     png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
333     png_ptr->zstream.next_out = png_ptr->row_buf;
334     return;
335     }
336    
337     #if defined(PNG_READ_gAMA_SUPPORTED)
338     else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
339     {
340     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
341     {
342     png_push_save_buffer(png_ptr);
343     return;
344     }
345    
346     png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
347     }
348    
349     #endif
350     #if defined(PNG_READ_sBIT_SUPPORTED)
351     else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
352     {
353     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
354     {
355     png_push_save_buffer(png_ptr);
356     return;
357     }
358    
359     png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
360     }
361    
362     #endif
363     #if defined(PNG_READ_cHRM_SUPPORTED)
364     else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
365     {
366     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
367     {
368     png_push_save_buffer(png_ptr);
369     return;
370     }
371    
372     png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
373     }
374    
375     #endif
376     #if defined(PNG_READ_sRGB_SUPPORTED)
377     else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
378     {
379     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
380     {
381     png_push_save_buffer(png_ptr);
382     return;
383     }
384    
385     png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
386     }
387    
388     #endif
389     #if defined(PNG_READ_iCCP_SUPPORTED)
390     else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
391     {
392     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
393     {
394     png_push_save_buffer(png_ptr);
395     return;
396     }
397    
398     png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
399     }
400    
401     #endif
402     #if defined(PNG_READ_sPLT_SUPPORTED)
403     else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
404     {
405     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
406     {
407     png_push_save_buffer(png_ptr);
408     return;
409     }
410    
411     png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
412     }
413    
414     #endif
415     #if defined(PNG_READ_tRNS_SUPPORTED)
416     else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
417     {
418     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
419     {
420     png_push_save_buffer(png_ptr);
421     return;
422     }
423    
424     png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
425     }
426    
427     #endif
428     #if defined(PNG_READ_bKGD_SUPPORTED)
429     else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
430     {
431     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
432     {
433     png_push_save_buffer(png_ptr);
434     return;
435     }
436    
437     png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
438     }
439    
440     #endif
441     #if defined(PNG_READ_hIST_SUPPORTED)
442     else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
443     {
444     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
445     {
446     png_push_save_buffer(png_ptr);
447     return;
448     }
449    
450     png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
451     }
452    
453     #endif
454     #if defined(PNG_READ_pHYs_SUPPORTED)
455     else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
456     {
457     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
458     {
459     png_push_save_buffer(png_ptr);
460     return;
461     }
462    
463     png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
464     }
465    
466     #endif
467     #if defined(PNG_READ_oFFs_SUPPORTED)
468     else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
469     {
470     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
471     {
472     png_push_save_buffer(png_ptr);
473     return;
474     }
475    
476     png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
477     }
478     #endif
479    
480     #if defined(PNG_READ_pCAL_SUPPORTED)
481     else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
482     {
483     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
484     {
485     png_push_save_buffer(png_ptr);
486     return;
487     }
488    
489     png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
490     }
491    
492     #endif
493     #if defined(PNG_READ_sCAL_SUPPORTED)
494     else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
495     {
496     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
497     {
498     png_push_save_buffer(png_ptr);
499     return;
500     }
501    
502     png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
503     }
504    
505     #endif
506     #if defined(PNG_READ_tIME_SUPPORTED)
507     else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
508     {
509     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
510     {
511     png_push_save_buffer(png_ptr);
512     return;
513     }
514    
515     png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
516     }
517    
518     #endif
519     #if defined(PNG_READ_tEXt_SUPPORTED)
520     else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
521     {
522     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
523     {
524     png_push_save_buffer(png_ptr);
525     return;
526     }
527    
528     png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
529     }
530    
531     #endif
532     #if defined(PNG_READ_zTXt_SUPPORTED)
533     else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
534     {
535     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
536     {
537     png_push_save_buffer(png_ptr);
538     return;
539     }
540    
541     png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
542     }
543    
544     #endif
545     #if defined(PNG_READ_iTXt_SUPPORTED)
546     else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
547     {
548     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
549     {
550     png_push_save_buffer(png_ptr);
551     return;
552     }
553    
554     png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
555     }
556    
557     #endif
558     else
559     {
560     if (png_ptr->push_length + 4 > png_ptr->buffer_size)
561     {
562     png_push_save_buffer(png_ptr);
563     return;
564     }
565     png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
566     }
567    
568     png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
569     }
570    
571     void /* PRIVATE */
572     png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
573     {
574     png_ptr->process_mode = PNG_SKIP_MODE;
575     png_ptr->skip_length = skip;
576     }
577    
578     void /* PRIVATE */
579     png_push_crc_finish(png_structp png_ptr)
580     {
581     if (png_ptr->skip_length && png_ptr->save_buffer_size)
582     {
583     png_size_t save_size;
584    
585     if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
586     save_size = (png_size_t)png_ptr->skip_length;
587     else
588     save_size = png_ptr->save_buffer_size;
589    
590     png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
591    
592     png_ptr->skip_length -= save_size;
593     png_ptr->buffer_size -= save_size;
594     png_ptr->save_buffer_size -= save_size;
595     png_ptr->save_buffer_ptr += save_size;
596     }
597     if (png_ptr->skip_length && png_ptr->current_buffer_size)
598     {
599     png_size_t save_size;
600    
601     if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
602     save_size = (png_size_t)png_ptr->skip_length;
603     else
604     save_size = png_ptr->current_buffer_size;
605    
606     png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
607    
608     png_ptr->skip_length -= save_size;
609     png_ptr->buffer_size -= save_size;
610     png_ptr->current_buffer_size -= save_size;
611     png_ptr->current_buffer_ptr += save_size;
612     }
613     if (!png_ptr->skip_length)
614     {
615     if (png_ptr->buffer_size < 4)
616     {
617     png_push_save_buffer(png_ptr);
618     return;
619     }
620    
621     png_crc_finish(png_ptr, 0);
622     png_ptr->process_mode = PNG_READ_CHUNK_MODE;
623     }
624     }
625    
626     void PNGAPI
627     png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
628     {
629     png_bytep ptr;
630    
631     if (png_ptr == NULL)
632     return;
633    
634     ptr = buffer;
635     if (png_ptr->save_buffer_size)
636     {
637     png_size_t save_size;
638    
639     if (length < png_ptr->save_buffer_size)
640     save_size = length;
641     else
642     save_size = png_ptr->save_buffer_size;
643    
644     png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
645     length -= save_size;
646     ptr += save_size;
647     png_ptr->buffer_size -= save_size;
648     png_ptr->save_buffer_size -= save_size;
649     png_ptr->save_buffer_ptr += save_size;
650     }
651     if (length && png_ptr->current_buffer_size)
652     {
653     png_size_t save_size;
654    
655     if (length < png_ptr->current_buffer_size)
656     save_size = length;
657    
658     else
659     save_size = png_ptr->current_buffer_size;
660    
661     png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
662     png_ptr->buffer_size -= save_size;
663     png_ptr->current_buffer_size -= save_size;
664     png_ptr->current_buffer_ptr += save_size;
665     }
666     }
667    
668     void /* PRIVATE */
669     png_push_save_buffer(png_structp png_ptr)
670     {
671     if (png_ptr->save_buffer_size)
672     {
673     if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
674     {
675     png_size_t i, istop;
676     png_bytep sp;
677     png_bytep dp;
678    
679     istop = png_ptr->save_buffer_size;
680     for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
681     i < istop; i++, sp++, dp++)
682     {
683     *dp = *sp;
684     }
685     }
686     }
687     if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
688     png_ptr->save_buffer_max)
689     {
690     png_size_t new_max;
691     png_bytep old_buffer;
692    
693     if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
694     (png_ptr->current_buffer_size + 256))
695     {
696     png_error(png_ptr, "Potential overflow of save_buffer");
697     }
698    
699     new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
700     old_buffer = png_ptr->save_buffer;
701     png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
702     (png_uint_32)new_max);
703     png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
704     png_free(png_ptr, old_buffer);
705     png_ptr->save_buffer_max = new_max;
706     }
707     if (png_ptr->current_buffer_size)
708     {
709     png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
710     png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
711     png_ptr->save_buffer_size += png_ptr->current_buffer_size;
712     png_ptr->current_buffer_size = 0;
713     }
714     png_ptr->save_buffer_ptr = png_ptr->save_buffer;
715     png_ptr->buffer_size = 0;
716     }
717    
718     void /* PRIVATE */
719     png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
720     png_size_t buffer_length)
721     {
722     png_ptr->current_buffer = buffer;
723     png_ptr->current_buffer_size = buffer_length;
724     png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
725     png_ptr->current_buffer_ptr = png_ptr->current_buffer;
726     }
727    
728     void /* PRIVATE */
729     png_push_read_IDAT(png_structp png_ptr)
730     {
731     #ifdef PNG_USE_LOCAL_ARRAYS
732     PNG_CONST PNG_IDAT;
733     #endif
734     if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
735     {
736     png_byte chunk_length[4];
737    
738     if (png_ptr->buffer_size < 8)
739     {
740     png_push_save_buffer(png_ptr);
741     return;
742     }
743    
744     png_push_fill_buffer(png_ptr, chunk_length, 4);
745     png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
746     png_reset_crc(png_ptr);
747     png_crc_read(png_ptr, png_ptr->chunk_name, 4);
748     png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
749    
750     if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
751     {
752     png_ptr->process_mode = PNG_READ_CHUNK_MODE;
753     if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
754     png_error(png_ptr, "Not enough compressed data");
755     return;
756     }
757    
758     png_ptr->idat_size = png_ptr->push_length;
759     }
760     if (png_ptr->idat_size && png_ptr->save_buffer_size)
761     {
762     png_size_t save_size;
763    
764     if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
765     {
766     save_size = (png_size_t)png_ptr->idat_size;
767    
768     /* Check for overflow */
769     if ((png_uint_32)save_size != png_ptr->idat_size)
770     png_error(png_ptr, "save_size overflowed in pngpread");
771     }
772     else
773     save_size = png_ptr->save_buffer_size;
774    
775     png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
776    
777     if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
778     png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
779    
780     png_ptr->idat_size -= save_size;
781     png_ptr->buffer_size -= save_size;
782     png_ptr->save_buffer_size -= save_size;
783     png_ptr->save_buffer_ptr += save_size;
784     }
785     if (png_ptr->idat_size && png_ptr->current_buffer_size)
786     {
787     png_size_t save_size;
788    
789     if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
790     {
791     save_size = (png_size_t)png_ptr->idat_size;
792    
793     /* Check for overflow */
794     if ((png_uint_32)save_size != png_ptr->idat_size)
795     png_error(png_ptr, "save_size overflowed in pngpread");
796     }
797     else
798     save_size = png_ptr->current_buffer_size;
799    
800     png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
801     if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
802     png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
803    
804     png_ptr->idat_size -= save_size;
805     png_ptr->buffer_size -= save_size;
806     png_ptr->current_buffer_size -= save_size;
807     png_ptr->current_buffer_ptr += save_size;
808     }
809     if (!png_ptr->idat_size)
810     {
811     if (png_ptr->buffer_size < 4)
812     {
813     png_push_save_buffer(png_ptr);
814     return;
815     }
816    
817     png_crc_finish(png_ptr, 0);
818     png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
819     png_ptr->mode |= PNG_AFTER_IDAT;
820     }
821     }
822    
823     void /* PRIVATE */
824     png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
825     png_size_t buffer_length)
826     {
827     int ret;
828    
829     if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
830     png_error(png_ptr, "Extra compression data");
831    
832     png_ptr->zstream.next_in = buffer;
833     png_ptr->zstream.avail_in = (uInt)buffer_length;
834     for (;;)
835     {
836     ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
837     if (ret != Z_OK)
838     {
839     if (ret == Z_STREAM_END)
840     {
841     if (png_ptr->zstream.avail_in)
842     png_error(png_ptr, "Extra compressed data");
843    
844     if (!(png_ptr->zstream.avail_out))
845     {
846     png_push_process_row(png_ptr);
847     }
848    
849     png_ptr->mode |= PNG_AFTER_IDAT;
850     png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
851     break;
852     }
853     else if (ret == Z_BUF_ERROR)
854     break;
855    
856     else
857     png_error(png_ptr, "Decompression Error");
858     }
859     if (!(png_ptr->zstream.avail_out))
860     {
861     if ((
862     #if defined(PNG_READ_INTERLACING_SUPPORTED)
863     png_ptr->interlaced && png_ptr->pass > 6) ||
864     (!png_ptr->interlaced &&
865     #endif
866     png_ptr->row_number == png_ptr->num_rows))
867     {
868     if (png_ptr->zstream.avail_in)
869     png_warning(png_ptr, "Too much data in IDAT chunks");
870     png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
871     break;
872     }
873     png_push_process_row(png_ptr);
874     png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
875     png_ptr->zstream.next_out = png_ptr->row_buf;
876     }
877    
878     else
879     break;
880     }
881     }
882    
883     void /* PRIVATE */
884     png_push_process_row(png_structp png_ptr)
885     {
886     png_ptr->row_info.color_type = png_ptr->color_type;
887     png_ptr->row_info.width = png_ptr->iwidth;
888     png_ptr->row_info.channels = png_ptr->channels;
889     png_ptr->row_info.bit_depth = png_ptr->bit_depth;
890     png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
891    
892     png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth,
893     png_ptr->row_info.width);
894    
895     png_read_filter_row(png_ptr, &(png_ptr->row_info),
896     png_ptr->row_buf + 1, png_ptr->prev_row + 1,
897     (int)(png_ptr->row_buf[0]));
898    
899     png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
900     png_ptr->rowbytes + 1);
901    
902     if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA))
903     png_do_read_transformations(png_ptr);
904    
905     #if defined(PNG_READ_INTERLACING_SUPPORTED)
906     /* Blow up interlaced rows to full size */
907     if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
908     {
909     if (png_ptr->pass < 6)
910     /* old interface (pre-1.0.9):
911     png_do_read_interlace(&(png_ptr->row_info),
912     png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
913     */
914     png_do_read_interlace(png_ptr);
915    
916     switch (png_ptr->pass)
917     {
918     case 0:
919     {
920     int i;
921     for (i = 0; i < 8 && png_ptr->pass == 0; i++)
922     {
923     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
924     png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
925     }
926    
927     if (png_ptr->pass == 2) /* Pass 1 might be empty */
928     {
929     for (i = 0; i < 4 && png_ptr->pass == 2; i++)
930     {
931     png_push_have_row(png_ptr, png_bytep_NULL);
932     png_read_push_finish_row(png_ptr);
933     }
934     }
935    
936     if (png_ptr->pass == 4 && png_ptr->height <= 4)
937     {
938     for (i = 0; i < 2 && png_ptr->pass == 4; i++)
939     {
940     png_push_have_row(png_ptr, png_bytep_NULL);
941     png_read_push_finish_row(png_ptr);
942     }
943     }
944    
945     if (png_ptr->pass == 6 && png_ptr->height <= 4)
946     {
947     png_push_have_row(png_ptr, png_bytep_NULL);
948     png_read_push_finish_row(png_ptr);
949     }
950    
951     break;
952     }
953    
954     case 1:
955     {
956     int i;
957     for (i = 0; i < 8 && png_ptr->pass == 1; i++)
958     {
959     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
960     png_read_push_finish_row(png_ptr);
961     }
962    
963     if (png_ptr->pass == 2) /* Skip top 4 generated rows */
964     {
965     for (i = 0; i < 4 && png_ptr->pass == 2; i++)
966     {
967     png_push_have_row(png_ptr, png_bytep_NULL);
968     png_read_push_finish_row(png_ptr);
969     }
970     }
971    
972     break;
973     }
974    
975     case 2:
976     {
977     int i;
978    
979     for (i = 0; i < 4 && png_ptr->pass == 2; i++)
980     {
981     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
982     png_read_push_finish_row(png_ptr);
983     }
984    
985     for (i = 0; i < 4 && png_ptr->pass == 2; i++)
986     {
987     png_push_have_row(png_ptr, png_bytep_NULL);
988     png_read_push_finish_row(png_ptr);
989     }
990    
991     if (png_ptr->pass == 4) /* Pass 3 might be empty */
992     {
993     for (i = 0; i < 2 && png_ptr->pass == 4; 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 3:
1004     {
1005     int i;
1006    
1007     for (i = 0; i < 4 && png_ptr->pass == 3; 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     if (png_ptr->pass == 4) /* Skip top two generated rows */
1014     {
1015     for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1016     {
1017     png_push_have_row(png_ptr, png_bytep_NULL);
1018     png_read_push_finish_row(png_ptr);
1019     }
1020     }
1021    
1022     break;
1023     }
1024    
1025     case 4:
1026     {
1027     int i;
1028    
1029     for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1030     {
1031     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1032     png_read_push_finish_row(png_ptr);
1033     }
1034    
1035     for (i = 0; i < 2 && png_ptr->pass == 4; i++)
1036     {
1037     png_push_have_row(png_ptr, png_bytep_NULL);
1038     png_read_push_finish_row(png_ptr);
1039     }
1040    
1041     if (png_ptr->pass == 6) /* Pass 5 might be empty */
1042     {
1043     png_push_have_row(png_ptr, png_bytep_NULL);
1044     png_read_push_finish_row(png_ptr);
1045     }
1046    
1047     break;
1048     }
1049    
1050     case 5:
1051     {
1052     int i;
1053    
1054     for (i = 0; i < 2 && png_ptr->pass == 5; i++)
1055     {
1056     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1057     png_read_push_finish_row(png_ptr);
1058     }
1059    
1060     if (png_ptr->pass == 6) /* Skip top generated row */
1061     {
1062     png_push_have_row(png_ptr, png_bytep_NULL);
1063     png_read_push_finish_row(png_ptr);
1064     }
1065    
1066     break;
1067     }
1068     case 6:
1069     {
1070     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1071     png_read_push_finish_row(png_ptr);
1072    
1073     if (png_ptr->pass != 6)
1074     break;
1075    
1076     png_push_have_row(png_ptr, png_bytep_NULL);
1077     png_read_push_finish_row(png_ptr);
1078     }
1079     }
1080     }
1081     else
1082     #endif
1083     {
1084     png_push_have_row(png_ptr, png_ptr->row_buf + 1);
1085     png_read_push_finish_row(png_ptr);
1086     }
1087     }
1088    
1089     void /* PRIVATE */
1090     png_read_push_finish_row(png_structp png_ptr)
1091     {
1092     #ifdef PNG_USE_LOCAL_ARRAYS
1093     /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
1094    
1095     /* Start of interlace block */
1096     PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
1097    
1098     /* Offset to next interlace block */
1099     PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
1100    
1101     /* Start of interlace block in the y direction */
1102     PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
1103    
1104     /* Offset to next interlace block in the y direction */
1105     PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
1106    
1107     /* Height of interlace block. This is not currently used - if you need
1108     * it, uncomment it here and in png.h
1109     PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
1110     */
1111     #endif
1112    
1113     png_ptr->row_number++;
1114     if (png_ptr->row_number < png_ptr->num_rows)
1115     return;
1116    
1117     #if defined(PNG_READ_INTERLACING_SUPPORTED)
1118     if (png_ptr->interlaced)
1119     {
1120     png_ptr->row_number = 0;
1121     png_memset_check(png_ptr, png_ptr->prev_row, 0,
1122     png_ptr->rowbytes + 1);
1123     do
1124     {
1125     png_ptr->pass++;
1126     if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
1127     (png_ptr->pass == 3 && png_ptr->width < 3) ||
1128     (png_ptr->pass == 5 && png_ptr->width < 2))
1129     png_ptr->pass++;
1130    
1131     if (png_ptr->pass > 7)
1132     png_ptr->pass--;
1133    
1134     if (png_ptr->pass >= 7)
1135     break;
1136    
1137     png_ptr->iwidth = (png_ptr->width +
1138     png_pass_inc[png_ptr->pass] - 1 -
1139     png_pass_start[png_ptr->pass]) /
1140     png_pass_inc[png_ptr->pass];
1141    
1142     png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
1143     png_ptr->iwidth) + 1;
1144    
1145     if (png_ptr->transformations & PNG_INTERLACE)
1146     break;
1147    
1148     png_ptr->num_rows = (png_ptr->height +
1149     png_pass_yinc[png_ptr->pass] - 1 -
1150     png_pass_ystart[png_ptr->pass]) /
1151     png_pass_yinc[png_ptr->pass];
1152    
1153     } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
1154     }
1155     #endif /* PNG_READ_INTERLACING_SUPPORTED */
1156     }
1157    
1158     #if defined(PNG_READ_tEXt_SUPPORTED)
1159     void /* PRIVATE */
1160     png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1161     length)
1162     {
1163     if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1164     {
1165     png_error(png_ptr, "Out of place tEXt");
1166     info_ptr = info_ptr; /* To quiet some compiler warnings */
1167     }
1168    
1169     #ifdef PNG_MAX_MALLOC_64K
1170     png_ptr->skip_length = 0; /* This may not be necessary */
1171    
1172     if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1173     {
1174     png_warning(png_ptr, "tEXt chunk too large to fit in memory");
1175     png_ptr->skip_length = length - (png_uint_32)65535L;
1176     length = (png_uint_32)65535L;
1177     }
1178     #endif
1179    
1180     png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1181     (png_uint_32)(length + 1));
1182     png_ptr->current_text[length] = '\0';
1183     png_ptr->current_text_ptr = png_ptr->current_text;
1184     png_ptr->current_text_size = (png_size_t)length;
1185     png_ptr->current_text_left = (png_size_t)length;
1186     png_ptr->process_mode = PNG_READ_tEXt_MODE;
1187     }
1188    
1189     void /* PRIVATE */
1190     png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
1191     {
1192     if (png_ptr->buffer_size && png_ptr->current_text_left)
1193     {
1194     png_size_t text_size;
1195    
1196     if (png_ptr->buffer_size < png_ptr->current_text_left)
1197     text_size = png_ptr->buffer_size;
1198    
1199     else
1200     text_size = png_ptr->current_text_left;
1201    
1202     png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1203     png_ptr->current_text_left -= text_size;
1204     png_ptr->current_text_ptr += text_size;
1205     }
1206     if (!(png_ptr->current_text_left))
1207     {
1208     png_textp text_ptr;
1209     png_charp text;
1210     png_charp key;
1211     int ret;
1212    
1213     if (png_ptr->buffer_size < 4)
1214     {
1215     png_push_save_buffer(png_ptr);
1216     return;
1217     }
1218    
1219     png_push_crc_finish(png_ptr);
1220    
1221     #if defined(PNG_MAX_MALLOC_64K)
1222     if (png_ptr->skip_length)
1223     return;
1224     #endif
1225    
1226     key = png_ptr->current_text;
1227    
1228     for (text = key; *text; text++)
1229     /* Empty loop */ ;
1230    
1231     if (text < key + png_ptr->current_text_size)
1232     text++;
1233    
1234     text_ptr = (png_textp)png_malloc(png_ptr,
1235     (png_uint_32)png_sizeof(png_text));
1236     text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
1237     text_ptr->key = key;
1238     #ifdef PNG_iTXt_SUPPORTED
1239     text_ptr->lang = NULL;
1240     text_ptr->lang_key = NULL;
1241     #endif
1242     text_ptr->text = text;
1243    
1244     ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1245    
1246     png_free(png_ptr, key);
1247     png_free(png_ptr, text_ptr);
1248     png_ptr->current_text = NULL;
1249    
1250     if (ret)
1251     png_warning(png_ptr, "Insufficient memory to store text chunk.");
1252     }
1253     }
1254     #endif
1255    
1256     #if defined(PNG_READ_zTXt_SUPPORTED)
1257     void /* PRIVATE */
1258     png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1259     length)
1260     {
1261     if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1262     {
1263     png_error(png_ptr, "Out of place zTXt");
1264     info_ptr = info_ptr; /* To quiet some compiler warnings */
1265     }
1266    
1267     #ifdef PNG_MAX_MALLOC_64K
1268     /* We can't handle zTXt chunks > 64K, since we don't have enough space
1269     * to be able to store the uncompressed data. Actually, the threshold
1270     * is probably around 32K, but it isn't as definite as 64K is.
1271     */
1272     if (length > (png_uint_32)65535L)
1273     {
1274     png_warning(png_ptr, "zTXt chunk too large to fit in memory");
1275     png_push_crc_skip(png_ptr, length);
1276     return;
1277     }
1278     #endif
1279    
1280     png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1281     (png_uint_32)(length + 1));
1282     png_ptr->current_text[length] = '\0';
1283     png_ptr->current_text_ptr = png_ptr->current_text;
1284     png_ptr->current_text_size = (png_size_t)length;
1285     png_ptr->current_text_left = (png_size_t)length;
1286     png_ptr->process_mode = PNG_READ_zTXt_MODE;
1287     }
1288    
1289     void /* PRIVATE */
1290     png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
1291     {
1292     if (png_ptr->buffer_size && png_ptr->current_text_left)
1293     {
1294     png_size_t text_size;
1295    
1296     if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
1297     text_size = png_ptr->buffer_size;
1298    
1299     else
1300     text_size = png_ptr->current_text_left;
1301    
1302     png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1303     png_ptr->current_text_left -= text_size;
1304     png_ptr->current_text_ptr += text_size;
1305     }
1306     if (!(png_ptr->current_text_left))
1307     {
1308     png_textp text_ptr;
1309     png_charp text;
1310     png_charp key;
1311     int ret;
1312     png_size_t text_size, key_size;
1313    
1314     if (png_ptr->buffer_size < 4)
1315     {
1316     png_push_save_buffer(png_ptr);
1317     return;
1318     }
1319    
1320     png_push_crc_finish(png_ptr);
1321    
1322     key = png_ptr->current_text;
1323    
1324     for (text = key; *text; text++)
1325     /* Empty loop */ ;
1326    
1327     /* zTXt can't have zero text */
1328     if (text >= key + png_ptr->current_text_size)
1329     {
1330     png_ptr->current_text = NULL;
1331     png_free(png_ptr, key);
1332     return;
1333     }
1334    
1335     text++;
1336    
1337     if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */
1338     {
1339     png_ptr->current_text = NULL;
1340     png_free(png_ptr, key);
1341     return;
1342     }
1343    
1344     text++;
1345    
1346     png_ptr->zstream.next_in = (png_bytep )text;
1347     png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
1348     (text - key));
1349     png_ptr->zstream.next_out = png_ptr->zbuf;
1350     png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1351    
1352     key_size = text - key;
1353     text_size = 0;
1354     text = NULL;
1355     ret = Z_STREAM_END;
1356    
1357     while (png_ptr->zstream.avail_in)
1358     {
1359     ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
1360     if (ret != Z_OK && ret != Z_STREAM_END)
1361     {
1362     inflateReset(&png_ptr->zstream);
1363     png_ptr->zstream.avail_in = 0;
1364     png_ptr->current_text = NULL;
1365     png_free(png_ptr, key);
1366     png_free(png_ptr, text);
1367     return;
1368     }
1369     if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
1370     {
1371     if (text == NULL)
1372     {
1373     text = (png_charp)png_malloc(png_ptr,
1374     (png_uint_32)(png_ptr->zbuf_size
1375     - png_ptr->zstream.avail_out + key_size + 1));
1376    
1377     png_memcpy(text + key_size, png_ptr->zbuf,
1378     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1379    
1380     png_memcpy(text, key, key_size);
1381    
1382     text_size = key_size + png_ptr->zbuf_size -
1383     png_ptr->zstream.avail_out;
1384    
1385     *(text + text_size) = '\0';
1386     }
1387     else
1388     {
1389     png_charp tmp;
1390    
1391     tmp = text;
1392     text = (png_charp)png_malloc(png_ptr, text_size +
1393     (png_uint_32)(png_ptr->zbuf_size
1394     - png_ptr->zstream.avail_out + 1));
1395    
1396     png_memcpy(text, tmp, text_size);
1397     png_free(png_ptr, tmp);
1398    
1399     png_memcpy(text + text_size, png_ptr->zbuf,
1400     png_ptr->zbuf_size - png_ptr->zstream.avail_out);
1401    
1402     text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
1403     *(text + text_size) = '\0';
1404     }
1405     if (ret != Z_STREAM_END)
1406     {
1407     png_ptr->zstream.next_out = png_ptr->zbuf;
1408     png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1409     }
1410     }
1411     else
1412     {
1413     break;
1414     }
1415    
1416     if (ret == Z_STREAM_END)
1417     break;
1418     }
1419    
1420     inflateReset(&png_ptr->zstream);
1421     png_ptr->zstream.avail_in = 0;
1422    
1423     if (ret != Z_STREAM_END)
1424     {
1425     png_ptr->current_text = NULL;
1426     png_free(png_ptr, key);
1427     png_free(png_ptr, text);
1428     return;
1429     }
1430    
1431     png_ptr->current_text = NULL;
1432     png_free(png_ptr, key);
1433     key = text;
1434     text += key_size;
1435    
1436     text_ptr = (png_textp)png_malloc(png_ptr,
1437     (png_uint_32)png_sizeof(png_text));
1438     text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
1439     text_ptr->key = key;
1440     #ifdef PNG_iTXt_SUPPORTED
1441     text_ptr->lang = NULL;
1442     text_ptr->lang_key = NULL;
1443     #endif
1444     text_ptr->text = text;
1445    
1446     ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1447    
1448     png_free(png_ptr, key);
1449     png_free(png_ptr, text_ptr);
1450    
1451     if (ret)
1452     png_warning(png_ptr, "Insufficient memory to store text chunk.");
1453     }
1454     }
1455     #endif
1456    
1457     #if defined(PNG_READ_iTXt_SUPPORTED)
1458     void /* PRIVATE */
1459     png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
1460     length)
1461     {
1462     if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
1463     {
1464     png_error(png_ptr, "Out of place iTXt");
1465     info_ptr = info_ptr; /* To quiet some compiler warnings */
1466     }
1467    
1468     #ifdef PNG_MAX_MALLOC_64K
1469     png_ptr->skip_length = 0; /* This may not be necessary */
1470    
1471     if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
1472     {
1473     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
1474     png_ptr->skip_length = length - (png_uint_32)65535L;
1475     length = (png_uint_32)65535L;
1476     }
1477     #endif
1478    
1479     png_ptr->current_text = (png_charp)png_malloc(png_ptr,
1480     (png_uint_32)(length + 1));
1481     png_ptr->current_text[length] = '\0';
1482     png_ptr->current_text_ptr = png_ptr->current_text;
1483     png_ptr->current_text_size = (png_size_t)length;
1484     png_ptr->current_text_left = (png_size_t)length;
1485     png_ptr->process_mode = PNG_READ_iTXt_MODE;
1486     }
1487    
1488     void /* PRIVATE */
1489     png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
1490     {
1491    
1492     if (png_ptr->buffer_size && png_ptr->current_text_left)
1493     {
1494     png_size_t text_size;
1495    
1496     if (png_ptr->buffer_size < png_ptr->current_text_left)
1497     text_size = png_ptr->buffer_size;
1498    
1499     else
1500     text_size = png_ptr->current_text_left;
1501    
1502     png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
1503     png_ptr->current_text_left -= text_size;
1504     png_ptr->current_text_ptr += text_size;
1505     }
1506     if (!(png_ptr->current_text_left))
1507     {
1508     png_textp text_ptr;
1509     png_charp key;
1510     int comp_flag;
1511     png_charp lang;
1512     png_charp lang_key;
1513     png_charp text;
1514     int ret;
1515    
1516     if (png_ptr->buffer_size < 4)
1517     {
1518     png_push_save_buffer(png_ptr);
1519     return;
1520     }
1521    
1522     png_push_crc_finish(png_ptr);
1523    
1524     #if defined(PNG_MAX_MALLOC_64K)
1525     if (png_ptr->skip_length)
1526     return;
1527     #endif
1528    
1529     key = png_ptr->current_text;
1530    
1531     for (lang = key; *lang; lang++)
1532     /* Empty loop */ ;
1533    
1534     if (lang < key + png_ptr->current_text_size - 3)
1535     lang++;
1536    
1537     comp_flag = *lang++;
1538     lang++; /* Skip comp_type, always zero */
1539    
1540     for (lang_key = lang; *lang_key; lang_key++)
1541     /* Empty loop */ ;
1542    
1543     lang_key++; /* Skip NUL separator */
1544    
1545     text=lang_key;
1546    
1547     if (lang_key < key + png_ptr->current_text_size - 1)
1548     {
1549     for (; *text; text++)
1550     /* Empty loop */ ;
1551     }
1552    
1553     if (text < key + png_ptr->current_text_size)
1554     text++;
1555    
1556     text_ptr = (png_textp)png_malloc(png_ptr,
1557     (png_uint_32)png_sizeof(png_text));
1558    
1559     text_ptr->compression = comp_flag + 2;
1560     text_ptr->key = key;
1561     text_ptr->lang = lang;
1562     text_ptr->lang_key = lang_key;
1563     text_ptr->text = text;
1564     text_ptr->text_length = 0;
1565     text_ptr->itxt_length = png_strlen(text);
1566    
1567     ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
1568    
1569     png_ptr->current_text = NULL;
1570    
1571     png_free(png_ptr, text_ptr);
1572     if (ret)
1573     png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
1574     }
1575     }
1576     #endif
1577    
1578     /* This function is called when we haven't found a handler for this
1579     * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
1580     * name or a critical chunk), the chunk is (currently) silently ignored.
1581     */
1582     void /* PRIVATE */
1583     png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
1584     length)
1585     {
1586     png_uint_32 skip = 0;
1587    
1588     if (!(png_ptr->chunk_name[0] & 0x20))
1589     {
1590     #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1591     if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1592     PNG_HANDLE_CHUNK_ALWAYS
1593     #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1594     && png_ptr->read_user_chunk_fn == NULL
1595     #endif
1596     )
1597     #endif
1598     png_chunk_error(png_ptr, "unknown critical chunk");
1599    
1600     info_ptr = info_ptr; /* To quiet some compiler warnings */
1601     }
1602    
1603     #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
1604     if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
1605     {
1606     #ifdef PNG_MAX_MALLOC_64K
1607     if (length > (png_uint_32)65535L)
1608     {
1609     png_warning(png_ptr, "unknown chunk too large to fit in memory");
1610     skip = length - (png_uint_32)65535L;
1611     length = (png_uint_32)65535L;
1612     }
1613     #endif
1614     png_memcpy((png_charp)png_ptr->unknown_chunk.name,
1615     (png_charp)png_ptr->chunk_name,
1616     png_sizeof(png_ptr->unknown_chunk.name));
1617     png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1]
1618     = '\0';
1619    
1620     png_ptr->unknown_chunk.size = (png_size_t)length;
1621    
1622     if (length == 0)
1623     png_ptr->unknown_chunk.data = NULL;
1624    
1625     else
1626     {
1627     png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr,
1628     (png_uint_32)length);
1629     png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
1630     }
1631    
1632     #if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
1633     if (png_ptr->read_user_chunk_fn != NULL)
1634     {
1635     /* Callback to user unknown chunk handler */
1636     int ret;
1637     ret = (*(png_ptr->read_user_chunk_fn))
1638     (png_ptr, &png_ptr->unknown_chunk);
1639    
1640     if (ret < 0)
1641     png_chunk_error(png_ptr, "error in user chunk");
1642    
1643     if (ret == 0)
1644     {
1645     if (!(png_ptr->chunk_name[0] & 0x20))
1646     if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
1647     PNG_HANDLE_CHUNK_ALWAYS)
1648     png_chunk_error(png_ptr, "unknown critical chunk");
1649     png_set_unknown_chunks(png_ptr, info_ptr,
1650     &png_ptr->unknown_chunk, 1);
1651     }
1652     }
1653    
1654     else
1655     #endif
1656     png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
1657     png_free(png_ptr, png_ptr->unknown_chunk.data);
1658     png_ptr->unknown_chunk.data = NULL;
1659     }
1660    
1661     else
1662     #endif
1663     skip=length;
1664     png_push_crc_skip(png_ptr, skip);
1665     }
1666    
1667     void /* PRIVATE */
1668     png_push_have_info(png_structp png_ptr, png_infop info_ptr)
1669     {
1670     if (png_ptr->info_fn != NULL)
1671     (*(png_ptr->info_fn))(png_ptr, info_ptr);
1672     }
1673    
1674     void /* PRIVATE */
1675     png_push_have_end(png_structp png_ptr, png_infop info_ptr)
1676     {
1677     if (png_ptr->end_fn != NULL)
1678     (*(png_ptr->end_fn))(png_ptr, info_ptr);
1679     }
1680    
1681     void /* PRIVATE */
1682     png_push_have_row(png_structp png_ptr, png_bytep row)
1683     {
1684     if (png_ptr->row_fn != NULL)
1685     (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
1686     (int)png_ptr->pass);
1687     }
1688    
1689     void PNGAPI
1690     png_progressive_combine_row (png_structp png_ptr,
1691     png_bytep old_row, png_bytep new_row)
1692     {
1693     #ifdef PNG_USE_LOCAL_ARRAYS
1694     PNG_CONST int FARDATA png_pass_dsp_mask[7] =
1695     {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
1696     #endif
1697     if (png_ptr == NULL)
1698     return;
1699    
1700     if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
1701     png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
1702     }
1703    
1704     void PNGAPI
1705     png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
1706     png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
1707     png_progressive_end_ptr end_fn)
1708     {
1709     if (png_ptr == NULL)
1710     return;
1711    
1712     png_ptr->info_fn = info_fn;
1713     png_ptr->row_fn = row_fn;
1714     png_ptr->end_fn = end_fn;
1715    
1716     png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
1717     }
1718    
1719     png_voidp PNGAPI
1720     png_get_progressive_ptr(png_structp png_ptr)
1721     {
1722     if (png_ptr == NULL)
1723     return (NULL);
1724    
1725     return png_ptr->io_ptr;
1726     }
1727     #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

  ViewVC Help
Powered by ViewVC 1.1.22